6

こんにちは私はJavaクラスの実行時に作成、コンパイル、ロードする必要があります。FTLを使用して、Javaソースファイルを作成しています。動的な依存関係がない場合は、ソースをコンパイルできます。

インスタンスを詳しく説明するために、2つのJavaソースファイル、1つのインターフェイスとその実装クラスがあります。次のようにJavaコンパイラAPIを使用してインターフェイスをコンパイルできます

String classpath=System.getProperty("java.class.path");
        String testpath =classpath+";"+rootPath+"/lib/is_wls_client.jar;"+rootPath+"/rtds_wls_proxyclient.jar;.;";
        File javaFile =  new File(javaFileName+".java");
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        List<String> optionList = new ArrayList<String>();
        optionList.addAll(Arrays.asList("-classpath",testpath));
        StandardJavaFileManager sjfm = compiler.getStandardFileManager(null, null, null);
        Iterable fileObjects = sjfm.getJavaFileObjects(javaFile);
        JavaCompiler.CompilationTask task = compiler.getTask(null, null, null,optionList,null,fileObjects);
        task.call();
        sjfm.close();

すでにクラスパスにある静的クラスのクラスパスを設定しましたが、このアプローチは動的に作成されたクラスでは機能しませんか?カスタムクラスローダーで修正できますか?私の最終的な実装はウェブ/アプリサーバーになります

フィードバックは大歓迎です

Satheesh

4

1 に答える 1

6

すべてのJavaファイルを一緒にコンパイルすることでこの問題を解決することができました。FTLを使用して、Javaクラスを生成し、JavaコンパイラAPIを使用してコンパイルし、カスタムクラスローダーを使用してクラスをロードします。

Javaコンパイラ

private  void compile(File[] files) throws IOException{
        String classpath=System.getProperty("java.class.path");
        String rootPath=getServletContext().getRealPath("/");
        System.out.println("--> root Path "+rootPath);
        String testpath=classpath+";.;xx.jar;yy.jar";
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        List<String> optionList = new ArrayList<String>();
        optionList.addAll(Arrays.asList("-classpath",testpath));
//      optionList.addAll(Arrays.asList("-d",rootPath+"/target"));
        StandardJavaFileManager sjfm = compiler.getStandardFileManager(null, null, null);
        Iterable fileObjects = sjfm.getJavaFileObjects(files);
        JavaCompiler.CompilationTask task = compiler.getTask(null, null, null,optionList,null,fileObjects);
        task.call();
        sjfm.close();

    }

以下のコードスニペットは、カスタムクラスローダーの使用方法を示しています

class CustomClassLoader extends ClassLoader {

     public CustomClassLoader(ClassLoader parent) {
            super(parent);
     }

    public Class findClass(String className,String path) {
        byte[] classData = null;
        try {
            FileInputStream f = new FileInputStream(path);
            int num = f.available();
            classData = new byte[num];

            f.read(classData);
        } catch (IOException e) {
            System.out.println(e);
        }
        Class x = defineClass(className, classData, 0, classData.length);
        return x;
    }
}

ありがとうSatheesh

于 2012-02-29T09:47:22.137 に答える