JDK 6 Supports * in Classpath But Be Aware of This

Finally JDK 6 (Mustang) lets me use wildcard (*) in classpath. I no longer have to enumerate all jar files in a lib directory. But with this added feature, it's easier to get errors like "javac: invalid flag:" For example, I want to complile a simple servlet, including all jar files in C:\Sun\AppServer\lib:
C:\tmp> javac -cp C:\Sun\AppServer\lib\*
HelloWorldServlet.java
javac: invalid flag: C:\Sun\AppServer\lib\addons
Usage: javac <options> <source>
use -help for a list of possible options
What's happening here is, the OS expands * to all files/directories in C:\Sun\AppServer\lib, since * has special meaning for the OS. So the real command resolves to:
javac -cp C:\Sun\AppServer\lib\activation.jar
C:\Sun\AppServer\lib\addon
C:\Sun\AppServer\lib\admin-cli.jar
C:\Sun\AppServer\lib\ant ... HelloWorldServlet.java
As all files/directories are expanded alphabetically, the first one (activation.jar) is treated as classpath element, and everything else starting with addon are treated as separate JVM options. Of course these are invalid JVM options, hence javac: invalid flag:

Note: if you are using javaw.exe instead of java.exe, * wildcard expansion in -cp or -classpath doesn't work, due to JDK 6 bug 6510337

So here are some tricks how to use * in classpath without getting burned:
  • "*" and "*.jar" have the same effect when used in classpath.
  • Quote it, if your classpath has a single element that uses *. For example,
    javac -cp "C:\Sun\AppServer\lib\*" HelloWorldServlet.java
  • This problem doesn't exist if you have more than one element in classpath, even though they do not exist. When in doubt, always quote your classpath value that uses wildcard.
    javac -cp C:\Sun\AppServer\lib\*;\nosuchdir HelloWorldServlet.java
  • This problem exists for all JDK tools that takes classpath option, including java. The error is different but solution is the same as above.
    java -cp C:\temp\* A
    Exception in thread "main" java.lang.NoClassDefFoundError: C:\temp\b/jar
  • Of course, if the directory contains 1 jar file, it will be expanded correctly, and you don't need to quote it. But using * doesn't save you much typing:
    java -cp C:\single-jar-file-folder\* A
    this is A
  • If on Unix, whether to quote or not quote wildcard classpath depends on which shell you are using. For example, tcsh or csh may fail with the following error: "java: No match." But the exact same command works under bash:
    java -cp tmp:$HOME/modules/*.jar Test abc

Followers

Pageviews Last 7 Days