Comment charger une classe Java qui n'est pas compilée?
Vous devez d'abord le compiler. Cela peut être fait par programme avec le javax.tools
API. Cela nécessite uniquement l'installation de JDK sur la machine locale au-dessus de JRE.
Voici un exemple de coup d'envoi de base (en laissant exception évidente manipulation de côté):
// 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]".
Ce qui donne comme
hello
world
[email protected]
Toute autre utilisation serait plus facile si ces classes implements
une certaine interface qui est déjà dans le classpath.
SomeInterface instance = (SomeInterface) cls.newInstance();
Sinon, vous devez impliquer le Reflection API pour accéder et appeler les méthodes (inconnues)/champs.
Cela dit et sans rapport avec le problème réel:
properties.load(new FileInputStream(new File("ClassName.properties")));
Laisser java.io.File
comptent sur le répertoire de travail actuel est la recette pour des problèmes de portabilité. Ne fais pas ça. Placez ce fichier dans classpath et utilisez ClassLoader#getResourceAsStream()
avec un chemin relatif au chemin d'accès aux classes.
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("ClassName.properties"));
Juste une question hors sujet. J'obtiens un null quand je charge les propriétés à votre guise mais j'obtiens les propriétés quand je le fais Foo.class.getResourceAsStream()? Pourriez-vous m'aider à comprendre votre code? Je vous remercie. – unj2
Ce fichier de propriétés est apparemment placé dans le même paquet que la classe 'Foo'. Comme indiqué, vous devez spécifier un chemin relatif au chemin de classe, par ex. 'com/example/nomdefichier.properties'. Mais si vous pouvez garantir que le fichier de propriétés est toujours dans le même paquet que la classe 'Foo', alors' Class # getResourceAsStream() 'est également correct. Vous ne manquerez que la possibilité d'externaliser le fichier de propriétés en dehors de l'application afin qu'il puisse être modifié sans modifier/reconditionner l'application. – BalusC
'Files.write (source, sourceFile, StandardCharsets.UTF_8);' ne compile pas pour moi. Je pense que vous voulez 'Files.write (sourceFile.toPath(), source.getBytes());'. –