2

次のテストを行いました。

コード

public class FooMain {
   public static void main(String args[]) throws ClassNotFoundException {
      Class klass = Class.forName("com.sun.xml.internal.ws.spi.ProviderImpl");
   }
}

$CLASSPATH 環境変数

echo $CLASSPATH
/usr/lib/jvm/java-7-openjdk-i386/jre/lib/rt.jar:.
jar tvf /usr/lib/jvm/java-7-openjdk-i386/jre/lib/rt.jar | grep com.sun.xml.internal.ws.spi.ProviderImpl

 1742 Wed Oct 24 18:52:52 EEST 2012 com/sun/xml/internal/ws/spi/ProviderImpl$1.class
 1349 Wed Oct 24 18:52:52 EEST 2012 com/sun/xml/internal/ws/spi/ProviderImpl$2.class
12412 Wed Oct 24 18:52:52 EEST 2012 com/sun/xml/internal/ws/spi/ProviderImpl.class

したがって、求められているクラスは $CLASSPATH にあります。

ただし、Ant のJavaタスクとforkを"false"に設定して上記のコードを実行すると失敗し、 forkが"true"に設定されている場合にのみ成功します。

ただし、これはANT in Action bookに書かれている内容に反しています。152 では、基本的な Ant の Java タスクが、「CLASSPATH 環境変数のすべて」などを含む Ant クラスパスで実行されることを確認しています。

では、 forkが「false」に設定されていると、 Ant のJavaタスクが目的のクラスを見つけられず、 forkが「true」に設定されている場合にのみ成功するのはなぜですか?

4

2 に答える 2

4

fork="false"タスクでは、タスク自体のクラスパス(属性またはネストされた要素)からの<java>クラスをロードする特別な「分離された」クラスローダーを使用します。ただし、ハードコードされたパッケージプレフィックスの特定のセットは、親ローダーからロードしようとします。タスク自体のクラスパスにはありません。はこのハードコードされたリストに含まれていないため、親に委任されないため、が表示されます。classpathref<classpath>com.sun.xmlClassNotFoundException

于 2013-01-20T23:07:01.380 に答える
2

マニュアルページには、Java タスクの操作に関する次の説明があります。

実行中の (Apache Ant) VM 内で Java クラスを実行するか、指定されている場合は別の VM をフォークします。

このタスクの実行時に異常が発生した場合は、fork="true" を設定して新しい JVM を使用します。

ANT を使用してクラスパスを管理する

常に JVM をフォークし、ANT クラスパス管理機能を利用することを強くお勧めします。

<path id="runtime.path">
    <fileset dir="lib/runtimejars" includes="*.jar"/>
</path>

<java classname="???" fork="true" classpathref="runtime.path">
    <arg line="arg1 arg2 arg3"/>
</java>

なんで?ビルドを別のマシンに移植する場合、CLASSPATH 変数が同じように設定されているとは限りません。

実行可能 jar

CLASSPATH 変数への依存を減らすもう 1 つの方法は、実行可能な jar を作成することです。次の回答は、manifestclasspathタスクを使用して、jar のマニフェスト内に埋め込むことができるクラスパスを作成する方法を示しています。

于 2013-01-20T21:57:35.683 に答える