Jak załadować klasę Java, która nie jest skompilowana?
Najpierw musisz go skompilować. Można to zrobić programowo za pomocą javax.tools
API. Wymaga to tylko zainstalowania JDK na komputerze lokalnym na górze JRE.
Oto prosty przykład kickoff (pozostawiając oczywisty wyjątek obsługi bok):
// 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]".
co daje jak
hello
world
[email protected]
Dalsze stosowanie byłoby łatwiej gdyby te zajęcia implements
pewien interfejs, który jest już w ścieżce klas.
SomeInterface instance = (SomeInterface) cls.newInstance();
W przeciwnym razie trzeba angażować Reflection API dostęp i powoływać się na (brak danych) metody/pola.
Powiedział i niezwiązane z rzeczywistym problemem:
properties.load(new FileInputStream(new File("ClassName.properties")));
Letting java.io.File
polegać na bieżącym katalogu roboczym jest recepta na przenośności kłopoty. Nie rób tego. Umieść ten plik w ścieżce klas i użyj ClassLoader#getResourceAsStream()
ze ścieżką względną clashspath.
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("ClassName.properties"));
Tylko nie na temat. Otrzymuję wartość null, gdy ładuję właściwości na swój sposób, ale otrzymuję właściwości, gdy robię to Foo.class.getResourceAsStream()? Czy możesz pomóc mi zrozumieć twój kod? Dziękuję Ci. – unj2
Ten plik właściwości jest najwyraźniej umieszczony w tym samym pakiecie co klasa 'Foo'. Jak już wspomniano, musisz podać ścieżkę względną classpath, np. 'com/example/filename.properties'. Ale jeśli możesz zagwarantować, że plik właściwości jest zawsze w tym samym pakiecie co klasa 'Foo', to również' Klasa # getResourceAsStream() 'jest również w porządku. Tęsknisz tylko za możliwością przekazania pliku właściwości poza aplikację, aby można było go modyfikować bez modyfikowania/przepakowywania aplikacji. – BalusC
'Files.write (source, sourceFile, StandardCharsets.UTF_8);' nie kompiluje się dla mnie. Myślę, że chcesz 'Files.write (sourceFile.toPath(), source.getBytes());'. –