import java.io.*;
import java.net.*;
import java.util.*;
public class TryIt {
public static void main(String[] args) throws Exception {
URL[] urls = {
(new File("a.jar")).getAbsoluteFile().toURI().toURL(),
(new File("b.jar")).getAbsoluteFile().toURI().toURL()
};
URLClassLoader cl = URLClassLoader.newInstance(urls);
String[] res = { "foo", "foo/", "foo/arb", "foo/bar", "foo/cab" };
for (String r: res) {
System.out.println("'" + r + "':");
for (URL u: Collections.list(cl.getResources(r)))
System.out.println(" " + u);
}
}
}
现在准备该程序中提到的JAR文件:
mkdir a/foo b/foo
touch a/foo/arb a/foo/bar b/foo/bar b/foo/cab
echo "Class-Path: b.jar" > mf
jar cfm a.jar mf -C a foo
jar cf b.jar -C b foo
如果你运行java TryIt,你会得到这样的输出:
'foo':
jar:file:…/a.jar!/foo
jar:file:…/b.jar!/foo
'foo/':
jar:file:…/a.jar!/foo/
jar:file:…/b.jar!/foo/
'foo/arb':
jar:file:…/a.jar!/foo/arb
'foo/bar':
jar:file:…/a.jar!/foo/bar
jar:file:…/b.jar!/foo/bar
'foo/cab':
jar:file:…/b.jar!/foo/cab
但是如果你运行jar -i a.jar来创建索引,那么上面的命令就会打印出来:
'foo':
jar:file:…/a.jar!/foo
'foo/':
jar:file:…/a.jar!/foo/
'foo/arb':
jar:file:…/a.jar!/foo/arb
'foo/bar':
jar:file:…/a.jar!/foo/bar
'foo/cab':
jar:file:…/b.jar!/foo/cab
索引本身如下所示:
JarIndex-Version: 1.0
a.jar
foo
b.jar
foo
getResources的合同是否意味着应该返回与给定名称匹配的所有可用资源?
Finds all the resources with the given name.
Normally one package name is mapped to one jar file, but if a particular package spans more than one jar file, then the mapped value of this package will be a list of jar files.
是否有某些规范表明我所观察到的确实是正确的(或至少是允许的)行为?
尽管有索引,是否有一些解决方法可以获得所有命名资源?
最佳答案 这似乎是一个错误.
我已经向Oracle报告了它,它现在在他们的bug数据库中为
bug 8150615.
我在OpenJDK源代码中进行了一些挖掘,并在那里找到了这种行为的共鸣.