Ответ 1
Как загрузить класс Java, который не скомпилирован?
Сначала вам нужно скомпилировать его. Это можно сделать программно с помощью javax.tools
API. Для этого требуется только JDK, установленный на локальной машине поверх JRE.
Здесь приведен пример базового запуска (оставление очевидной обработки исключений):
// Prepare source somehow.
String source = "package test; public class Test { static { System.out.println(\"hello\"); } public Test() { System.out.println(\"world\"); } }";
// Save source in .java file.
File root = new File("/java"); // On Windows running on C:\, this is C:\java.
File sourceFile = new File(root, "test/Test.java");
sourceFile.getParentFile().mkdirs();
Files.write(sourceFile.toPath(), source.getBytes(StandardCharsets.UTF_8));
// Compile source file.
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null, null, null, sourceFile.getPath());
// Load and instantiate compiled class.
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { root.toURI().toURL() });
Class<?> cls = Class.forName("test.Test", true, classLoader); // Should print "hello".
Object instance = cls.newInstance(); // Should print "world".
System.out.println(instance); // Should print "[email protected]".
Что дает, например,
hello
world
[email protected]
Дальнейшее использование было бы более легким, если бы эти классы implements
имели определенный интерфейс, который уже находится в пути к классам.
SomeInterface instance = (SomeInterface) cls.newInstance();
В противном случае вам понадобится API отражения для доступа и вызова (неизвестных) методов/полей.
Это сказало и не связано с реальной проблемой:
properties.load(new FileInputStream(new File("ClassName.properties")));
Предоставление java.io.File
полагаться на текущий рабочий каталог - это рецепт проблемы с переносимостью. Не делай этого. Поместите этот файл в путь к классам и используйте ClassLoader#getResourceAsStream()
с относительным путем classpath.
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("ClassName.properties"));