在我看來,JAR file indexing打破了ClassLoader.getResources()
的機制。考慮下面的程序:JAR索引和getResources
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
合同意味着匹配給定名稱的所有可用的資源應當返還?
查找具有給定名稱的所有資源。
是不是the JAR File Specification允許索引包跨越多個JAR文件?
通常情況下,一個包名稱映射到一個jar文件,但是如果一個特定的包跨越多個jar文件,那麼這個包的映射值將是一個jar文件列表。
是否有一些說明我所觀察到的確實是正確的(或至少是允許的)行爲?
是否有一些解決方法來獲取所有命名的資源,儘管索引?