Reputation: 837
My problem is the following: I am trying to access a class file in a Jar. I have a jar "dumb.jar" located in package "com.msgxsd". The jar is on the classpath, and If I try and do
InputStream is = this.getClass().getClassLoader()
.getResourceAsStream("com/msgxsd/dumb.jar");
then I get an input stream for the jar without a problem.
The problem arises when I try and get an input stream (or a URL) for the file inside the jar. All the jar contains (apart from the manifest obviously) is the file "DummyClass1.class".
I have tried all of the following:
InputStream is = this.getClass().getClassLoader()
.getResourceAsStream("DummyClass1.class");
InputStream is = this.getClass().getClassLoader()
.getResourceAsStream("dumb.jar!/DummyClass1.class");
But the input stream returned is always null. I have also tried
URL url = this.getClass().getResource("DummyClass1.class");
URL url = this.getClass().getResource("dumb.jar!/DummyClass1.class");
But the URL returned is null.
I have already looked at every single one of the questions relating to accessing a file within a Jar, but the proposed solutions (as seen above) do not work for me.
All I want is to be able to get either an InputStream (or ideally a URL) for the "DummyClass1.class" inside the jar, so that I can the somehow construct a File instance.
Any suggestions would be much appreciated.
Upvotes: 2
Views: 642
Reputation: 3982
The simplest thing for you to do is to move your jar so that it is included directly in the classpath, or change your classpath to also include "com/msgxsd" as a top-level entry. In either of these cases DummyClass
will be loaded by the standard ClassLoader
and you can simply do getResourceAsStream("DummyClass1.class")
as you have already suggested.
If changing your classpath in this way is not possible then you need to create a JarInputStream
as suggested by @Micky above or in this more complete answer.
Upvotes: 1
Reputation: 11
What I would do is use a JarInputStream
to access the contents of the jar file directly. Then iterate through the JarEntry
collection until you find the file you are looking for and read it from the stream. Something like this:
JarInputStream jarIn = new JarInputStream(this.getClass().getClassLoader() .getResourceAsStream("com/msgxsd/dumb.jar"));
JarEntry entry = jarIn.getNextJarEntry();
Now read the file using the jarIn
read method.
Upvotes: 1
Reputation: 7957
Try
is = this.getClass().getClassLoader().getResourceAsStream("com/msgxsd/dumb.jar!/DummyClass1.class")
Upvotes: 1
Reputation: 1116
Try
InputStream is = this.getClass().getClassLoader().getResourceAsStream("dumb.jar/DummyClass1.class");
maybe specify the DummyClass1.class location inside the jar
Upvotes: 2
Reputation: 21902
Try this (sorry if there are typos, I'm just typing the code off the top of my head without trying it):
int index = path.indexOf('!');
if (index == -1) return url.openStream();
String jarPath = path.substring(0, index);
File jarFile = new File(new URL(jarPath).toURI());
if (!jarFile.exists()) return null;
String filePath = path.substring(index + 1);
if (filePath.startsWith("/")) {
filePath = filePath.substring(1);
}
JarFile jar = new JarFile(jarFile);
return jar.getInputStream(jar.getJarEntry(filePath));
Upvotes: 1