How to get a path to a resource in a Java JAR file
This is deliberate. The contents of the "file" may not be available as a file. Remember you are dealing with classes and resources that may be part of a JAR file or other kind of resource. The classloader does not have to provide a file handle to the resource, for example the jar file may not have been expanded into individual files in the file system.
Anything you can do by getting a java.io.File could be done by copying the stream out into a temporary file and doing the same, if a java.io.File is absolutely necessary.
When loading a resource make sure you notice the difference between:
getClass().getClassLoader().getResource("com/myorg/foo.jpg") //relative path
and
getClass().getResource("/com/myorg/foo.jpg")); //note the slash at the beginning
I guess, this confusion is causing most of problems when loading a resource.
Also, when you're loading an image it's easier to use getResourceAsStream()
:
BufferedImage image = ImageIO.read(getClass().getResourceAsStream("/com/myorg/foo.jpg"));
When you really have to load a (non-image) file from a JAR archive, you might try this:
File file = null;String resource = "/com/myorg/foo.xml";URL res = getClass().getResource(resource);if (res.getProtocol().equals("jar")) { try { InputStream input = getClass().getResourceAsStream(resource); file = File.createTempFile("tempfile", ".tmp"); OutputStream out = new FileOutputStream(file); int read; byte[] bytes = new byte[1024]; while ((read = input.read(bytes)) != -1) { out.write(bytes, 0, read); } out.close(); file.deleteOnExit(); } catch (IOException ex) { Exceptions.printStackTrace(ex); }} else { //this will probably work in your IDE, but not from a JAR file = new File(res.getFile());}if (file != null && !file.exists()) { throw new RuntimeException("Error: File " + file + " not found!");}
The one line answer is -
String path = this.getClass().getClassLoader().getResource(<resourceFileName>).toExternalForm()
Basically getResource
method gives the URL. From this URL you can extract the path by calling toExternalForm()
.