6

私の使用例は、JDK 6 で提供される ToolProvider および JavaCompiler クラスを使用して、Java プログラムから生成されたソース ファイルをコンパイルすることです。ソース ファイルには、コンテキスト クラスローダー (J2EE コンテナーで実行される) 内のクラスへの参照が含まれていますが、システム クラスローダー内には含まれていません。私の理解では、デフォルトでは、ToolProvider はシステム クラスローダーを使用して JavaCompiler インスタンスを作成します。

JavaCompiler が使用するクラスローダーを指定する方法はありますか?

IBM DeveloperWorks の何かを変更して、このアプローチを試しました。

FileManagerImpl fm = 
    new FileManagerImpl(compiler.getStandardFileManager(null, null, null););

FileManagerImpl は次のように定義されています。

static final class FileManagerImpl 
    extends ForwardingJavaFileManager<JavaFileManager> {

   public FileManagerImpl(JavaFileManager fileManager) {
      super(fileManager);
   }

   @Override
   public ClassLoader getClassLoader(JavaFileManager.Location location) {
      new Exception().printStackTrace();
      return Thread.currentThread().getContextClassLoader();
   }

}

スタックトレースは、アノテーション処理中に一度だけ呼び出されたことを示しています。コンパイルするソース ファイルで参照されているクラスがシステム クラスパス上になく、コンテキスト クラスローダーから使用できることを確認しました。

4

3 に答える 3

8

contextclassloader に認識されているファイルへのクラスパスがわかっている場合は、それらをコンパイラに渡すことができます。

    StandardJavaFileManager fileManager = compiler.getStandardFileManager(this /* diagnosticlistener */, null, null);
// get compilationunits from somewhere, for instance via fileManager.getJavaFileObjectsFromFiles(List<file> files)
List<String> options = new ArrayList<String>();
options.add("-classpath");
StringBuilder sb = new StringBuilder();
URLClassLoader urlClassLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
for (URL url : urlClassLoader.getURLs())
    sb.append(url.getFile()).append(File.pathSeparator);
options.add(sb.toString());
CompilationTask task = compiler.getTask(null, fileManager, this /* diagnosticlistener */, options, null, compilationUnits);
task.call();

この例では、(クラスパスを取得できる) URLClassloader を使用していることを前提としていますが、必要に応じて独自のクラスパスを挿入することもできます。

于 2009-03-20T12:15:21.927 に答える
1

もう 1 つのオプションは、Commons JCIを使用することです。

于 2008-12-02T22:33:47.510 に答える
0

ここでは、2つの別々の質問をしています。

1つは、システムクラスパスにないクラスをコンパイルする方法です。これは、「-classpath」コマンドライン引数をコンパイラに渡すことで簡単に解決できます(Leihcaが最初に述べたように)。

2つ目は、スレッドコンテキストクラスローダーでToolProviderとJavaCompilerをインスタンス化する方法です。この記事の執筆時点では、これは未解決の質問です。カスタムクラスローダーからjavax.tools.ToolProviderを使用していますか?

于 2010-02-23T14:03:02.063 に答える