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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 23:31:06  来源:igfitidea点击:

Access resources from another jar file

javaclasspathjsvc

提问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?"

请参阅“如何在类路径中使用通配符添加多个 jar?

Solution 2

解决方案2

To read data in JARs not on the classpath, use URLClassLoader. The general algorithm is this:

要读取不在类路径上的 JAR 中的数据,请使用URLClassLoader. 一般的算法是这样的:

  1. Find the list of JARs in the globalclasspathdirectory.
  2. Create a URLClassLoaderfrom this list of JARs.
  3. Look up the resource you want from the URLClassLoaderinstance.
  1. 在目录中查找 JAR 列表globalclasspath
  2. URLClassLoader从这个 JAR 列表创建一个。
  3. URLClassLoader实例中查找您想要的资源。

To find JARs on the classpath, I used ResourceListfrom 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 getResourceAsStreamas suggested here:

您是否getResourceAsStream按照此处的建议尝试过:

how-to-a-read-file-from-jar-in-java

如何从 jar-in-java 读取文件