Sunday, July 03, 2011

Conditionally Call and Ant Target

If you want to set a target to only run if you set a particular value, easy. Just use the if attribute as follows:


<target name="whatever" if="my.value">
<echo message="target executed"/>
</target>


If you want the above target to run - set my.value to something in your property file before that target and it will run.


<property name="my.value" value="yada"/>

If you leave the property out of your file altogether the target won't run.

You can also have other tasks set values and use those values to determine if targets should run or not based on whether a file was available, etc. Details about conditional values can be found in the Ant FAQ:

Conditionally Execute Ant Target

Saturday, July 02, 2011

Ant - Copy Files That Have Changed

If you want to copy files that have changed from one directory to another use a file set with the "modified" option like this:


<copy todir="${dir.copy.to}">
<fileset dir="${dir.copy.from}">
<modified/>
</fileset>

</copy>


Ant will set up a cache.properties file which tracks file information so it knows the state of files after each build. Then when it runs a task it can refer to the cache file to determine which files have changed since the last successful build and need to be included in the fileset.

If you want the build to include a file that is getting excluded by the cache file just delete that file from the cache.properties file and it will be included in the file set the next time the ant build is run.

Tuesday, June 28, 2011

Get Ant to Call a Java Class

To get Ant to call you own Java class to do some processing you can write your own custom Ant task. Here's the info on how to do that:

http://ant.apache.org/manual/develop.html

Sunday, June 26, 2011

Running Ant from within a Java Class

Here's a good article on running Ant within another Java program.

http://www.ibm.com/developerworks/websphere/library/techarticles/0502_gawor/0502_gawor.html

You might want to do this if wrapping your ant build in a process that needs additional auditing and security, or to create a friendly user interface for running builds, for example.

Ant, Gradle, Maven, Build Software and Processes

Still pondering all my options for a build solution for a particular project but these are my thoughts going into further testing and proof of concept for a new build and deploy solution.

What build solution you choose really depends on the requirements of your particular project, security concerns and the staff you have available to support the solution.

I find Ant simple to use and manage. I like the control of what is getting into my code when and how. Because I put it there.

For all these dependency management issues addressed by Maven and some other build solutions: I think it is not difficult for experienced programmers to find and download a jar file or source code, though I think some companies and organizations providing software libraries and open source software could make this more straight forward and manage their repository of code and libraries better.

Tangent: And when getting source from the Internet not require SVN to download source (dislike). Make it easy for me to download a zip. It's a lot faster and I want a stable version that's not going to change the next time I download it. I also don't want those .svn files in my source if I don't want the software changing on me or to upload changes to your repo.

That being said large companies managing what software their developers include in production software have other concerns. These companies should have a process for requesting and downloading new libraries off the Internet to a central repository so they know what is being deployed to production systems, regardless of what build software they are using. This process should include making sure the code is from a trusted source, checking downloads with provided security keys and possibly even compiling open source libraries to make sure no rogue code has slipped in, and/or (crazy thought I know) removing questionable code in these libraries which is not needed and may introduce security problems (but let your dev's know so they don't try to use features that are not available).

You may not have these next problems with Maven, if working on a project that is small and does not have a lot of dependencies or using an internal repo at your company where Maven is not allowed to access the Internet (but you might in any case). My experience with Maven on complex projects has in general, been a lot of overhead managing things even though Maven is supposed to make things simpler. Maven's plus is that it handles dependency management by going out and grabbing all the libraries you need off the Internet or internal repo for you. Yes I know it does other stuff too. In my case, it seemed like I ended up with a bunch of compile errors to fix every time I turned on my computer. On a recent project, Maven kept updating things when it seemed like dependencies should be stable because I wasn't changing versions. This bothered me. As did having to re-fix my code every time I turned on my computer for no apparent reason. I think when you know what you're doing with the dependencies, Maven can actually make things more complicated, time consuming, and less secure. I stopped using Maven for that project and have been much more productive ever since.

Also with Maven, there are security concerns with pulling random code from the Internet (unless your company has a well managed internal repository which is well managed and secured). If you don't believe that last point, please don't work on any type of financial application or anything that stores personal private data or store anything important on the machine you dev with or let it on a network where valuable data is stored. Thanks.

I know a lot of system administrators use various scripting languages to manage various things and may not prefer an XML configuration file for managing builds. However when it comes to a build system I would prefer separation of execution from configuration. Like MVC separates the model from the view, the steps to run and files to move are in XML while the programmatic execution is in Java. Personal preference, but separation of duties can make things cleaner, easier to manage, less error prone, and more secure as we have learned from MVC.

I'd also rather work with languages I and a lot of other dev's know: Java and XML, vs. learning another new scripting language specific to a particular build software solution. That makes it hard to find employees to support that system, and less people in the organization knowing it who can help fix problems. I also don't want to have to extend (rewrite) the build system to support Java when other solutions alrady exist that meets my needs.

PS as you can see from my resume I have learned a lot of new languages besides Java over the years. This is why consideration for when a new language is really needed and the pros and cons of each is important to me: WebDatabaseProgrammer.com

As for the need to customize, if you're looking for something Ant can't do, I don't think it's that difficult for an experienced Java programmer to figure out how to add new classes that can perform tasks under the Ant framework, or customize Ant itself. I have customized open source code that didn't do exactly what I wanted. It's not that tough. Download the source, grab the dependencies and edit the Java as needed. Just like any other project. If you intend to get updates however, keep your custom code separate from the open source library you downloaded, using and appropriate design pattern.

It seems to me that using a universal language that many developers know should cover whatever the build system needs to do. Java + XML can do pretty much anything you can imagine. I think rare would be the project where Java couldn't get the job done well enough. Of course adding new Java tasks requires compiling code but it also adds some control to what your build system is allowed to do and universal logging can ensure you can audit what your build system is doing, regardless of who edits the XML file. You can add a layer of security also based on who can edit the Java classes and who can edit the XML.

I actually like that variables are immutable once the Ant build process starts. This ensures your variables aren't changing mid stream and avoids tricky errors related to variables changing in random places during the build. XSL transformation works the same way and it took a bit of getting used to, but now I like it because once you get to the point of transforming, or building, certain things should be set.

In general, your build system is probably one of the most important places you don't want to take security risks. That's where you can audit everything and make sure nothing unintended gets into your production software. Whatever build solution you choose, I recommend making sure your processes for updating your builds are secure and audited, including database updates, compilation, and deploying all types of files. It doesn't matter how much development and testing you do on the source code if someone can alter it when it gets deployed and after everyone's done scrutinizing it. Make sure this process is secure.

Sunday, April 03, 2011

Eclipse: Selection Does Not Contain A Main Type

If you are having a problem launching your project as a Java Application in Eclipse due to the error: "Selection does not contain a main type" a simple work around is to simply create a new Java project and copy your class files into the source folder of the new project.

