Я работаю над приложением, которое динамически компилирует и загружает исходные файлы java из указанного каталога с зависимостями jar. Допустим, у нас есть следующая структура каталогов:
project
| lib
| dependency1.jar
| dependency2.jar
| dependency3.jar //used only by dependency1.jar
| src
| mypackage
| ClassA.java //uses dependency1.jar
| ClassB.java //uses dependency2.jar
Я хочу, чтобы оба класса ClassA
и ClassB
были доступны при создании экземпляра среды выполнения и выполнении метода с использованием Java Reflection -> as Class<?>
object.
В настоящее время я запускаю компиляцию со следующими параметрами компилятора, которая всегда заканчивается ошибкой компиляции, говорящей о том, что импортированный пакет не существует. Если ни один из классов в каталоге src не использует внешнюю библиотеку, все работает нормально.
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
List<String> options = new LinkedList<>();
options.add("-d");
options.add("path-to-project-directory/build");
options.add("-cp");
options.add("lib;src");
...
и затем загрузка как:
File compiledDir = new File("path-to-project-directory/build");
ClassLoader cl = new URLClassLoader(new URL[]{ compiledDir.toURI().toURL() });
Class<?> classA = cl.loadClass("mypackage.ClassA");
, который отлично работает с скомпилированными классами.
Я читал, что это что-то вроде инкрементальной компиляции? Есть ли способ обойти это? Я не уверен, что я что-то упустил или это будет не так просто.