Volledige versie bekijken : Externe class files inladen in Java



ultddave
12 October 2011, 20:43
Hey,

Ik heb een vraag ivm het inladen van .class files @runtime via de java classloader.

Situatie:
Ik heb een map genaamd "plugins". In die map bevind zich een bestand "MyNewAlgorithm2.class". Die class heeft als binary name "implementation.MyNewAlgorithm2".

Maar de file zit dus NIET in een map genaamd "implementation" (maar zat daar wel in tijdens development, vandaar die binary name). Hij zit nu dus gewoon rechtstreeks onder de map "plugins".

En ik wil deze klasse inladen @runtime om die te gebruiken.

Dit is mijn code:


ClassFileScanner c = new ClassFileScanner();
c.getReferencedClasses("plugins/MyNewAlgorithm2.class");
System.out.println(c.getName());
try
{
URLClassLoader loader = URLClassLoader.newInstance(new URL[] { new File("plugins").toURI().toURL() });
Class<?> cls = loader.loadClass(c.getName());
System.out.println("Succes");
}
catch(Exception e) {System.out.println(e.toString());}

(Ter informatie; de ClassFileScanner gaat de binary name van de .class file uitlezen. Dus ik kan de volledige (binary) name van de .class file achterhalen, zonder problemen. Het is het inladen dat niet lukt.

Output:


implementation.MyNewAlgorithm2
java.lang.ClassNotFoundException: implementation.MyNewAlgorithm2


Dus ik kan de class niet inladen omdat hij niet in een map "implementation" zit.

Als ik echter deze code gebruik:

Class<?> cls = loader.loadClass("MyNewAlgorithm2");
(hardcoded omdat het een voorbeeld is).

Krijg ik deze output:


implementation.MyNewAlgorithm2
Exception in thread "main" java.lang.NoClassDefFoundError: MyNewAlgorithm2 (wrong name: implementation/MyNewAlgorithm2)


Dus een NoClassDefFoundError...

Iemand een oplossing? ;)

Ik wil dus weten of het mogelijk is om een class file in te laden als ik zijn binary name weet en als hij in een willekeurige map(pen) zit die niet noodzakelijk overeenkom(t)(en) met deze binary name. ;)

Mvg,
Dave

ultddave
13 October 2011, 15:49
Voorlopig oplossing:
.class file inlezen in een byte array en dan de ClassLoader::defineClass method gebruiken voor de klasse te kunnen gebruiken. Werkt zonder problemen, al weet'k niet of deze oplossing echt "goed" is qua manier van programmeren.

Mvg,
Dave