I am building a modular application which contains template classes in its core module (executed by the user) and loads implementations for these classes from .jar
files in a certain directory on every startup.
The loading process of these implementations looks like this:
Collection<Class<?>> output = Lists.newArrayList();
JarFile jarFile = new JarFile(path);
Enumeration<JarEntry> jarEntries = jarFile.entries();
URL[] urls = { new URL("jar:file:" + path + "!/") };
URLClassLoader classLoader = URLClassLoader.newInstance(urls);
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
if(jarEntry == null
|| jarEntry.isDirectory()
|| !jarEntry.getName().endsWith(".class")){
continue;
}
...
int ignoreClass = ".class".length();
String className = jarEntry.getName().substring(0,jarEntry.getName().length()-ignoreClass);
className = className.replace('/', '.');
Class implementationClass = classLoader.loadClass(className);
Class<?> outputClass = this.loadToClassPath(path, implementationClass);
output.add(outputClass);
continue;
}
private Class<?> loadToClassPath(String path, Class toLoad) throws NoSuchMethodException,
MalformedURLException,
InvocationTargetException,
IllegalAccessException,
ClassNotFoundException {
URLClassLoader loader = (URLClassLoader) KelpApplicationRepository.class.getClassLoader();
Method addURL = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
addURL.setAccessible(true);
addURL.invoke(loader, new File(path).toURI().toURL());
return loader.loadClass(toLoad.getName());
}
It compiles, but I get the following runtime error:
[17:51:24 ERROR]: de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate initializing Kelp v0.1-SNAPSHOT (Is it up to date?)
java.lang.NoClassDefFoundError: de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate
at java.lang.ClassLoader.defineClass1(Native Method) ~[?:1.8.0_171]
at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[?:1.8.0_171]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[?:1.8.0_171]
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) ~[?:1.8.0_171]
at java.net.URLClassLoader.access$100(URLClassLoader.java:73) ~[?:1.8.0_171]
at java.net.URLClassLoader$1.run(URLClassLoader.java:368) ~[?:1.8.0_171]
at java.net.URLClassLoader$1.run(URLClassLoader.java:362) ~[?:1.8.0_171]
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_171]
at java.net.URLClassLoader.findClass(URLClassLoader.java:361) ~[?:1.8.0_171]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_171]
at java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:814) ~[?:1.8.0_171]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_171]
at de.pxav.kelp.core.application.inject.VersionBinderModule.implementationsOf(VersionBinderModule.java:214) ~[?:?]
at de.pxav.kelp.core.application.inject.VersionBinderModule.lambda$configure$1(VersionBinderModule.java:75) ~[?:?]
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184) ~[?:1.8.0_171]
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) ~[?:1.8.0_171]
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) ~[?:1.8.0_171]
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[?:1.8.0_171]
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[?:1.8.0_171]
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) ~[?:1.8.0_171]
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) ~[?:1.8.0_171]
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:1.8.0_171]
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418) ~[?:1.8.0_171]
at de.pxav.kelp.core.application.inject.VersionBinderModule.configure(VersionBinderModule.java:73) ~[?:?]
at com.google.inject.AbstractModule.configure(AbstractModule.java:62) ~[?:?]
at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:340) ~[?:?]
at com.google.inject.spi.Elements.getElements(Elements.java:110) ~[?:?]
at com.google.inject.internal.InjectorShell$Builder.build(InjectorShell.java:138) ~[?:?]
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:104) ~[?:?]
at com.google.inject.Guice.createInjector(Guice.java:96) ~[?:?]
at com.google.inject.Guice.createInjector(Guice.java:73) ~[?:?]
at com.google.inject.Guice.createInjector(Guice.java:62) ~[?:?]
at de.pxav.kelp.core.KelpPlugin.onLoad(KelpPlugin.java:41) ~[?:?]
at org.bukkit.craftbukkit.v1_8_R3.CraftServer.loadPlugins(CraftServer.java:297) [spigot.jar:git-Spigot-db6de12-18fbb24]
at org.bukkit.craftbukkit.v1_8_R3.CraftServer.reload(CraftServer.java:739) [spigot.jar:git-Spigot-db6de12-18fbb24]
at org.bukkit.Bukkit.reload(Bukkit.java:535) [spigot.jar:git-Spigot-db6de12-18fbb24]
at org.bukkit.command.defaults.ReloadCommand.execute(ReloadCommand.java:25) [spigot.jar:git-Spigot-db6de12-18fbb24]
at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) [spigot.jar:git-Spigot-db6de12-18fbb24]
at org.bukkit.craftbukkit.v1_8_R3.CraftServer.dispatchCommand(CraftServer.java:641) [spigot.jar:git-Spigot-db6de12-18fbb24]
at org.bukkit.craftbukkit.v1_8_R3.CraftServer.dispatchServerCommand(CraftServer.java:627) [spigot.jar:git-Spigot-db6de12-18fbb24]
at net.minecraft.server.v1_8_R3.DedicatedServer.aO(DedicatedServer.java:412) [spigot.jar:git-Spigot-db6de12-18fbb24]
at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:375) [spigot.jar:git-Spigot-db6de12-18fbb24]
at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:654) [spigot.jar:git-Spigot-db6de12-18fbb24]
at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:557) [spigot.jar:git-Spigot-db6de12-18fbb24]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_171]
Caused by: java.lang.ClassNotFoundException: de.pxav.kelp.core.sidebar.version.SidebarVersionTemplate
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[?:1.8.0_171]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_171]
at java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:814) ~[?:1.8.0_171]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_171]
... 45 more
I am wondering why, because the .class
file of SidebarVersionTemplate
exists in the core module. Maybe it has to do with the extends
keyword in the implementation class? Does this keyword load classes by default in Java?
implementation class:
public class SidebarVersion extends SidebarVersionTemplate {
template class:
public abstract class SidebarVersionTemplate {
Any ideas? Thanks in advance
Aucun commentaire:
Enregistrer un commentaire