public static List<Class> findClasses(URL resource, String packageName) throws ClassNotFoundException, URISyntaxException, MalformedURLException, IOException {
        List<Class> classes = new ArrayList<>();
        File[] files;
        switch (resource.getProtocol()) {
            case "file":
                files = new File(resource.toURI()).listFiles();
                for (File file : files) {
                    if (file.isDirectory()) {
                        classes.addAll(findClasses(file.toURI().toURL(), packageName + "." + file.getName()));
                    } else if (file.getName().endsWith(".class")) {
                        classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6)));
                    }
                }
                break;
            case "jar":
                String jarPath = resource.getPath().substring(5, resource.getPath().indexOf("!")); //strip out only the JAR file
                JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8"));
                Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
                String name,
                 javaName;
                int classExtIdx;
                while (entries.hasMoreElements()) {
                    name = entries.nextElement().getName();
                    classExtIdx = name.indexOf(".class");
                    if (name.startsWith(packageName) && classExtIdx > 0) { //filter according to the path
                        javaName = name.substring(0, classExtIdx).replace("/", ".");
                        classes.add(Class.forName(javaName));
                    }
                }
                break;
        }
        return classes;
    }