You can also create a new Java project in Eclipse and change the build path to point to your existing source folders. Right click on the project and select "Java Build Path". Click on the "Source" tab. Remove any folders you don't want and point to your existing source folders.

Then your Eclipse Java project configuration should be accurate (without having to figure out the problem with it - which is the other option) and you should be able to right click on a class file with a main method and run it.

Related posts:

http://dev.eclipse.org/newslists/news.eclipse.newcomer/msg04471.html

http://stackoverflow.com/questions/4252472/java-launch-error-selection-does-not-contain-a-main-type

Sunday, March 27, 2011

SSL Certificates for Java Web Servers

Digicert makes it pretty simple to get SSL certificates for Java web servers. I like.

They have a tool to generate the command line code you need to enter to generate your certificate request here:

https://www.digicert.com/easy-csr/keytool.htm

Just enter the appropriate information. Open a command prompt window on the server on which you intend to install the certificate. Navigate to the folder where you want to store the certificate files. Copy and paste the command into the command prompt window.

A file will be created for the keystore, and for the CSR (certificate request). Copy and paste the certificate request (in the .csr file that gets created) into the box on the order form where it asks for that information.

Once your certificate is approved, download and copy it to the folder you created above. Run the command on this page but replace the domain name with the domain name for which you ordered the certificate:

http://www.digicert.com/ssl-certificate-installation-java.htm

Friday, January 14, 2011

Syntax and Result Differences - Sybase and SQL Server

SQL Server is based off Sybase. They both use Transact SQL. However I've found some differences in behavior (at least in the version of Sybase and driver I'm using).

You cannot do a count in a select in sybase without a group by and get accurate results.

COUNT without GROUP BY:

Select count(some_field) from whatever_table will return every row in the table. That select statement works in SQL Server without the group by. In Sybase you'll need to add group by like this:

select count(some_field) from whatever_table group by (some_field)

COLUMNS and GROUP BY:

If you don't have all the columns you are selecting in the group by you may get incorrect results but no error. In SQL this will give you an error like this:

Column 'some_field' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

In Sybase something like this will just give you inaccurate results:

select some_field, other_field
from whatever_table
group by other_field

EMPTY STRING, LTRIM, LEN

- insert

If you try to insert an empty string using an insert statement with Sybase it inserts a 1 character space instead of an empty string. Length will equal 1.

insert into some_table (id, some_field) values(23, '')
select len(some_field) from some_table where id = 23 (this will give you length of 1)

In SQL Server the above statements would 1.) insert a true empty string and 2.) return a length of 0.

- ltrim and length

In Sybase ltrim(some_field) above would give you a null and len(ltrim(some_field)) will give you null - no matter how many spaces you have in some_field.

In SQL Server the same scenario would give you an empty string after trim and 0 for the length.

Saturday, December 25, 2010

Finding Memory Leaks in Java Applications

Trying this out to analyze memory usage and find leaks in Java application:

http://blog.emptyway.com/2007/04/02/finding-memory-leaks-in-java-apps/

Pretty slick...

In Eclipse for my debug configuration I put this in the vm arguments box:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9000
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-agentlib:hprof=heap=dump,file=/tmp/hprof.bin,
format=b,depth=10

A few more details for those not so familiar with Java:

jconsole.exe is found in the /bin directory in the directory where you installed the Java JDK. It is an application with a GUI so just double click on it to open it up. You then select your application from the list to view details about it.

jps.exe is run from command prompt. It is also found in the /bin directory in the directory where you installed the Java JDK. Go to a command prompt (start menu, run, enter "cmd" hit enter) and navigate to that bin folder or alternatively you can type out the full path to jps.exe to run it.

jmap.exe is also in the /bin directory. You also would run that from the command line by typing in the location where you want to write the file and the process id as described in the above article.

jmap -dump:format=b,file=/tmp/java_app-heap.bin 15976

Once that file is created,run jhat as directed.

jhat -J-Xmx326m /tmp/java_app-heap.bin

Then in browser go to:

http://localhost:7000

You can browse that data to find which objects are most in use, how much memory they are taking up, etc.

If a very slow leak can run the app in production using the above to output file over time and then view it.

Seems like support for Eclipse Memory Analyzer and Eclipse TPTP are dwindling but this method above is pretty simple.

Sunday, November 21, 2010

Postini, IMail, SSL/TLS

Here's a run down on setting up Postini with IMail. Really quick...disclaimer in case of error but here are my notes...

Postini

You probably all run some kind of mail software with spam blocking capabilities. However the painful thing is that spammers are out there inserting mail directly into your mail server and overloading spam boxes all the time. This takes up resources on your mail server(s) and clients.

What's kind of neat about Postini is that it's a filtering service in front of your mail server. You can force all inbound and outbound mail to go through Postini if you have your own mail server or a service that offers Postini. By setting up Postini correctly a lot of the garbage bombarding your server can be stopped before it ever gets that far.

Postini was bought out by Google and as you can imagine has a tad bit more mail to analyze than the average company hosting an email system. By passing all the garbage through them first, I would hope they can do some pretty good analytics on mail going through their system and figure out how to weed out the junk, the same way they figure out how to put the best web sites at the top of the search engine results [hopefully!]

Postini blocks viruses, spam and has a bunch of cool features like allowing you to block IP ranges from sending mail to your server. Since a lot of spam comes from certain parts of the world, if you don't do business in those areas you can simply block out entire spam friendly networks completely. I found that blocking out everything but ARIN significantly reduced my spam on a particularly old domain that is probably in every spammer's list in existence.

The other cool thing about Postini is that it allows you to force TLS between two parties - for regulatory copmliance or simply because you want to know your email transmission is encrypted end to end (which can be hard to do).

These are just a few of the highlights of Postini service.

The biggest problem with Postini is that, if you're a small business, getting support is challenging. You don't always get answers and when you do they are vague or not actually answering the question you asked or simply don't resolve the problem. Lately, however, I haven't had a ton of questions which is good. The service has been pretty reliable.

IMail

If you're not interested in spending mega-bucks on Exchange, IMail is a simpler, less expensive option and the company provides very good support. When it comes to email that's important to me because I find email to be a royal pain. As noted in a recent episode of American Greed, spam is the backbone of organized Internet crime. They are all trying to get into your in box to get you to click a link - or something.

When people's email isn't working - they want it fixed. Now. Although I'm pretty handy with Java, open source typically comes with no or minimal support. Additionally open source has so many people contributing that are not quite held accountable in the same way I would expect a company with paid staff to be. Mostly, I'd rather pay a bit more and get someone who can help me fix things fast than futz around with user groups and mailing lists or reverse engineering code to find a fix to a type of technology I find completely annoying because it is hard to secure, unreliable and always under attack. I prefer to deal with email as little as possible. I just want to call someone and get an answer. There is one person at Ipswitch in particular I have talked to over the years who is extremely knowledgeable about IMail and was able to quickly answer all my questions during set up.

