java - 如何使用反射从外部 JAR 文件检索一些资源

标签 java reflection classloader

好吧,我知道这里已经发布了类似的问题,事实上,我的解决方案就是从它们那里得到的。

我的想法是拥有一些可由用户添加到应用程序中的模块(模块是 JAR 文件内文件夹中的一组 XML 文件)。这意味着用户可以将一些 jar 放在预定义的文件夹中,并且该 JAR 中的所有资源都必须可供应用程序使用。为此,我需要从外部文件夹加载所有 JAR,并将 XML 作为资源检索。 JAR文件通常没有任何class文件,但也许将来可以有。

该应用程序还有一个“默认”模块,该模块已位于其资源文件夹内。该模块工作正常,我可以使用 Reflections 列出其中的所有 XML。

我使用反射检索所有 XML 文件的代码非常简单:

    final Set<String> resources = new Reflections(CustomPath.MODULES_FOLDER, new ResourcesScanner()).getResources(Pattern
            .compile(".*\\.xml"));

返回一组类似于modules_folder/module_name/file1.xml的字符串。

加载 Jar 文件的代码使用 URLClassLoader :

Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class });
        method.setAccessible(true); // promote the method to public access.
        method.invoke(loader, new Object[] { url });

据我了解,资源可从 URLClassLoader 获取。事实上,我可以做这样的事情:

URLClassLoader.getSystemResource("modules_folder/module_name/file1.xml").

文件已加载,如果我输入无效路径,则会引发错误。我还需要知道未预定义的“module_name”。那么就不是解决办法了。

如果我再次运行使用反射检索资源的方法,它只会检索项目资源文件夹内的文件。未从 JAR 中检索任何资源。

然后,我不明白为什么反射无法从 JAR 文件中获取文件(如果已经加载)。我不确定 Reflections 是否因任何原因无法访问 URLCLassLoader,或者必须以不同的方式使用。

问题是...为什么 Reflections 无法访问运行时加载的 JAR 中的资源?如果这是一个限制,那么在外部 JAR 文件中没有任何 Java 类的最佳方法是什么?

最佳答案

好的,那就把最终的结果作为以后的引用。我的问题是 new Reflections(CustomPath.MODULES_FOLDER, new ResourcesScanner()) 的默认构造函数未访问 URLClassLoader。那么它就不可能获得我要找的资源了。解决方案是使用 ConfigurationBuilder 并包含我需要的所有类加载器。

final ConfigurationBuilder builder = new ConfigurationBuilder();
builder.addUrls(ClasspathHelper.forPackage(PathManager.MODULES_FOLDER, ClassLoader.getSystemClassLoader(),
            ClasspathHelper.contextClassLoader(), ClasspathHelper.staticClassLoader()));
builder.addScanners(new ResourcesScanner());
final Reflections reflections = new Reflections(builder);
final Set<String> resources = reflections.getResources(Pattern.compile(".*\\.xml"));

从前面的代码中可以看出,我将 ClassLoader.getSystemClassLoader() 添加到构建器中,并且该加载器是我用于加载 Jar 文件的加载器。

关于java - 如何使用反射从外部 JAR 文件检索一些资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57612780/

相关文章:

java - 反射中获取方法参数的类型

java - Java中控制类加载顺序

java - Tomcat:Tomcat内部是如何卸载类的?

java - 在一个类中设置一个值并从另一个类中检索 Java(Android 应用程序)

java - Timer.schedule() 执行后留下一个打开的线程

java - 从 java 到 zul zk 的动态单选按钮

java - App Engine 上的 getObjectById

java - 在 Java 中可以访问方法 "reflectively"的源代码吗?

java - 我可以在不将类名硬编码为字符串文字的情况下将类名作为编译时常量获取吗?

java - 被测类名与androidTest相同时发现重复类