Динамическая компиляция класса java

269
01 марта 2017, 19:42

При компиляции Diagnostic выдает package org.apache.log4j does not exist

Имею вот такой метод, который в рантайме должен компилировать исходник java.

public static void compile(final File file, final JavaFileObject... objects) {
    System.setProperty("java.home", "c:\\Program Files\\Java\\jdk1.7.0_45");
    final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    final DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
    final StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, Locale.getDefault(), Charset.defaultCharset());
    final Iterable<? extends JavaFileObject> compilationUnits = new ArrayList<JavaFileObject>(Arrays.asList(objects));
    String[] compileOptions = new String[] { "-d", file.getAbsolutePath() };
    final Iterable compilationOptions = Arrays.asList(compileOptions);
    final JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, compilationOptions, null,
            new ArrayList(Arrays.asList(objects)));
    final boolean result = task.call();
    if (result) {
        System.out.println("Compilation was successful");
    } else {
        System.out.println("Compilation failed");
        for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
            System.err.format("Error on line %d in %s", diagnostic.getLineNumber(), diagnostic);
        }
    }
    try {
        fileManager.close();
    } catch (final IOException e) {
        e.printStackTrace();
    }
}

В File путь D:\project\src\main\resources В JavaFileObject приходит например вот такой исходник:

import java.lang.Override;
import java.lang.String;
import org.apache.log4j.Logger;
public class Audi implements Car {
private String engine;
private final Logger LOGGER = Logger.getLogger(this.getClass());
@Override
public void start() {
LOGGER.info("The engine starts");
setEngine("start");
}
@Override
public void stop() {
LOGGER.info("The engine stops");
setEngine("stop");
}
public String getEngine() {
return this.engine;
}
public void setEngine(final String engine) {
this.engine = engine;
}
}

Если убрать Logger, то все компилиться нормально. Как с этим бороться подскажите пожалуйста?

С наилучшими пожеланиями!

Answer 1

Я немного исправил ваш код и у меня компилируется и выполняется без ошибок. Я проверил в командной строке.

public static void compile(final File file) {
    final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    final DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
    final StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
    List<String> optionList = new ArrayList<>();
    optionList.add("-classpath");
    optionList.add(System.getProperty("java.class.path") + System.getProperty("path.separator") + "/log4j-1.2.17.jar");
    Iterable<? extends JavaFileObject> compilationUnit
            = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(file));
    JavaCompiler.CompilationTask task = compiler.getTask(
            null,
            fileManager,
            diagnostics,
            optionList,
            null,
            compilationUnit);
    final boolean result = task.call();
    if (result) {
        System.out.println("Compilation was successful");
    } else {
        System.out.println("Compilation failed");
        for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
            System.err.format("Error on line %d in %s", diagnostic.getLineNumber(), diagnostic);
        }
    }
    try {
        fileManager.close();
    } catch (final IOException e) {
        e.printStackTrace();
    }
}
READ ALSO
Вычисление Load Average для Windows

Вычисление Load Average для Windows

Как можно вычислить Load Average системы с ОС Windows? (Язык программирования - java)Sigar API и OperatingSystemMXBean не вычисляют Load Average под Windows

331
Как узнать разницу между датами с минимальный интревалом в один день?

Как узнать разницу между датами с минимальный интревалом в один день?

Есть БД Realm, которая хранит объекты с записями о действиях пользователяСтруктура объекта с записью такая: timestamp с датой и коллекция действий...

215
не понимаю fileiutputstream.write

не понимаю fileiutputstream.write

Мне нужно скопировать в один файл половину всех байтов, во второй файл вторую половину(или большую часть если количество байт не равное)

221
Почему возникает java.lang.NoClassDefFoundError?

Почему возникает java.lang.NoClassDefFoundError?

При использовании данного кода:

328