For me running on IIS was kind of a pain because I prefer Java and it's another thing to manage, but I've used Imail in the past and it's reliable with good support as mentioned. For those who like and know IIS this would be a plus. Setting up the SSL cert was much easier with IIS than Java. The web site runs a little slow but going to look into how that can be tweaked. Using IMail is, for the most part, a piece of cake. The only thing I found challenging (having a basic understanding of mail servers) was getting the SSL cert installed and finding all the parts and pieces to make it work with Postini.

Set Up

--IMAIL--
> Purchase or get trial at IPSwitch.com
> Install - call for help as needed.
> Note that MX records will be pointed at Postini (see below) not your mail server.

--POSTINI--
> Set up an account and login to the System Administrator
> Click on the Orgs & Users tab
> Select your top level account from the drop down list of orgs
> Click the link (name) of your account (top node in the list)
> Enter a new org name in the box at the top and click the "add" button
> Click on orgs & users tab to get the full list of orgs
> Click on the name of the org you just created to view the settings.
> Click on the "general settings" link 3/4 down the page
> Change "email config type org" to Yes and save [allows mail server settings for this org]
> Click on "DNS Instructions" for MX records to use...

--EDIT YOUR DNS--
> edit your MX records to include the specified servers (note that each domain should have the domainname itself in the MX record - replace the part that says yourdomain with the domain for which you are setting up email)

--POSTINI--
> Click on "domains" under the tabs and add a domain
> Click on "users" under the tabs and createa user
> Click on "Inbound Servers" tab, "Delivery Manager", then "Edit" to add your mail servers. If you have your own mail server choose "Use my own mail server" and % to balance load to each server.
> There are other cool features you can look into later...manually block mail from certain IPs (bottom right when you click on "Inbound Servers"), force TLS between certain domains, etc.

--IMAIL--
> In your mail server allow relay from Postini (ONLY so you don't create an open relay for spammers!) In the latest version of Imail you would click on "Services" on the left, then double click on "Imail SMTP service".
> Under "General" click on the "Addresses" tab. Select "Group" from the drop down and enter the Postini IP addresses specified for your outbound mail configuration. The IP addresses depend on which server number you were assigned when you signed up for the service. The server number is in your MX records specified in the DNS instructions. More in this document:
Postini Outbound Services

--POSTINI--
> Click on "Outbound Servers" tab, and at the bottom left choose "Add Another Outbound Email Server" and add your mail server(s) that will be used for sending bounces back to your users.

--IMAIL --
> Set up webmail per the IMail instructions.
> If you want webmail to show up on it's own domain with no directory at the end and no access to the administrator and other things from that domain, set up a second web site on IIS and point it specifically at the webmail folder instead of the parent directory. In other words instead of mail.mydomain.com/web_mail_folder to get to mail you point IIS web site at the web_mail_folder and then can get to that same thing by going to mail.mydomain.com (if that doesn't make sense...call IPSwitch. They are very helpful.)

