0

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.

Jachdich
  • 782
  • 8
  • 23

0 Answers0