Использование Java Compiler API для компиляции нескольких файлов Java - PullRequest
5 голосов
/ 02 февраля 2012

Привет! У меня есть требование создавать, компилировать и загружать Java-классы во время выполнения.Используя FTL, я создаю исходные файлы Java и могу скомпилировать исходный код, если динамическая зависимость отсутствует.

Для разработки с экземпляром у меня есть два исходных файла Java, один интерфейс и его класс реализации.Я могу скомпилировать интерфейс, используя 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

1 Ответ

6 голосов
/ 29 февраля 2012

Мне удалось решить эту проблему, скомпилировав все файлы Java вместе. Используя FTL, я генерирую классы Java, а затем компилирую их с помощью API Java-компилятора и загружаю классы с помощью загрузчика пользовательских классов

Java Complier

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

...