Marcus Junius Brutus
Marcus Junius Brutus

Reputation: 27286

Ant java task can't find class in rt.jar but java from console succeeds (and JAVA_HOME is properly set)

I am trying to execute some JAX-WS code with Ant and although the javac target succeeds the java target fails with the following:

java.lang.ClassNotFoundException: com.sun.xml.internal.ws.spi.ProviderImpl

Now if I explicitly add the following jar to the classpath used by the java task:

/usr/lib/jvm/java-1.7.0-openjdk-i386/jre/lib/rt.jar

... the execution then succeeds but that shouldn't have been necessary as JAVA_HOME is properly set:

$ echo $JAVA_HOME
/usr/lib/jvm/java-7-openjdk-i386

Moreover, I echo the version of java Ant is using and I get:

ant.java.version=1.7

Here's the relative section of my Ant run task:

<echo message="ant.java.version=${ant.java.version}" />
<java classname="${project.MainClass.name}">                    
   <classpath refid="run.classpath"/>           
</java>

Finally, if I run the code from the command line (not from within Ant) execution also succeeds without having to explicit add rt.jar to the CLASSPATH.

update and resolution

Looking at the accepted answer I think this is an instance of a broader class of problems related to using internal Sun classes. As mentioned in this answer, to explicitly compile against the internal Sun classes one has to set the javac -XDignore.symbol.file flag. This is because javac does not by default link against the rt.jar file but rather against a special symbol file lib/ct.sym with class stubs that contains many (but not all) of Sun's classes. Explicitly adding rt.jar in the classpath also solves the problem for the exact same reason but I think it's cleaner to use javac -XDignore.symbol.file. As to why Ant apparently compiles against rt.jar when fork is set to true (as suggested by this answer), I still don't know.

In retrospect I think it makes sense that javac doesn't include rt.jar in the CLASSPATH.

Upvotes: 1

Views: 3160

Answers (2)

Meeraj Kanaparthi
Meeraj Kanaparthi

Reputation: 336

Add compiler argument:

<compilerarg value="-XDignore.symbol.file" /> 

This worked for me:

 <javac srcdir="src" destdir="build_output" source="1.7" target="1.7">
  <compilerarg value="-XDignore.symbol.file" />
  <classpath>
    <pathelement location="lib/......jar"/>
    <pathelement location="lib/....jar"/>
  </classpath>
</javac>

Upvotes: 1

Marcus Junius Brutus
Marcus Junius Brutus

Reputation: 27286

A solution was to set the java's Ant task fork property to "true":

<java classname ="${project.MainClass.name}" fork="true">
    <classpath refid="run.classpath"/>
</java>

When fork is set to "true" then the rt.jar doesn't have to be explicitly present in the run.classpath.

Upvotes: 0

Related Questions