& 8我用来做
URLClassLoader urlLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
for (URL u : urlLoader.getURLs()) {
System.out.println("*************** url=" + url);
}
但是在Java 9中,上面给出了错误
java.lang.ClassCastException: java.base/jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to java.base/java.net.URLClass
Loader
那么如何在不知道jar文件的包前缀或文件系统路径的情况下列出所有资源?
答案 0 :(得分:1)
Java9 Release Note说明了这一点:
应用程序类加载器不再是实例
java.net.URLClassLoader
(一个从未实现的实现细节 在以前的版本中指定)。假设的代码ClassLoader.getSytemClassLoader()
会返回URLClassLoader
个对象 需要更新。请注意,Java SE和JDK不提供 用于动态扩充类的应用程序或库的API 在运行时的路径。
要add to this from the mailing list,资源查找方法很少,包括以下方式:
命名模块中的类可以通过Class::getResourceAsStream
方法读取自己的资源,该方法返回InputStream
。它可以通过Class::getResource
方法获取其自己资源之一的URL。这些方法不会在其他命名模块中找到资源。
ClassLoader::getResource*
方法找不到任何资源
命名模块。
Class
和ClassLoader
中的所有现有资源查找方法与今天针对类路径上的资源的工作方式相同。
新的Module::getResourceAsStream
方法可以
用于读取任何命名模块的资源,没有限制。
这些选择可以在Jigsaw的resource encapsulation和readable artifact要求之间取得平衡。
答案 1 :(得分:0)
由于转向模块化架构,不再支持查找类路径的旧方法:
应用程序类加载器不再是实例 URLClassLoader,而不是内部类。这是默认值 用于既不是Java SE也不是JDK的模块中的类的加载器 模块。
https://docs.oracle.com/javase/9/migrate/toc.htm
您可以尝试直接解析classpath属性,或尝试使用ModuleFinder
和朋友对模块执行某些操作。
答案 2 :(得分:0)
我找到的最佳答案是为getResources提供一个参数,当然这意味着你知道资源所在路径的前缀
ArrayList<URL> resources = new ArrayList<URL>();
ClassLoader urlLoader = ClassLoader.getSystemClassLoader();
Enumeration<URL> eU = urlLoader.getResources("com");
while (eU.hasMoreElements()) {
URL u = eU.nextElement();
JarFile jarFile = new JarFile(u.getFile().replace("file:/", "").replaceAll("!.*$", ""));
Enumeration<JarEntry> e = jarFile.entries();
while (e.hasMoreElements()) {
JarEntry jarEntry = e.nextElement();
resources.add(urlLoader.getResource(jarEntry.getName()));
}
}