2

次のようなカスタム JavaFileManager があります。

public class InMemoryForwardingFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> {

    private final Map<String, ByteArrayJavaFileObject> javaFileObjects = new HashMap<>();

    @Override
    public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException{

        JavaFileObject fileObject = new ByteArrayJavaFileObject( ... );
        javaFileObjects.put(className, fileObject);

        return fileObject;
    }


    @Override
    public ClassLoader getClassLoader(Location location){

        return new SecureClassLoader(InMemoryForwardingFileManager.class.getClassLoader()){

            @Override
            protected Class<?> findClass(String name) throws ClassNotFoundException {

                ByteArrayJavaFileObject fileObject = javaFileObjects.get(name);

                if(fileObject != null){
                    byte[] bytes = fileObject.getBytes();
                    return defineClass(name, bytes, 0, bytes.length);
                } else{
                    throw new ClassNotFoundException();
                }

            }

        }

    }
}

読みやすくするために、多くのコードを編集しました。このクラスは、list(...) メソッドと inferBinaryName(...) メソッドも実装しています。

私のプロジェクトの別の領域では、次のようなものを実行します。

InMemoryForwardingFileManager fileManager = // get singleton instance

... // declare compilation units, options, diagnostic listener, etc

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
CompilationTask compilerTask = compiler.getTask(null, fileManager, diagnostics, compilationOptions, null, compilationUnits);
compilerTask.call();

// load and instantiate the compiled class
ClassLoader classLoader = fileManager.getClassLoader(null);
MyGeneratedClass instance = (MyGeneratedClass) classLoader.loadClass(fullClassName).newInstance();

windows/mac/linux の eclipse でいくつかの junit テストを実行すると、期待どおりに動作します。Windows 上のグラスフィッシュでプロジェクトを実行すると、期待どおりに動作します。Mac OS X Mavericks または Centos 6.4 の Glassfish で同じプロジェクトを実行すると、getJavaFileForOutput(...) が呼び出されることはありません。私のファイルマネージャーの getClassLoader(...) メソッドは最終的に呼び出されますが、それまでには手遅れです。

getJavaFileForOuput メソッドの呼び出しを妨げている Linux+glassfish 環境の特徴は何ですか?

すべての環境が同じ jdk バージョン (jdk1.7.0_45) を使用するように正しく設定されていると確信しています。

何かアドバイス??

4

1 に答える 1

0

ここで私自身の質問に答えます。

これが頭をよぎったとは信じられませんが、Windows 環境では Glassfish3 が使用されていたのに対し、他の環境では Glassfish4 が使用されていたことがわかりました。これを発見した後、glassfish4 を使用して Windows でプロジェクトをテストしたところ、Mac/Linux で経験したのと同じ問題を再現することができました。

それは漠然とした私の質問への回答ですが、上記のコードが Glassfish4 で期待どおりに機能しない理由が正確にわかった場合は、ここに説明を追加します。

于 2013-11-10T23:27:46.357 に答える