I am trying to access a directory inside my jar file. I want to go through every of the files inside the directory itself. I tried, for example, using the following:
<Here is a solution which should work given that you use Java 7... The "trick" is to use the new file API. Oracle JDK provides a FileSystem
implementation which can be used to peek into/modify ZIP files, and that include jars!
Preliminary: grab System.getProperty("java.class.path", ".")
, split against :
; this will give you all entries in your defined classpath.
First, define a method to obtain a FileSystem
out of a classpath entry:
private static final Map<String, ?> ENV = Collections.emptyMap();
//
private static FileSystem getFileSystem(final String entryName)
throws IOException
{
final String uri = entryName.endsWith(".jar") || entryName.endsWith(".zip"))
? "jar:file:" + entryName : "file:" + entryName;
return FileSystems.newFileSystem(URI.create(uri), ENV);
}
Then create a method to tell whether a path exists within a filesystem:
private static boolean pathExists(final FileSystem fs, final String needle)
{
final Path path = fs.getPath(needle);
return Files.exists(path);
}
Use it to locate your directory.
Once you have the correct FileSystem
, use it to walk your directory using .getPath()
as above and open a DirectoryStream
using Files.newDirectoryStream()
.
And don't forget to .close()
a FileSystem
once you're done with it!
Here is a sample main()
demonstrating how to read all the root entries of a jar:
public static void main(final String... args)
throws IOException
{
final Map<String, ?> env = Collections.emptyMap();
final String jarName = "/opt/sunjdk/1.6/current/jre/lib/plugin.jar";
final URI uri = URI.create("jar:file:" + jarName);
final FileSystem fs = FileSystems.newFileSystem(uri, env);
final Path dir = fs.getPath("/");
for (Path entry : Files.newDirectoryStream(dir))
System.out.println(entry);
}
You can use the PathMatchingResourcePatternResolver
provided by Spring.
public class SpringResourceLoader {
public static void main(String[] args) throws IOException {
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
// Ant-style path matching
Resource[] resources = resolver.getResources("/Images/**");
for (Resource resource : resources) {
System.out.println("resource = " + resource);
InputStream is = resource.getInputStream();
BufferedImage img = ImageIO.read(is);
System.out.println("img.getHeight() = " + img.getHeight());
System.out.println("img.getWidth() = " + img.getWidth());
}
}
}
I didn't do anything fancy with the returned Resource
but you get the picture.
Add this to your maven dependency (if using maven):
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
This will work directly from within Eclipse/NetBeans/IntelliJ and in the jar that's deployed.
Running from within IntelliJ gives me the following output:
resource = file [C:\Users\maba\Development\stackoverflow\Q12016222\target\classes\pictures\BMW-R1100S-2004-03.jpg]
img.getHeight() = 768
img.getWidth() = 1024
Running from command line with executable jar gives me the following output:
C:\Users\maba\Development\stackoverflow\Q12016222\target>java -jar Q12016222-1.0-SNAPSHOT.jar
resource = class path resource [pictures/BMW-R1100S-2004-03.jpg]
img.getHeight() = 768
img.getWidth() = 1024