Java 从另一个 jar 文件访问资源
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20150374/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Access resources from another jar file
提问by Dave
I have a simple structure: A data jar file which contains a batch of data, and a service jar file, which runs a service using the data. To make the data easy to replace, I have them separate, and service.jar's classpath contains the directory which data.jar is in.
我有一个简单的结构:一个包含一批数据的数据 jar 文件和一个使用数据运行服务的服务 jar 文件。为了便于替换数据,我将它们分开,service.jar 的类路径包含 data.jar 所在的目录。
Within service.jar, I use getResource to load the data files. This works if the data files are directly within the folder, but fails when they are inside data.jar;
在 service.jar 中,我使用 getResource 加载数据文件。如果数据文件直接位于文件夹中,则此方法有效,但当它们位于 data.jar 中时会失败;
This fails:
这失败了:
all
+ globalclasspath
| + data.jar
| + mine.properties
+ daemons
+ service.jar
jsvc -cp globalclasspath:daemons/service.jar (...)
MyClass.class.getClassLoader( ).getResource( "mine.properties" ); // <-- null
But this works:
但这有效:
all
+ globalclasspath
| + mine.properties
+ daemons
+ service.jar
jsvc -cp globalclasspath:daemons/service.jar (...)
MyClass.class.getClassLoader( ).getResource( "mine.properties" ); // <-- not null
I don't want to change the classpath (unless I can change it to something generic which doesn't depend on the name of the data jar file), but I'm fine with changing the getResource string (I've tried /data/mine.properties and /data.jar/mine.properties to no avail). Is there a change I can make so that the resources can be loaded from within the jar?
我不想更改类路径(除非我可以将其更改为不依赖于数据 jar 文件名称的通用内容),但是我可以更改 getResource 字符串(我已经尝试过 /data /mine.properties 和 /data.jar/mine.properties 无济于事)。我是否可以进行更改以便可以从 jar 中加载资源?
采纳答案by creemama
Solution 1
解决方案1
Use a classpath wildcard.
使用类路径通配符。
jsvc -cp globalclasspath/*:daemons/service.jar (...)
See "How to use a wildcard in the classpath to add multiple jars?"
Solution 2
解决方案2
To read data in JARs not on the classpath, use URLClassLoader
. The general algorithm is this:
要读取不在类路径上的 JAR 中的数据,请使用URLClassLoader
. 一般的算法是这样的:
- Find the list of JARs in the
globalclasspath
directory. - Create a
URLClassLoader
from this list of JARs. - Look up the resource you want from the
URLClassLoader
instance.
- 在目录中查找 JAR 列表
globalclasspath
。 URLClassLoader
从这个 JAR 列表创建一个。- 从
URLClassLoader
实例中查找您想要的资源。
To find JARs on the classpath, I used ResourceList
from the StackOverflow article "Get a list of resources from classpath directory."
为了在类路径上查找 JAR,我使用ResourceList
了 StackOverflow 文章“从类路径目录中获取资源列表”中的内容。
public class MyClass {
/**
* Creates a {@code URLClassLoader} from JAR files found in the
* globalclasspath directory, assuming that globalclasspath is in
* {@code System.getProperty("java.class.path")}.
*/
private static URLClassLoader createURLClassLoader() {
Collection<String> resources = ResourceList.getResources(Pattern.compile(".*\.jar"));
Collection<URL> urls = new ArrayList<URL>();
for (String resource : resources) {
File file = new File(resource);
// Ensure that the JAR exists
// and is in the globalclasspath directory.
if (file.isFile() && "globalclasspath".equals(file.getParentFile().getName())) {
try {
urls.add(file.toURI().toURL());
} catch (MalformedURLException e) {
// This should never happen.
e.printStackTrace();
}
}
}
return new URLClassLoader(urls.toArray(new URL[urls.size()]));
}
public static void main(String[] args) {
URLClassLoader classLoader = createURLClassLoader();
System.out.println(classLoader.getResource("mine.properties"));
}
}
I ran the following command:
我运行了以下命令:
java -cp globalclasspath:daemons/service.jar MyClass
The terminal output:
终端输出:
jar:file:/workspace/all/globalclasspath/data.jar!/mine.properties
回答by John B
Have you tried getResourceAsStream
as suggested here:
您是否getResourceAsStream
按照此处的建议尝试过: