En Java, me carga la clase externa (en el archivo .jar) de esta manera:Scala - objeto dinámico/clase de carga
ClassLoader classLoader = new URLClassLoader(new URL[] {
new File("module.jar").toURI().toURL()});
Class clazz = classLoader.loadClass("my.class.name");
Object instance = clazz.newInstance();
//check and cast to an interface, then use it
if (instance instanceof MyInterface)
...
y funciona bien.
====================
Ahora quieren hacer lo mismo en Scala. Tengo un trait
llamado Module
(Module.scala
):
trait Module {
def name: String
}
object Module {
lazy val ModuleClassName = "my.module.ExModule"
}
que escribir un módulo que se extiende Module
, a continuación, compilar a module.jar
:
package my.module
import Module
object ExModule extends Module {}
Entonces lo cargo por este código:
var classLoader = new URLClassLoader(Array[URL](
new File("module.jar").toURI.toURL))
var clazz = classLoader.loadClass(Module.ModuleClassName)
Funciona bien. Pero si creo nueva instancia, consigo esta excepción:
java.lang.InstantiationException: my.module.ExModule
Si lo prueba:
-> siempre vuelven false
.
¿Podría ayudarme con este problema?
Editado
supongo que se debe a que es un ExModule
object
(no class
). Pero cuando lo cambio a class
, y classLoader.loadClass(...)
levanta un java.lang.NoClassDefFoundError
. Supongo que es porque ExModule
se extiende desde un trait
.
Estoy confundido. ¿Podría alguien ayudarme por favor?
Editado
clazz.isInstanceOf[Class[Module]]//or Class[Byte], or Class[_]...
vuelve true
.
Creo que estabas más cerca de convertirlo en una clase (cuando recibías la ClassNotFoundException). ¿Estás seguro de que cuando hiciste referencia a module.jar estás obteniendo el camino correcto? El hecho de que se extienda desde un rasgo no debe hacer ninguna diferencia: ExModule es una clase (en ese caso). –
Sí, estoy seguro de que la ruta a 'module.jar' es correcta. El método 'classLoader.loadClass (...)' funciona bien (en caso de que 'ExModule' sea' object'). –
¿Puedes mirar el bytecode compilado (vía javap o similar)? Scalac tiene la extraña costumbre de agregar $ sy otros nombres extraños en todo el lugar, y tal vez su ExModule solo tiene un nombre un poco más en la versión compilada. Además, puede pedirle a Scalac que imprima el código java igual a su scala (simplemente no recuerdo la opción ahora). – Rogach