我试图用Ant执行一些JAX-WS代码,虽然javac目标成功,但java目标失败:
java.lang.ClassNotFoundException: com.sun.xml.internal.ws.spi.ProviderImpl
现在,如果我显式地将以下jar添加到java任务使用的类路径:
/usr/lib/jvm/java-1.7.0-openjdk-i386/jre/lib/rt.jar
…然后执行成功,但这不应该是必要的,因为JAVA_HOME是正确设置的:
$ echo $JAVA_HOME
/usr/lib/jvm/java-7-openjdk-i386
此外,我回显java Ant使用的版本,我得到:
ant.java.version=1.7
这是我的Ant run任务的相对部分:
<echo message="ant.java.version=${ant.java.version}" />
<java classname="${project.MainClass.name}">
<classpath refid="run.classpath"/>
</java>
最后,如果我从命令行(而不是在Ant中)运行代码,执行也会成功,而不必显式地将rt.jar添加到CLASSPATH。
更新和分辨率
查看公认的答案,我认为这是与使用内部Sun类相关的更广泛的一类问题的一个实例。正如在这个回答中提到的,要针对内部Sun类显式编译,必须设置javac -XDignore.symbol.file
标志。这是因为在默认情况下,javac
不链接rt.jar
文件,而是链接一个特殊的符号文件lib/ct.sym
,其中包含许多(但不是全部)Sun的类。显式地在类路径中添加rt.jar
也解决了同样的问题,但我认为使用javac -XDignore.symbol.file
更干净。至于为什么当fork
被设置为true(正如这个答案所建议的)时,Ant明显地针对rt.jar
进行编译,我仍然不知道。
回想起来,我认为javac
在CLASSPATH中不包括rt.jar
是有道理的。
添加编译器参数:
<compilerarg value="-XDignore.symbol.file" />
这个为我工作:
<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>
解决方案是将java的Ant任务fork属性设置为"true":
<java classname ="${project.MainClass.name}" fork="true">
<classpath refid="run.classpath"/>
</java>
当fork被设置为"true"时,rt.jar不必显式地出现在run.classpath中。