¿Cómo cargo una clase de Java que no está compilada?
Es necesario compilarlo primero. Esto puede hacerse programáticamente con el javax.tools
API. Esto solo requiere que el JDK se instale en la máquina local en la parte superior de JRE.
Aquí hay un ejemplo básico patada de salida (dejando el manejo de un lado excepción obvia):
// 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]".
que da como
hello
world
[email protected]
El uso adicional sería más fácil si esas clases implements
un determinado interfaz que ya está en el classpath.
SomeInterface instance = (SomeInterface) cls.newInstance();
De lo contrario, la necesidad de involucrar a Reflection API acceder a e invocar los métodos (desconocido)/campos.
Dicho esto y sin relación con el problema real:
properties.load(new FileInputStream(new File("ClassName.properties")));
Dejar java.io.File
se basan en el directorio de trabajo actual es la receta para la portabilidad problemas. No hagas eso. Coloque ese archivo en classpath y use ClassLoader#getResourceAsStream()
con una ruta de acceso relativa a la clase.
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("ClassName.properties"));
Sólo una pregunta fuera de tema. Obtengo un valor nulo cuando cargo las propiedades a su manera pero obtengo las propiedades cuando lo hago Foo.class.getResourceAsStream()? ¿Podrías ayudarme a entender tu código? Gracias. – unj2
Ese archivo de propiedades aparentemente se coloca en el mismo paquete que la clase 'Foo'. Como se dijo, debe especificar una ruta relativa a la ruta de clase, p. 'com/example/filename.properties'. Pero si puede garantizar que el archivo de propiedades esté siempre en el mismo paquete que la clase 'Foo', entonces' Class # getResourceAsStream() 'también está bien. Solo perderá la capacidad de externalizar el archivo de propiedades fuera de la aplicación para que pueda modificarse sin modificar/reempaquetar la aplicación. – BalusC
'Files.write (source, sourceFile, StandardCharsets.UTF_8);' no compila para mí. Creo que quieres 'Files.write (sourceFile.toPath(), source.getBytes());'. –