-- SSL CERTIFICATE (webmail and mail traffic) --
> In IIS create a cert request. I used Digicert.com and they were extremely easy to work with. Click on the IIS link on the left side of their home page and scroll to the bottom to get instructions for IIS cert request.
> When you get back the certificate, install it in IIS (for the domain you're running webmail on).
> Test your webmail domain and make sure it's accessible via SSL (https://mail.mydomain.com)
> For Digicert there were some chained certificates I needed to install in IMail. Originally exporting from IIS didn't work because the output didn't include the full chain. So...
> Use the MMC to export the cert with the full chain of certs:
http://www.digicert.com/ssl-support/pfx-import-export-iis-7.htm
> These "unsupported" instructions will get you two files that have the private key and the cert in separate files - I don't know if there's any issue with this...but I did it and it worked.
http://kb.imailserver.com/cgi-bin/imail.cfg/php/enduser/std_adp.php?p_faqid=42&p_created=1218038946
> You'll need the full chain in your cert file as explained in this article:
http://support.ipswitch.com/kb/IM-20010425-DM01.htm

-- PORTS AND FIREWALL--
> You'll want to make sure spammers can't inject mail straight into your mail server, so set up your firewall to only allow SMTP to Postini
> In order to let users connect, you set up a separate port for them to connect to and force authentication on that port. In Imail there's an option to do this on the "advanced" link for SMTP server settings.
> I also tried to use that same port for SSL hoping all traffic would be SSL encrypted on that alternate port but found the following info at the bottom of this link:

http://support.ipswitch.com/kb/IM-20050428-DM01.htm

Note for Outlook and Outlook Express users: If you tell your client to use SSL over SMTP and set the port to anything other than 25 the client will attempt to negotiate the SSL connection before sending the EHLO as if it was communicating over a dedicated SSL port. This will not work on the extra port. Users must issue EHLO and then STARTTLS to use SSL over the alternate SMTP port.

When users tried to enter the port and check "SSL" in outlook didn't work. They had to uncheck it to get this to work. However another mail connection I used from an alternate piece of software didn't work. By moving SSL to a separate port I believe that Outlook will attempt to use TLS if available. What I wonder is - what if something happens and it's not? The problem here is that with Postini you can force TLS between your mail server and Postini and between Postini and other mail servers, but for people connecting from their machine to our mail server - we also want to make sure that portion of the transmission is encrypted. Need to set up some alternate type of monitoring to enforce this potentially.

> So for now users are set up to connect to alternate port with SSL unchecked.
> Set up SSL port for POP/IMAP also and provided that port with "server requires SSL" setting.

TLS is cool because it runs on the same port as SMTP so takes up less ports, easier for users to configure and uses TLS when available otherwise not - but for connections from users to the mail server, wondering how that can be enforced and monitored as noted.

-- DICTIONARY ATTACKS --

Shortly after set up we were plagued by "dictionary attacks" (see my twitter account for more on that http://twitter.com/teriradichel

To prevent or at least slow down dictionary attacks - where someone just hits your web server with every possible valid email they can think of in rapid succession until they find a good one - edit SMTP service settings in the box that says "Dictionary" attacks and limit the number of attacks per session, failures, etc.

-- TRANSFERING MAIL TO MAIL SERVER --

If you're transferring users from another mail server you might also be interested in:

How to transfer your users and mail from your old mail server to new:
http://kb.imailserver.com/cgi-bin/imail.cfg/php/enduser/std_adp.php?p_faqid=716&p_created=1247145176&p_sid=gOAbiCfk&p_accessibility=0&p_redirect=&p_lva=&p_sp=cF9zcmNoPTEmcF9zb3J0X2J5PWRmbHQ6MSZwX2dyaWRzb3J0PSZwX3Jvd19jbnQ9MTU4LDE1OCZwX3Byb2RzPTAmcF9jYXRzPTAmcF9wdj0mcF9jdj0mcF9zZWFyY2hfdHlwZT1hbnN3ZXJzLnNlYXJjaF9ubCZwX3BhZ2U9MiZwX3NlYXJjaF90ZXh0PW1vdmUgbWFpbA**&p_li=&p_topview=1

Basically to move mail you transfer all your users over as noted above. Then you can connect via IMAP in outlook to both mail servers, and copy all the mail from the inbox of one server to the inbox of the other. There may be other folders to copy as well depending on what the user has set up.

Probably missing a few things here but that's the gist of it.

Monday, November 01, 2010

Skip Tests Running Maven Install From Command Line

mvn -Dmaven.test.skip=true install

JDK version - Eclipse, Maven

Do you know what compiler Maven is really compiling with when you choose "install"?

I am able to get a project in Maven-Eclipse-Plugin to compile with a specified compiler when using "Maven build..." option. But when I choose "Maven install" it has a mind of its own and decides to use an old compiler version. This may cause a project to fail to build due to incompatibilities (generics) or introduce security issues because various security flaws have been fixed in newer versions of Java.

What really bugs me is that this happened without me changing anything as noted in this previous post, and is kind of frustrating because have to spend time futzing with this instead of getting work done:

Maven-Eclipse compiler issue

Didn't get so lucky with some simple tweaking in my last post, so added compiler variable to a profile in settings.xml like this:

Specify Maven Compiler JDK version in settings

I added a new profile to my Maven settings.xml file as specified in link above. I called my compiler variable MY_JAVA_HOME and pointed it to the JDK I want to use.

Then I added the maven compiler plugin to my project by right clicking on the project node in Eclipse, choosing Maven (I'm using the Maven-eclipse-plugin as specified in other posts which is the source of the Maven right click menu in Eclipse), then adding this plugin: maven-compiler-plugin.

I then replaced configuration node as specified above but using the variable I created in my settings.xml profile:


<configuration>
<verbose>true</verbose>
<fork>true</fork>
<executable>${MY_JAVA_HOME}/bin/javac</executable>
<compilerVersion>1.6</compilerVersion>
</configuration>


Seems to work, however there is a warning in the above link that this does not necessarily force the compiler to use the specified JDK version (which I find kind of odd also - use my configuration and throw an error if it won't work).

I actually dropped out of Eclipse and ran mvn install from the command line to get a bit more control over what was going on and was able to get all my projects to compile and install again.

I personally don't like when my software applications do things I don't ask them to do and don't tell me about it - and it's not the way I have it configured.

Tuesday, October 05, 2010

Securing Encryption Keys

I see a lot of articles about encryption but not a lot of information about protecting encryption keys. What good does encryption do if someone has the key? That's like locking your house when you leave for work but leaving the key hanging on the door.

Let's say you encrypt a configuration file. Now you start up your app and you need to decrypt that file. In order to decrypt there's a key somewhere most likely that allows decryption of that file. Where is that key stored? Do you have to type it in when you run the application? Do you have to look it up in a database? How do you secure access to that database? Do you put it in another file? How do you secure access to that file over and above the way you secured access to the configuration file itself?

Whoever has access to that key can decrypt your data - do network admins have access to the file with the key? Do database administrators have access to the key stored in the database? Can a hacker access the key through a backdoor or SQL injection under the permisissions of the user account that runs your web application? Is the key sent unprotected over the network or with weak SSL encryption? Is the key floating in memory on your machine in easy to spot format? Is it embedded in a Java class that is simple to decompile using tools on the web? Are your files and databases backed up to a back up device accessible by third parties? How do you implement checks and balances required for PCI Compliance in terms of encryption key storage and retrieval?

Here is some information I was able to find on the topic:

Some suggestions for protecting encryption keys
http://it.toolbox.com/wiki/index.php/Protect_encryption_keys_in_memory,_files,_databases,_and_during_transport_between_system_processes


PCI Encryption suggestions:
http://forums.sun.com/thread.jspa?threadID=5433515

Limited information but discussing the issues around keys:
http://www.symantec.com/connect/articles/introduction-encryption

Encryption key policy from SANS:
http://www.sans.org/security-resources/policies/User_Encryption_Key_Protection_Policy.pdf

Intel loses DRM Protection Key 9/17/2010 - key management is not simple...
http://www.voltage.com/products/data_protection.htm

Voltage has been in the encryption / key management space for a while - but how are your keys secure when given to a third party?
http://www.voltage.com/products/data_protection.htm

Saturday, July 17, 2010

Sunday, July 11, 2010

Maven Mysteries - Generics and Compiler Issues

Maven by default compiles code with a lower compiler version than 1.5 which has support for generics.

Today I was programming along when suddenly a project that has been compiling for a while suddenly stopped compiling (using Maven + Eclipse) and Maven started griping about the project code's inclusion of generics when this is not supported prior to JDK 1.5. Hmm. I had this working before so why did it suddenly start failing? Who knows.

So I go in and reset the project to use the 1.6 compiler by right clicking on the project node in Eclipse, choosing compiler and changing the settings.

No dice.

I then right clicked on the project node, chose Maven (I'm using Maven plugin as described in another post) and choose "Update Project Configuration". Right click on the pom, choose Run As and Maven Install...well then I started getting compiler errors in Eclipse I wasn't getting before. I went to one of the errors, right clicked and told it to change the project to use JDK 1.5 which supports generics.

Ok now it compiles...but now the setting changes I just made say 1.5 instead of 1.6. Why didn't it work when I set the project to use JDK 1.6? So I go back to the project node, change the compiler setting to JDK 1.6. Still compiles. That's good.

Then I go right click and choose Maven and Update Project Configuration. Running Maven Install still works.

OK great. Whatever.

Classloaders In Depth

Digging into the details of classloads has been on my list of research items for a while. I understand the concepts and the implications - what if a class gets loaded other than the one you intend to be running in your app and you're not really running the code you think you are?

Anyway...ran into this error today...

java.lang.LinkageError: loader constraint violation: when resolving method "[class]" the class loader (instance of [classloader1]) of the current class, [class], and the class loader (instance of [classloader2]) for resolved class, [class], have different Class objects for the type [class in conflict] used in the signature

Which led me to this great blog post which does a great job of epxlaining the nitty gritty of class loaders and potential issues with self-first and parent-first class loading...

Java Class Loaders

Nice.

Oh and by the way, I fixed this by changing the package of the class in my web app so it was different than the package of the conflicting class loaded by the web server. This may not be the right solution in all cases - you may want to remove the class from your web app and use the parent class or vice versa instead.

Saturday, July 10, 2010

Strange Network / Web Site behavior

Something very odd happened when I transferred web sites from one network to another, and view them using one particular network provider.

If I hit the web sites in rapid succession the images go all wacky and some images will get displayed multiple times when they are only supposed to be displayed once, for instance. These are straight html pages - about as basic as you can get.

I cannot reproduce this skewing of the web pages when working locally on the machine that is hosting the web site.

I also noticed that when I strolled down to the local coffee shop with my laptop I could not reproduce this funky behavior. This leads me to believe that the problem is due to the network or software thereon of the ISP at the particular location having the problem. It seems like something is capturing and altering the results of the request in transit and at some point before reaching my computer they are getting skewed.

Will have to research further.

7/15/2010

Interesting...last night I uncovered that my mail seemed to be going through a proxy server. They claimed that my network traffic was not going out through any proxy servers previously, but I asked them to double check the web traffic since obviously something was affecting the email traffic and sending it where it shouldn't be going.

Magically today, I have not yet been able to reproduce whatever was causing web sites to be skewed. I have not yet tested on Comcast network again.

Tuesday, June 29, 2010

Database restore script - roles, users, permissions and schemas

I noted some code for creating some database roles and assigning users to them the other day. Here's a more extensive script that can be used when transfering databases between environments (say dev, test and production) where you want to assign users to specific schemas and roles, clear out permissions, and/or restore database users after restoring a database. Using a script is preferable to doing everything by hand because it can produce more consistent results and will be faster. Additionally you can use the same script in different environments and set up different users and/or schemas as needed.

This script should save a lot of time, though could be even more automated (creating logins for instance).

Additionally if you have existing users with appropriate permissions you may want to (I have recently learned) assign the new user in the newly restored database the old sysid to keep those permissions in tact.

Another item of note - all permissions and roles are stored in the master database. If you want to return to default roles and permissions, hopefully you have backed up the database and can restore the master database to retrieve those settings. Restoring the master database requires putting the SQL Server database in single user mode and there are a few tricks to that which I have around here somewhere...



/*

Before running this script:

a. create the user + pwd on the server

b. replace this everywhere found below with your new user name and schema:

set @newuser = 'test'
set @dbschema = 'dbs'

c. run script below which does the following:

add schema to all dbs
add user to all dbs
add all objects to schema @dbschema
add roles to dbs
add user to roles


*/



/*
STEP 1: add schema to every db
*/

Declare @dbschema varchar(10)
Declare @sql varchar(4000)

set @dbschema = 'dbs'

set @sql = 'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') ' +
' BEGIN ' +
' use ? ' +
' declare @s varchar(255) ' +
' if not exists(select name from sys.schemas where name=''' + @dbschema + ''')' +
' begin ' +
' set @s = ''create schema ' + @dbschema +
' '' exec (@s) ' +
' end ' +
' end '

print @sql
exec master.dbo.sp_MSforeachdb @sql

GO

/************
Step 2: change schema of all user defined objects
************/

Declare @sql varchar(2000)
Declare @cntitems int
Declare @dbschema varchar(20)
Declare @oldschema varchar(20)
Declare @itemname varchar(128)
Declare @db varchar(128)

set @dbschema = 'dbs'

if (select object_id('tempdb..##objnames')) is not null
drop table ##objnames

create table ##objnames (itemname varchar(128), oldschema varchar(128), dbname varchar(128))

set @sql = 'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') ' +
' BEGIN ' +
' use ? ' +
' insert into ##objnames select t.name, s.name, ''?'' from ' +
' sys.all_objects t ' +
' left outer join sys.schemas s ' +
' on s.schema_id = t.schema_id ' +
' where is_ms_shipped = 0 and parent_object_id = 0 ' +
' and type_desc <> ''system_table'' and ' +
' t.name not like ''dt_%'' and t.name not like ''%#'' and s.name <> ''' + @dbschema +
' '' END'

print @sql

exec master.dbo.sp_MSforeachdb @sql

/*****
loop through the objects we found and change schemas
******/

select @cntitems=count(*) from ##objnames

While @cntitems > 0
begin
select top 1 @itemname=itemname, @oldschema = oldschema, @db = dbname from ##objnames

delete from ##objnames where itemname = @itemname and oldschema=@oldschema and dbname=@db

if (@itemname like '%-%')
print ('ERROR: cannot update item with - in name: ' + @itemname)
else
begin
set @sql = 'use ' + @db + ' ALTER SCHEMA ' + @dbschema + ' TRANSFER ' + @oldschema + '.' + @itemname
print (@sql)
exec (@sql)
end
select @cntitems=count(*) from ##objnames

end


/*********
step 3: delete orphan users now that schemas are fixed
**********/

-- var for exec sql

-- vars are for db loop below
declare @CNT int
declare @name char(128)
declare @sid varbinary(85)
declare @c int
declare @hexnum char(100)

set nocount on


/*
You may need to change the database owner...

set @sql = 'select @cnt = count(*) from master..syslogins l right join ' +
rtrim(@db) + '..sysusers u on l.sid = u.sid' +
' where l.sid is null and u.name = ''DBO'''
exec sp_executesql @sql,N'@cnt int out',@cnt out

if DB is not mapped to login that exists map DBO to SA
if @cnt = 1
begin
--print 'exec ' + @db + '..sp_changedbowner ''SA'''
-- exec sp_changedbowner 'SA'
end -- if @cnt = 1
*/

Declare @sql varchar(1000)
Declare @db varchar(50)

if (select object_id('tempdb..##orphans')) is not null
drop table ##orphans

create table ##orphans (orphan varchar(128), dbname varchar(128))

set @sql= 'BEGIN ' +
' use ? ' +
' insert into ##orphans select u.name, ''?'' from master..syslogins l right join ' +
' sysusers u on l.sid = u.sid ' +
' where l.sid is null and issqlrole <> 1 and isapprole <> 1 ' +
' and (u.name <> ''INFORMATION_SCHEMA'' and u.name <> ''guest'' and u.name <> ''dbo'' ' +
' and u.name <> ''system_function_schema'' ' +
' and u.name <> ''sys'') and u.name <> ''MS_DataCollectorInternalUser'' ' +
' END '

exec master.dbo.sp_MSforeachdb @sql

select @cnt = count(*) from ##orphans

WHILE @cnt > 0
BEGIN

select top 1 @name= orphan, @db = dbname from ##orphans
delete from ##orphans where orphan = @name

set @sql = 'exec ' + rtrim(@db) + '..sp_revokedbaccess ''' + rtrim(@name) + ''''
print @sql
exec (@sql) -- drop the orphan from the db

select @cnt = count(*) from ##orphans

end
go

/**********
Step 4: create roles and assign user to roles
*********/
Declare @newuser varchar(20)
declare @dbschema varchar(20)
Declare @sql varchar(1000)

set @dbschema = 'dbs'
set @newuser = 'test'

/* create the cto roles on each database */

set @sql = 'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') ' +
' BEGIN ' +
' use ? ' +
' IF NOT EXISTS (select * from sys.database_principals where name=''dbs_select'') ' +
' create role dbs_select ' +
' end '

print @sql

exec master.dbo.sp_MSforeachdb @sql

set @sql = 'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') BEGIN ' +
+ ' use ? ' +
' IF NOT EXISTS (select * from sys.database_principals where name=''dbs_execute'') ' +
'create role dbs_execute ' +
' end '

print @sql

exec master.dbo.sp_MSforeachdb @sql

set @sql = 'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') BEGIN ' +
+ ' use ? ' +
' IF NOT EXISTS (select * from sys.database_principals where name=''dbs_delete'') ' +
'create role dbs_delete ' +
' end '

print @sql

exec master.dbo.sp_MSforeachdb @sql

set @sql = 'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') ' +
' BEGIN ' +
' use ? ' +
' IF NOT EXISTS (select * from sys.database_principals where name=''dbs_update'') ' +
' create role dbs_update ' +
' end '

print @sql

exec master.dbo.sp_MSforeachdb @sql

set @sql = 'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') BEGIN ' +
+ ' use ? ' +
' IF NOT EXISTS (select * from sys.database_principals where name=''dbs_insert'') ' +
' create role dbs_insert ' +
' end '

print @sql

exec master.dbo.sp_MSforeachdb @sql


/* grant these roles permissions to cto schema in this database */
set @sql = 'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') ' +
' begin ' +
' use ? ' +
' grant execute on schema :: ' + @dbschema + ' TO dbs_execute ' +
' end '

print (@sql)

exec master.dbo.sp_MSforeachdb @sql

set @sql = 'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') ' +
' begin ' +
' use ? ' +
' print ''?'' '+
' grant select on schema :: ' + @dbschema + ' TO dbs_select ' +
' end '

print (@sql)

exec master.dbo.sp_MSforeachdb @sql

set @sql = 'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') ' +
' begin ' +
' use ? ' +
' grant delete on schema :: ' + @dbschema + ' TO dbs_delete ' +
' end '

print (@sql)

exec master.dbo.sp_MSforeachdb @sql

set @sql = 'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') ' +
' begin ' +
' use ? ' +
' grant insert on schema :: ' + @dbschema + ' TO dbs_insert ' +
' end '

print (@sql)

exec master.dbo.sp_MSforeachdb @sql

set @sql = 'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') ' +
' begin ' +
' use ? ' +
' grant update on schema :: ' + @dbschema + ' TO dbs_update ' +
' end '

print (@sql)

exec master.dbo.sp_MSforeachdb @sql

set @sql =
'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') ' +
' begin ' +
' use ? ' +
'if not exists( select u.name from master..syslogins l right join ' +
+ '?.dbo.sysusers u
on l.sid = u.sid
where u.name=''' + @newuser + ''') create user ' + @newuser
+ ' end '
print (@sql)
exec master.dbo.sp_MSforeachdb @sql



/* assign user to roles in each db */
set @sql = 'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') BEGIN ' +
' use ? ' +
' exec sp_addrolemember ''dbs_execute'', ' + @newuser +
' end '

print @sql

exec master.dbo.sp_MSforeachdb @sql


set @sql = 'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') BEGIN ' +
' use ? ' +
' exec sp_addrolemember ''dbs_select'', ' + @newuser +
' end '
print (@sql)
exec master.dbo.sp_MSforeachdb @sql

set @sql = 'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') BEGIN ' +
' use ? ' +
' exec sp_addrolemember ''dbs_insert'', ' + @newuser +
' end '
print (@sql)
exec master.dbo.sp_MSforeachdb @sql


set @sql = 'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') BEGIN ' +
' use ? ' +
' exec sp_addrolemember ''dbs_update'', ' + @newuser +
' end '
print (@sql)
exec master.dbo.sp_MSforeachdb @sql


set @sql = 'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') BEGIN ' +
' use ? ' +
' exec sp_addrolemember ''dbs_delete'', ' + @newuser +
' end '
print (@sql)
exec master.dbo.sp_MSforeachdb @sql

set @newuser='test'
set @dbschema = 'dbs'

set @sql = 'IF ''?'' NOT IN (''master'', ''model'', ''msdb'', ''tempdb'') ' +
' begin ' +
' use ? ' +
' declare @s varchar(255) ' +
' set @s = ''alter user ' + @newuser + ' with default_schema = ' + @dbschema + ' '' ' +
' exec (@s) ' +
' end '


print (@sql)

exec master.dbo.sp_MSforeachdb @sql

-- Remove temporary tables
drop table ##orphans, ##objnames

Saturday, June 12, 2010

The statement did not return a resultset - bug: MS JDBC driver + SQL Server 2000

There is a bug that has been driving me insane. I thought I was doing something wrong but apparently it's a bug in Microsoft SQL Server JDBC driver when using SQL Server 2000.

I had a bunch of sprocs that were failing for no apparent reason. I thought it was code change to incorporate a database connection pool. Coincidentally I updated the Microsoft JDBC driver at the same time and forgot about it.

Oddly enough the fix is to add "SET NOCOUNT ON" to stored procedures and then things run as expected.

The statement did not resturn a ResultSet

The Resultset has No Current Row

If you get this error using Microsoft JDBC driver to return records as a ResultSet:

The ResultSet has no current row

ResultSet rs = getResultSetFunction();
rs.next() <-----------

"ResultSet has not current row" does not mean that the resultset has not returned any records. It means that the recordset has not been positioned to the row you want to read from. When you first load the recordset, it's not positioned to any row.

So rs.next() will position the resultset to the first row (i.e. make the first row the current row), so you can read some data from that row.

The result set needs to have a current row to read some data from it.

Saturday, May 29, 2010

Java Map Collection Classes

Choosing the right collection class has an impact on the performance of your application. In a previous post I gave a run down of Big O Notation. A hash map look up will have better performance generally than other types of collections when you can look up the data based on a key - O(1) since the underlying data structure is an array - and is useful when the order of the data is not important.

This article has a good run down of Java Maps including how they work and how to choose the right one for your application:

Java Map Collection Classes

In general the concept of optimizing for performance after the application has been built - by actually profiling the application and then making specific implementation decisions - is something I liked to hear. You need to understand the basics to implement a solid architecture but true optimization happens after you can measure the performance, taking all application variables into account from network to hardware to various software components and data distribution, and determining where your bottlenecks lie once you can actually measure the results of your particular application.

Sunday, May 23, 2010

AJAX Attack Surface

I have read articles stating Ajax *supposedly* does not increase the attack surface of a web application.

Whether or not that statement is true, I've personally been cautious about integrating Ajax into web applications I've written. This isn't because I have anything against Ajax or think people shouldn't use it or that I think there's anything wrong with the technology - the concept is great. In fact I implemented an Ajax like client side very complex quote calculation JavaScript library of sorts for a web site prior to ever hearing of Ajax many years ago to reduce round trips to the server and improve performance for web visitors.

The reason for my caution is that I wanted to completely understand how Ajax functions -- and how to secure applications using it -- before integrating it. To prevent lost sales and problems for my customers, it is easier and just as effective to just leave it out for most web sites which don't have a good justification for using it. For web sites that perform very well, get great search engine rankings and drive lots of business to those customers (and isn't that the point?) without it, Ajax may only be a source of new problems and expense that is not worth the cool factor.

However I have had customers who insist on Ajax and there are times where it does make sense - especially for applications with complex user interfaces that might otherwise use frames, for example, to prevent going back to the server for the same data over and over again - so have been revisiting and working with Ajax lately and researching the security issues surrounding it.

I just read an article by a "white hat" security web site claiming Ajax does not increase the attack surface of a web application. It has very high search engine rankings presumably because all the people who don't understand or care about the security implications of all the new "cool" technology they throw on their web sites are linking to it to prove to the world that Ajax doesn't pose any additional security problems because that's what someone wrote - without really understanding or thinking about the underlying architectural changes that result from using Ajax.

Well, it's probably a semantic argument because the point is, your web site needs to be secure and you need to constantly monitor both your web site and the security newsgroups and publications for new threats. And yes, using Ajax is probably fine and any web technology you choose to use needs to be implemented securely.

However I disagree that Ajax does not increase the attack surface on a web application. Here's why:

#1. Definition of attack surface:

Attack Surface

The attack surface of a software environment is the code within a computer system that can be run by unauthenticated users.

In other words, more code, components and entry points = greater attack surface.

#2. How you reduce attack surface (same article):

The basic strategies of attack surface reduction are to reduce the amount of code running, reduce entry points available...

#3. New object created by third party - Ajax requires Ajax request object which you don't need if not using Ajax. That means you've introducing a new component and more code - which increases the attack surface. Every new thing you add to a software system is a potential new security problem no matter where it originates. That is the nature of software and systems - not because any particular thing you add has inherent security flaws (a separate issue and some things are riskier than others).

#4. More code (most likely) to support Ajax server side. Chances are pretty good that incorporating Ajax into your code base introduces server side code to support smaller requests server side that handle updating subsections of pages.

#5. More client side code. When someone clicks on something that initiates an Ajax request they are running client side code to make the request. That code wasn't needed before Ajax.

#6. Another entry point. Code is going through client side requests handled initially by JavaScript now instead of just being a link clicked on in the browser that is parsed into a request by the browser and sent over. In addition to the browser parsing you now have some code written by the web developer that has to decipher the request and do the right thing with it, potentially check additional user input, and handle errors appropriately. This is an additional step that wasn't there without Ajax. Probably you have new entry points server side as well for more, smaller requests to the web server.

Besides all that...

The thing that I am most concerned about is JavaScript code running client side that, if errors out before gets to the web server, is an error you'll never know about unless the programmer captures the error and sends it back to the server. This is something many sites don't do - including some large company web sites - because if they were doing it correctly I would never see JavaScript errors. And I do all the time.

Client side errors (in the most case without complex error logging or if your error logging fails) won't be in your web server logs and is a clear weak point that hackers will look at to attack your web application in ways that can be hidden from your view. They don't have to cover their tracks in logs. The person using the web site and the person running it may never know anything went wrong.

For example, if a hacker was able to exploit your JavaScript client side to redirect customers making purchases on your site to an alternate site instead so they get the sale, if it all happened on the client machine you'll think the customer just dropped out during the purchase. You'll have no tracks on your web server, no fingerprints, no clues. The customer may have gone onto make a purchase and received what they bought so they never knew there was a problem either. The other thing is code can be introduced to execute client side functions behind the scenes that don't go to the web server and don't show the user that anything is going on.

So, I would say Ajax increases the attack surface, but even if that technically is not true due to some semantically technical, philosophical justification - Ajax makes applications more complex with trickier security problems (maintenance issues, and bugs). In my opinion.

That doesn't mean I'm not using it. I'm just trying to figure out how to use it correctly and think too many people throw doodads and cool new technology on their web sites without really understanding the implications of using it and how to implement it in a secure manner.

Files Altered On Web Request

Just experienced strangeness with JavaScript in browser which has various maintenance and security implications.

While testing a web site using Jetty 6.1.12 and Eclipse with Jetty plugin, I noticed that somehow magically after requesting a web page, my files were ending up with extra characters at the end and I wasn't editing them. This happened both with HTML files and JavaScript files. It looked like the file would get the last 150 or so characters at the end of the document copied and pasted to the end of it. I would fix the file. Open it up to verify my fixes were saved. Then I would start and run the application and the problem would happen all over again.

This is odd - The source files shouldn't get edited and saved to disk when I make request to the web site. What would be changing them - the browser? Jetty? Jetty Eclipse Plugin? The OS? Browser plugin? Virus scanning software? Something in network? This is where it gets tricky.

The source files shouldn't get edited and saved to disk when I make request to the local web site. That should never alter the source code in the original web site. The original source files were altered, not just the code shown by view source in the browser or cached JavaScript source.

I figured out a few of things:

1. Could fix the files (delete the extra characters) in WordPad, but NotePad wouldn't make the changes stick for some reasons. I also realized later that NotePad wasn't alerting me when it didn't save the file if locked. WordPad would tell me. I had to shut down the web server to change the files even after setting ofline storage to 0 in FireFox.

2. After fixing the files they would continue to get corrupted. I finally made them read only to try to resolve the problem and changed my logging to indicate any time the files changed or there was an access error to try to pinpoint what was changing them. Even when the files were read only they still got changed and no logs indicating how they were changed or what changed them.

3. JavaScript functions in HTML file and did not have issues and the page loaded consistently on a few tests (did not test extensively).

4. FireFox does not log an error if your JavaScript src file path is incorrect. It just tells you a particular function is missing.

5. I realized even though I thought I turned off Firefox caching was still caching JavaScript files. Closing and opening browser would ensure I was getting the right file.

6. At one point I noticed that I had two opening head tags instead of correctly closing the head tag. That may have caused errors - but shouldn't have caused my source files to get altered.

7. I started working offline to remove any issues related to things getting cached somewhere related to being on the network even though the web page I am requesting is localhost.

8. When I initially had this problem I checked in both IE and FireFox and the same thing seemed to be happening, but perhaps one of them was altering the file so when I checked in the other I got the same result.

I don't know which of the above actually solved the problem but I'm not seeing it anymore and don't have time to explore this further. Just posting it online in case the makers of all this software want to figure out what in the world caused this because having software rewrite your source files when a web page is requested - is a bit troubling.

Tuesday, May 18, 2010

Generic Ajax Request

Here's a generic way to create an AJAX request (AJAX code below being JavaScript):

function createRequest(){

request=null;

try{
request = new XMLHttpRequest();
}catch(tryMS){
try{
request = new ActiveXObject("Mxsml2.XMLHTTP");
}catch(otherMS){
try{
request = new ActiveXObject("Microsoft.XMLHTTP");
}catch(failed){
request=null;
}
}
}

return request;
}


And a sample function that uses it:

function getPage(){

try{

request = createRequest();

var url ="/some/page.html";

request.open("GET", url, true);

request.onreadystatechange=displayPage;

request.send(null);

}catch(e){
alert(e)
}

}


function displayPage(){
try{
if (request.readyState== 4){
obj = document.getElementById('someDiv');
if (request.status== 200){
obj.innerHTML = request.responseText;
}
}
}catch(e){
alert(e + request.responseText);
}
}

Next on the reading list:

Ajax Security

Remove file association with .lnk files in Windows 2008

Why Microsoft allows you to change all .lnk files to be associated with Notepad in Windows 2008 (or any other OS for that matter) I'll never know. Obviously that is going to royally mess things up. It's easy to do also because I just did it - I actually couldn't see I was opening a .lnk file because it had a really long path and in Windows 2008 the interface is funky (don't really like it). I right clicked and chose to open with Notepad. I guess the box was automatically checked to open all files of that sort with Notepad (I didn't check it).

Great. Now all my icons on the whole system show Notepad. When I clicked on any short cut it opened the short cut file in Notepad and displayed gibberish instead of opening the related program. So I thought ok, I'll just go into file associations and restore to default. Nope. Not so simple. There's no option to unassociate the file or restore to default (that I saw at first glance).

Sheesh.

So I just guessed that this might be in the registry and because I live my life on the edge, I searched for the .lnk file association and found it. Actually don't live that dangerously because I compared the settings to another machine that was working and determined that I needed to delete the "OpenWithList" node. Then log out and log back in.

Ouilla.

Saturday, May 08, 2010

Jetty 503 - Service Unavailable

This is the type of programming issue that could drive one insane.

For some reason, suddenly getting 503 error in Jetty running Jetty Maven Plugin in Eclipse. That's it. No other explanation. Servlet could not be initialized. No additional clues to be had. Logging is printing to screen. Nada of use.

Finally just recomplied the whole multi-node project. Got errors that certain directories could not be deleted. Could not delete the directories manually until I closed Eclipse and everything related to this thing.

Once I deleted the directories and re-installed all the nodes, it worked again.

Thursday, May 06, 2010

error reading /root/.m2/repository/javax/jms/jms/1.1/jms-1.1.jar; error in opening zip file

So I'm working away minding my own business and suddenly code that has been compiling stops compiling without any changes to the configuration. Apparently Maven has decided it needs to download something different - or re-download something which has moved and suddenly generating errors.

Anyway the error:

error reading /root/.m2/repository/javax/jms/jms/1.1/jms-1.1.jar; error in opening zip file

Maven attempting to download missing files

I agree.

But anyway I figured out that log4J was the problem and removed it from my project since working on different logging mechanism. Why in the world has this been compiling for weeks and suddenly stops? Hmmm?

Additionally after I pulled out log4J I got a bunch of errors about java mail components missing. Apparently those classes must have been part of the log4j jar but I didn't look.

The implication being that my app was using the log4j mailer classes rather than the java mail jar I downloaded from Sun java web site in my web app.

I would look into this further but since I removed log4j from my app my work here is done.

Wednesday, May 05, 2010

Asynchronous HTTP Requests

Informative article on Asynchronous HTTP requests.

Asynchronous HTTP Requests

Ah...but custom protocol handlers...ugh.

Checking out Jetty asynchronous HTTP client...
Jetty Http Client - Asynchronous web requests

Another implementation for review...but this an asycnhronous page fetcher... Hmm....the point of asynchronous is that you don't wait for a response right? At least that was my goal...

Asynchronous Web Page Fetcher

Cold Fusion Number Precision Problem

From some tax documentation I am reading for Sales Tax Online web tax calculation component:

"You may encounter a precision problem for very large amounts when using the ColdFusion number type. Because this type has a very large exponential range, it necessarily sacrifices precision in the number of significant digits it can carry. This will not generally be a problem with amounts expressed in currencies that have only two significant fractional digits (e.g., US Dollars), however, foreign currencies can have as many as four significant fractional digits. A value with a large non-fractional portion could suffer a rounding error in the fractional digits."

Monday, May 03, 2010

Chinese Jar Missing

Hmm. What is this all about.

Problem processing jar entry
com/ibm/icu/impl/data/LocaleElements_zh__PINYIN.class

Suddenly started appearing when running Jetty plugin without me adding anything to my project in terms of dependencies, included classes, etc.

Also coincidentally the whole structure of my Eclipse menus changed as well. Not sure if related. I didn't do anything to update Eclipse. I assume this is all automagic - not sure how I feel about that.

Anyway apparently this error can be ignored (don't usually like that answer) because some jar scanner couldn't find a jar, but didn't stop execution.

Read about it here:
http://www-01.ibm.com/support/docview.wss?uid=swg1PK81656

This is the stack trace:

2010-05-03 23:49:59.202:WARN::Problem processing jar entry com/ibm/icu/impl/data/LocaleElements_zh__PINYIN.class
java.lang.ArrayIndexOutOfBoundsException: 48188
at org.objectweb.asm.ClassReader.readClass(Unknown Source)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
at org.eclipse.jetty.annotations.AnnotationParser.scanClass(AnnotationParser.java:596)
at org.eclipse.jetty.annotations.AnnotationParser.access$000(AnnotationParser.java:43)
at org.eclipse.jetty.annotations.AnnotationParser$2.processEntry(AnnotationParser.java:576)
at org.eclipse.jetty.webapp.JarScanner.matched(JarScanner.java:152)
at org.eclipse.jetty.util.PatternMatcher.matchPatterns(PatternMatcher.java:82)
at org.eclipse.jetty.util.PatternMatcher.match(PatternMatcher.java:64)
at org.eclipse.jetty.webapp.JarScanner.scan(JarScanner.java:75)
at org.eclipse.jetty.annotations.AnnotationParser.parse(AnnotationParser.java:588)
at org.eclipse.jetty.annotations.AbstractConfiguration.parseWebInfLib(AbstractConfiguration.java:108)
at org.eclipse.jetty.annotations.AnnotationConfiguration.configure(AnnotationConfiguration.java:77)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:975)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:608)
at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:155)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:349)
at org.mortbay.jetty.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:102)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:165)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:162)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:165)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:92)
at org.eclipse.jetty.server.Server.doStart(Server.java:231)
at org.mortbay.jetty.plugin.JettyServer.doStart(JettyServer.java:69)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:433)
at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:377)
at org.mortbay.jetty.plugin.JettyRunMojo.execute(JettyRunMojo.java:546)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:105)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:577)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:324)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:247)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:104)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:427)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:157)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:121)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)