I have asked this question on how to list all classes in a package in Java. The accepted answer does work but it does not work when it is compiled into a .jar file. Why does it work in eclipse but does not in a jar? How can I make it work in a jar?
Here's the code:
package com.cospox.elecsim.util;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.List;
import java.util.stream.Collectors;
import com.cospox.elecsim.components.Component;
public final class OnLoadManager {
public static void doOnLoad() throws Exception {
for (Class<?> cls : getClasses(Component.class)) {
if (cls != Component.class) {
Method onLoad = cls.getDeclaredMethod("onLoad");
onLoad.setAccessible(true);
onLoad.invoke(null);
}
}
}
private static List<Class<?>> getClasses(Class<?> caller)
throws IOException, URISyntaxException {
return Files.walk(getPackagePath(caller))
.filter(Files::isRegularFile)
.filter(file -> file.toString().endsWith(".class"))
.map(path -> mapPathToClass(path, caller.getPackage().getName()))
.collect(Collectors.toList());
}
private static Class<?> mapPathToClass(Path clsPath, String packageName) {
String className = clsPath.toFile().getName();
className = className.substring(0, className.length() - 6);
return loadClass(packageName + "." + className);
}
private static Path getPackagePath(Class<?> caller)
throws IOException, URISyntaxException {
String packageName = createPackageName(caller);
Enumeration<URL> resources = caller.getClassLoader()
.getResources(packageName);
return Paths.get(resources.nextElement().toURI());
}
private static String createPackageName(Class<?> caller) {
return caller.getPackage().getName().replace(".", "/");
}
private static Class<?> loadClass(String name) {
try {
return Class.forName(name);
} catch (ClassNotFoundException e) {
return null;
}
}
}
I'd really like to stay away from libraries that use Guava, as it's google and I really do not want to have google in my code.
Thanks in advance.
EDIT - this is the full error:
java.nio.file.FileSystemNotFoundException
at com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:171)
at com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:157)
at java.nio.file.Paths.get(Paths.java:143)
at com.cospox.elecsim.util.OnLoadManager.getPackagePath(OnLoadManager.java:48)
at com.cospox.elecsim.util.OnLoadManager.getClasses(OnLoadManager.java:30)
at com.cospox.elecsim.util.OnLoadManager.doOnLoad(OnLoadManager.java:19)
at com.cospox.elecsim.Game.doOnLoad(Game.java:154)
at com.cospox.elecsim.Game.<init>(Game.java:149)
at com.cospox.elecsim.Main.setup(Main.java:26)
at processing.core.PApplet.handleDraw(PApplet.java:2425)
at processing.opengl.PSurfaceJOGL$DrawListener.display(PSurfaceJOGL.java:866)
at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:692)
at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:674)
at jogamp.opengl.GLAutoDrawableBase$2.run(GLAutoDrawableBase.java:443)
at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1293)
at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1147)
at com.jogamp.newt.opengl.GLWindow.display(GLWindow.java:759)
at com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:81)
at com.jogamp.opengl.util.AnimatorBase.display(AnimatorBase.java:452)
at com.jogamp.opengl.util.FPSAnimator$MainTask.run(FPSAnimator.java:178)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
You can find the full code here for any context needed.