简体   繁体   English

从另一个 jar 文件访问资源

[英]Access resources from another jar file

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.我有一个简单的结构:包含一批数据的数据 jar 文件和使用数据运行服务的服务 jar 文件。 To make the data easy to replace, I have them separate, and service.jar's classpath contains the directory which data.jar is in.为了便于替换数据,我把它们分开了,service.jar的类路径包含data.jar所在的目录。

Within service.jar, I use getResource to load the data files.在 service.jar 中,我使用 getResource 加载数据文件。 This works if the data files are directly within the folder, but fails when they are inside data.jar;如果数据文件直接位于文件夹中,则此方法有效,但当它们位于 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).我不想更改类路径(除非我可以将其更改为不依赖于数据 jar 文件名称的通用内容),但我可以更改 getResource 字符串(我试过 /data /mine.properties 和 /data.jar/mine.properties 无济于事)。 Is there a change I can make so that the resources can be loaded from within the jar?我可以进行更改以便可以从 jar 中加载资源吗?

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 . 要读取JAR中不在类路径上的数据,请使用URLClassLoader The general algorithm is this: 一般算法是这样的:

  1. Find the list of JARs in the globalclasspath directory. globalclasspath目录中找到JAR列表。
  2. Create a URLClassLoader from this list of JARs. 从此JAR列表中创建URLClassLoader
  3. Look up the resource you want from the URLClassLoader instance. 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

Have you tried getResourceAsStream as suggested here: 您是否按照此处的建议尝试了getResourceAsStream

how-to-a-read-file-from-jar-in-java 如何对一个读文件,从-JAR-中的Java

You can now use the maven-resources-plugin to share resources between your jars!您现在可以使用maven-resources-plugin在您的 jar 之间共享资源!

In the pom.xml file of the source module/jar, add the following plugin:在source module/jar的pom.xml文件中,添加如下插件:

<artifactId>DATA_MODULE_NAME</artifactId>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
        </plugin>
    </plugins>
</build>

This will tell maven to copy the contents of the resource folder along with the jar.这将告诉 maven 将资源文件夹的内容与 jar 一起复制。

In the module you want to access those resources, add this to the dependencies in the pom:在您要访问这些资源的模块中,将其添加到 pom 中的依赖项中:

<dependencies>
    <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>DATA_MODULE_NAME</artifactId>
        <version>${project.version}</version>
    </dependency>
</dependencies>

When you build your final jar, the resources from the source module will be copied in and available using getResource()当您构建最终的 jar 时,源模块中的资源将被复制并使用getResource()获取

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM