从另一个jar文件访问资源

Dav*_*ave 12 java classpath jsvc

我有一个简单的结构:一个包含一批数据的数据jar文件,以及一个使用该数据运行服务的服务jar文件.为了使数据易于替换,我将它们分开,service.jar的classpath包含data.jar所在的目录.

在service.jar中,我使用getResource来加载数据文件.如果数据文件直接位于文件夹中,但是当它们位于data.jar内时失败,则此方法有效;

这失败了:

all
+ globalclasspath
| + data.jar
|   + mine.properties
+ daemons
  + service.jar

jsvc -cp globalclasspath:daemons/service.jar (...)

MyClass.class.getClassLoader( ).getResource( "mine.properties" ); // <-- null
Run Code Online (Sandbox Code Playgroud)

但这有效:

all
+ globalclasspath
| + mine.properties
+ daemons
  + service.jar

jsvc -cp globalclasspath:daemons/service.jar (...)

MyClass.class.getClassLoader( ).getResource( "mine.properties" ); // <-- not null
Run Code Online (Sandbox Code Playgroud)

我不想更改类路径(除非我可以将它改为通用的,不依赖于数据jar文件的名称),但是我可以更改getResource字符串(我试过/数据) /mine.properties和/data.jar/mine.properties无济于事.我可以进行更改,以便可以从jar中加载资源吗?

cre*_*ama 5

解决方案1

使用类路径通配符.

jsvc -cp globalclasspath/*:daemons/service.jar (...)
Run Code Online (Sandbox Code Playgroud)

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

解决方案2

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

  1. 在目录中找到JAR列表globalclasspath.
  2. URLClassLoader从此JAR列表中创建一个.
  3. URLClassLoader实例中查找所需的资源.

为了在类路径上查找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"));
    }
}
Run Code Online (Sandbox Code Playgroud)

我运行了以下命令:

java -cp globalclasspath:daemons/service.jar MyClass
Run Code Online (Sandbox Code Playgroud)

终端输出:

jar:file:/workspace/all/globalclasspath/data.jar!/mine.properties
Run Code Online (Sandbox Code Playgroud)