10

これについて多くの質問と回答が寄せられていることは知っていますが、まだ適切な解決策がなく、一部の部分を理解していません。そのため、*.java ファイルをプログラムでコンパイルする必要があります。

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

は私が使用しているもので、(予想どおり) コンパイラはnull. さて、JRE ではなく JDK を「ランタイム」として使用する必要があることはわかっていますが、ここで私が理解できないことがtools.jarあります。アプリケーションのクラスパスを入力してからアクセスするだけで十分ではないでしょうか。 Java コンパイラ API に? これが本当なら、スタンドアロンの Java アプリケーションと Web ベースのアプリケーションに違いはありますか (あると思います)。実際、私は PlayFramework webapp から JavaCompiler を呼び出そうとしているので、おそらくこのソリューション (を含むtools.jar) はスタンドアロン アプリケーションでのみ機能することがわかりました。

また、カスタム ClassLoader を作成し、上記のメソッドをリフレクションで呼び出そうとしましたが、取得しているnullのはcompilerオブジェクトだけです。

ClassLoader classloader = app.classloader();
File file = new File("lib/tools.jar");          
URL url = file.toURI().toURL();
URL[] urls = new URL[]{url};
ClassLoader newCL = new URLClassLoader(urls, classloader) {
};
Class<?> loadClass = newCL.loadClass("javax.tools.ToolProvider");
Method method = loadClass.getMethod("getSystemJavaCompiler", null);             
Object object = method.invoke(null);
System.out.println("Object: " + object); // NULL

上記のコードの説明:

  • 簡単にするために、try/catch は含めていません。
  • app.classloader() は、アプリの ClassLoader を返す Play メソッドです。
  • tools.jarPlayプロジェクトの私のlibフォルダーに含まれています(これは、Playのドキュメントによると、プロジェクトのクラスパス上にあることを意味します)

Play が Java Compiler クラスをロードできるようになる前に、他に何かしなければならないことがあると確信しています。何が欠けているのかわかりません。

や Eclipse JDT コンパイラなどのオプションRuntime.exec("javac myFile.java")は知っていますが、それは私が探しているものではありません。

ああ、そしてSystem.setProperty("java.home", "PATH_TO_YOUR_JDK");and thenのようなものToolProvider.getSystemJavaCompiler();が機能していますが、このソリューションはとても醜いと思います。

よろしくお願いします

EDIT : (追加情報を提供し、最後のステータスを反映するため) これは web-app-structure の基本的な表現です:

myApp
|-conf\...
|-lib\MyJar.jar
|-lib\tools.jar
|-logs\...
|-...

MyJar.jar にはMETA-INF/MANIFEST.MF、次の内容のファイルが含まれています。

Manifest-Version: 1.0
Sealed: true
Main-Class: here.comes.my.main.class
Class-Path: tools.jar

Play アプリを起動せずlibに、(フォルダー内で)試していjava -jar MyJar.jarます: したがって、これは問題が Play とは何の関係もないことを私に信じ込ませます。通常、Jar を実行しているときにコンパイラを取得することさえできません!mainToolProvider.getSystemJavaCompiler();null

4

2 に答える 2

1

Web アプリケーションとスタンドアロン アプリケーションに違いはありません。

tools.jar を webapp クラスパスにパッケージ化しないでください。Java のクラスローダーは、通常、ボトムアップでしか機能しません。したがって、jdk の一部である ToolProvider は、webapp クラスパスで tools.jar を認識しません (webapp クラスパスを調べることはできません)。

解決策: JDK を使用し、それを指していることを確認するか、tools.jar を Java ext dir に配置します。プロパティ -Djava.ext.dir を任意のディレクトリに設定することで、ext ディレクトリをオーバーライドできます。

于 2013-04-18T13:18:09.703 に答える