运行 jar 时 Java 类加载器不工作

问题描述 投票:0回答:1

我有这个Java代码,用于获取包中的所有类:

public static Set<Class> findAllClassesUsingClassLoader(String packageName) throws Exception {
        InputStream stream = ClassLoader.getSystemClassLoader().getResourceAsStream(packageName.replaceAll("[.]", "/"));
        System.out.println(packageName);
        String text = new String(stream.readAllBytes(), StandardCharsets.UTF_8);
        System.out.println(text);
        BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
        return reader.lines().filter(line -> line.endsWith(".class")).map(line -> {
            try {
                System.out.println("HERE");
                return getClass(line, packageName);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }).collect(Collectors.toSet());
    }

    public static Class getClass(String className, String packageName) throws Exception {
        try {
            return Class.forName(packageName + "." + className.substring(0, className.lastIndexOf('.')));
        } catch (ClassNotFoundException e) {
            throw new Exception("Class " + className + " not found!");
        }
    }

当我从 IDE 运行它时它可以工作,但是当我使用

java -jar
运行我的应用程序时,InputStream 为空。

如何更改我的代码以使其能够通过

java -jar
运行?

java classloader
1个回答
0
投票

我找到了问题的解决方案:

这是代码:

public static Set<Class<?>> getClassesFromResource(String packageName) throws Exception {
    String packageFolder = packageName.replaceAll("[.]", "/");
    Set<Class<?>> classes = new HashSet<Class<?>>();
    URI resource = EntityDAOUtils.class.getClassLoader().getResource(packageFolder).toURI();
    Path myPath = null;

    if ("jar".equals(resource.getScheme())) {
        for (FileSystemProvider provider : FileSystemProvider.installedProviders()) {
            if (provider.getScheme().equalsIgnoreCase("jar")) {
                try {
                    myPath = provider.getFileSystem(resource).getPath(packageFolder);
                } catch (FileSystemNotFoundException e) {
                    // in this case we need to initialize it first:
                    myPath = provider.newFileSystem(resource, Collections.emptyMap()).getPath(packageFolder);
                }
            }
        }
    }

    Stream<Path> walk = Files.walk(myPath, 1);
    for (Iterator<Path> it = walk.iterator(); it.hasNext();) {
        String line = it.next().toString();
        if (line.endsWith(".class")) {
            classes.add(getClass(line.replace('/', '.').replace(".class", ""), packageName));
        }
    }
    walk.close();
    return classes;
}

public static Class getClass(String className, String packageName) throws Exception {
    try {
        return Class.forName(packageName + "." + className.substring(className.lastIndexOf('.') + 1));
    } catch (ClassNotFoundException e) {
        throw new Exception(
                "Class " + packageName + "." + className.substring(className.lastIndexOf('.') + 1) + " not found!");
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.