Java 如何从JAR中的类读取外部文件
文件结构:Java 如何从JAR中的类读取外部文件,java,classloader,Java,Classloader,文件结构: /web-project | |---/WEB-INF/a.jar | |---/META-INF/resources/b.properties 位于A.jar中的A.class想要读取/META-INF/resources/b.properties 我认为a.jar和b.properties都在同一个类加载器下(因为它们在相同的web上下文中) 为了达到我的目的,我尝试了以下方法,但没有成功 InputStream is = null; ClassLoad
/web-project
|
|---/WEB-INF/a.jar
|
|---/META-INF/resources/b.properties
位于A.jar
中的A.class
想要读取/META-INF/resources/b.properties
我认为a.jar和b.properties都在同一个类加载器下(因为它们在相同的web上下文中)
为了达到我的目的,我尝试了以下方法,但没有成功
InputStream is = null;
ClassLoader[] loaders = { Thread.currentThread().getContextClassLoader(),
ClassLoader.getSystemClassLoader(), getClass().getClassLoader() };
ClassLoader currentLoader = null;
for (int i = 0; i < loaders.length; i++) {
if (loaders[i] != null) {
currentLoader = loaders[i];
is = currentLoader.getResourceAsStream("/META-INF/resources/b.properties");
if (is != null) { // is is always null no matter what ways I used.
break;
}
}
}
似乎我应该使用FileInputStream
来获取JAR之外的资源,而不是使用getResourceAsStream()
====已更新2=====
最后,我用下面的解决方案解决了这个问题
context.getResourceAsStream("/META-INF/resources/b.properties");
基于以下前提条件:
a、 jar/b.properties在相同的上下文中
A.class
可以获得ServletContext
对象您可以通过首先验证jar文件的路径来解决此问题。您可以执行以下代码行并检查路径
getClass().getProtectionDomain().getCodeSource().getLocation();
由于资源文件位于jar文件之外,因此需要更改jar文件的路径相对路径
Properties mainProperties = new Properties();
FileInputStream file = new FileInputStream("<relative-path>/META-INF/resources/b.properties");
mainProperties.load(file);
file.close();
似乎我应该使用FileInputStream
来获取JAR之外的资源,而不是使用getResourceAsStream()
根据定义,资源位于JAR文件中。它之外的任何内容都不是资源而是文件,您应该使用FileInputStream
或FileReader
来读取它。你可以用
URL url = getClass().getProtectionDomain().getCodeSource().getLocation();
要获取JAR文件的位置,如果您将该文件分发到同一目录中,您只需对其进行一点路径修改即可获得该文件的路径。请发布一些我们可以运行的内容,或者至少了解一下您的程序的外观。此代码在哪个上下文中运行?Servlet初始化?请求处理?那么,您如何使用来自
jsp
或Servlet
或任何其他类的类A
?JAR文件中是否有资源?如果是这样的话,你发布的代码或任何简化版本都应该能找到它。如果没有,请不要。@Howard Wang您可以试试我发布的内容,如果行得通,请告诉我们。或者将代码更改为A.class.getResourceAsStream(“/META-INF/resources/b.properties”)
,或者删除字符串参数中的初始斜杠(/
)。Class.getResourceAsStream允许初始斜杠;ClassLoader.getResourceAsStream没有。getClass().getProtectionDomain().getCodeSource().getLocation()提供JAR文件的位置。这与JAR文件中资源的正确URI没有任何关系。@EJP看起来我用错了词。我指的是jar文件的位置。@EJP同时,OP请求访问jar文件之外的资源。如果您错过了问题的这一部分,getResourceAsStream()
用于Jar文件内的资源,META-INF
位于具有该路径的Jar文件内,前面没有任何内容,当然不是Jar文件自身的位置。这是不可能的。他自相矛盾。他声称它是外部的,但在这种情况下,为什么它会在META-INF中呢?注意:我很好奇你是如何测试一些不起作用的东西的。@EJP同意。就我而言,它不是META-INF文件夹。我根据他/她显示的文件夹结构创建了一个文件夹,然后进行了测试。
/web-project
|
|---/WEB-INF/a.jar
|
|---/test/resources/b.properties
URL url = getClass().getProtectionDomain().getCodeSource().getLocation();