Monday, October 15, 2007

Solution to classpath too long (aka input line too long) problem in Windows

If you use Java in Windows, you're bound to run into classpath too long problem when your classpath grows. Windows has a limit (1KB - 2KB) of characters you can have on one single command line. The infamous "Input line is too long" is very annoying. Here's a trick to get around it.

"java.exe" command also scan for classes from the environment variable "CLASSPATH". If you can break your classpath into separate folders and jars, you can concatenate them like this:


setlocal

set CLASSPATH=c:/my/first/jar/somejar.jar;%CLASSPATH%
set CLASSPATH=c:/my/second/jar/someotherjar.jar;%CLASSPATH%
set CLASSPATH=c:/path/to/a/folder;%CLASSPATH%
.......
.......

java com.mycompany.Main

endlocal

By using CLASSPATH env variable, you don't need to pass it in to "java" command. The setlocal/endlocal pair ensures the CLASSPATH is "local" to this process and won't pollute the systemwise value.

--------
Updated:

Travis has pointed out that there is a limit on environment variable in Windows. I found it limited to 8K. So this isn't an absolute solution but it should sustain you for awhile. As suggested by D, you could shorten the path by using virtual drive. Further more, JDK6 has supported wildcard (*) in classpath.

Virtual drive:
Say you have bunch of jars under c:/path/to/lib

subst z: c:/my/path/to/lib
set CLASSPATH=z:/jar1.jar:%CLASSPATH%

Or with JDK6:

set CLASSPATH=c:/path/to/lib/*:%CLASSPATH%

Monday, October 08, 2007

Check for broken links in Ruby, Bash script and Java

I found myself writing 3 different versions of a function to check for broken links in Ruby, Bash and Java. Just want to document here in case anyone interested. Note that these functions use HEAD method (as opposed to GET/POST). It won't download a big file just to see if it's live.

Ruby
require 'net/http'
require 'uri'

def isLive?(url)
uri = URI.parse(url)
response = nil
Net::HTTP.start(uri.host, uri.port) { |http|
response = http.head(uri.path.size > 0 ? uri.path : "/")
}
return response.code == "200"
end

puts isLive?("http://google.com")
puts isLive?("http://asdfasdf.com")

Bash
#!/bin/bash

function isLive {
wget -q --spider $1
}

isLive "http://google.com/somefakelink"

if [ $? -eq 0 ]; then
echo "Good link"
else
echo "Broken link"
fi

Java: Edited (December 18 2008): I've written a better Java version that handles link forwarding and doesn't use 3rd party API here

/* need httpunit-1.6.jar http://httpunit.sourceforge.net */

private boolean isLive(String link) {
try {
WebRequest request = new HeadMethodWebRequest(link);
WebConversation wc = new WebConversation();
WebResponse response = wc.getResource(request);
return response.getResponseCode() == 200
} catch (Exception e)
return false;
}
}