我从其他正在运行的jar中加载资源时遇到麻烦。这是我的设置
resource.jar # contains resources I want to load
`-res/hwview/file1
engine.jar # my application which need resources
`-res/hwview/file2
有趣的是,使用下面的代码,我可以加载file2
(在我运行的jar中),但不能加载file1
。
String dir = "res/hwview";
Enumeration<URL> e = getClass().getClassLoader().getResources(dir);
while(e.hasMoreElements()) {
// prints only file1 from engine.jar
// (actually it's in classes directory because I run it from my IDE)
System.out.println(e.nextElement());
}
[OUTPUT]
/path/to/my/project/SiHwViewUiModel/classes/res/hwview
所以我想也许这个罐子没有被ClassLoader拾取所以我打印了加载的内容
ClassLoader cl = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader)cl).getURLs();
for(URL url: urls){
System.out.println(url.getFile());
}
[OUTPUT]
/path/to/my/project/SiHwViewUiModel/classes/
/path/to/my/project/Resources/deploy/resources.jar
... and other not so important jars
有什么想法吗? 谢谢你的帮助!
答案 0 :(得分:3)
我找到了解决方案。 getResources()
方法和类似方法的问题在于,不能给出目录,只能给出特定文件。这意味着如果我想在整个类路径中搜索特定结构,我需要在基目录中创建 marker 文件。
示例:我想访问my/path
目录 - &gt;创建marker.info
(名称无关紧要)文件,然后搜索它。
resources.jar
`- my/path/
|- my/directories
`- marker.info
resources2.jar
`- my/path/
|- my/other/directories
`- marker.info
# search
Enumeration<URL> urls = getClass().getClassLoader().getResources("my/path/marker.info");
# print
print(urls);
/path/to/resources.jar!/my/path/marker.info
/path/to/resources2.jar!/my/path/marker.info
答案 1 :(得分:1)
如果JAR文件在类路径上,则不需要做任何特殊操作。资源将被找到。
如果他们不在类路径上,则需要创建URLClassLoader
并使用其getResource()
方法。
答案 2 :(得分:0)
在Spring中,它可以从类路径中的所有jar文件加载xml文件:
ApplicationContext context = new ClassPathXmlApplicationContext(
"classpath*:**/applicationContext*.xml");
您可以查看Spring源代码,看看Spring是如何实现的。
答案 3 :(得分:-2)
public final class JarResource
{
private String jarFileName;
private Map<String, Long> hashSizes = new HashMap<String, Long>();
private Map<String, Object> hashJarContents = new HashMap<String, Object>();
public JarResource(String jarFileName) throws Exception
{
this.jarFileName = jarFileName;
ZipFile zipFile = new ZipFile(this.jarFileName);
Enumeration<ZipEntry> e = (Enumeration<ZipEntry>) zipFile.entries();
while (e.hasMoreElements())
{
ZipEntry zipEntry = e.nextElement();
if(!zipEntry.isDirectory())
{
hashSizes.put(getSimpleName(zipEntry.getName()), zipEntry.getSize());
}
}
zipFile.close();
// extract resources and put them into the hashMap.
FileInputStream fis = new FileInputStream(jarFileName);
BufferedInputStream bis = new BufferedInputStream(fis);
ZipInputStream zis = new ZipInputStream(bis);
ZipEntry ze = null;
while ((ze = zis.getNextEntry()) != null)
{
if (ze.isDirectory())
{
continue;
}
else
{
long size = (int) ze.getSize();
// -1 means unknown size.
if (size == -1)
{
size = hashSizes.get(ze.getName());
}
byte[] b = new byte[(int) size];
int rb = 0;
int chunk = 0;
while (((int) size - rb) > 0)
{
chunk = zis.read(b, rb, (int) size - rb);
if (chunk == -1)
{
break;
}
rb += chunk;
}
hashJarContents.put(ze.getName(), b);
}
}
zis.close();
}
public byte[] getResource(String name)
{
return (byte[]) hashJarContents.get(name);
}
private String getSimpleName(String entryName)
{
// Remove ".jar" extension
int index = entryName.indexOf("/");
String fileNameWithoutExt = entryName.substring(index, entryName.length());
return fileNameWithoutExt;
}
}
然后使用此类加载资源:
public static void main(String[] args) throws Exception
{
JarResource jr = new JarResource("/home/mjiang/Downloads/solr-4.8.0/dist/solr-cell-4.8.0-test.jar");
byte[] resource = jr.getResource("/META-INF/NOTICE.txt");
InputStream input = new ByteInputStream(resource, resource.length);
BufferedReader dis = new BufferedReader(new InputStreamReader(input));
String line = "";
while((line = dis.readLine()) != null)
{
System.out.println(line);
}
dis.close();
}