Quote or escape your Java classpath in cygwin!

If you are using Java in cygwin, a little attention is necessary because two worlds collide. On the one hand, the Windows world, where the java.exe lives and on the other the bash of cygwin in which you are starting the command. In particular, when setting the classpath you need to pay attention to the differences.

Java on Linux separates its classpath entries using the colon (:) while Java on Windows separates the entries with a semi-colon (;). There is a good reason for this; on Windows the colon would have been impractical as it is used in file pathes (c:\…), on Linux the semi-colon is impractical, as it is used to end a command line.

Thus using the Windows Java in cygwin forces us to use the semi-colon (because that’s what the java.exe expects) in an enviornment where the semi-colon is a command line end. So to make it work, you need to either quote the argument or escape the semi-colons
$ java -cp "path/to/include;path/to/some.jar" Main
$ java -cp path/to/include\;path/to/some.jar Main

Else the following errors occur.
When using the semi-colon un-escaped:

$ java -cp .;Printer.jar PrintTest
Usage: java [-options] class [args...]
(to execute a class)
or java [-options] -jar jarfile [args...]
(to execute a jar file)
[...]

When using the colon (which would be correct in a Linux environment)

$ java -cp .:Printer.jar PrintTest
Exception in thread "main" java.lang.NoClassDefFoundError: PrintTest
Caused by: java.lang.ClassNotFoundException: PrintTest
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
Could not find the main class: PrintTest. Program will exit.


Posted

in

by