Why my Jar doesn't run unless I extract files?


Every time I run the exported .jar file, that contains a JFrame with an image as its icon, the file doesn't run, <strong>unless I extract the file</strong>. In the compiler it is running. I dont want to make a launcher that saves both, the resources package and the jar file, in a directory.



"Why my Jar doesn't run unless I extract files?"


This seems to be the behavior of using File to your resources. Take for example

File file = new File("resources/image.png"); Image image = ImagIO.read(file);

And you project structure (Note the resources should actually be in the src, so that it builds into the jar automatically - unless you configure it differently. But for the sake of this argument, let's say you <em>do</em> confgigure it where resources is built to the jar)

C:\ Project resources\image.png

Some examination:


Run from IDE - WORKS! Why? Using File looks for files on the file system. Using a relative path, the search will begin from the "working directory", which in the case of the IDE in generally the project root. So "resources/image.png" is a valid path, relative to ProjectRoot

</li> <li>

Build jar, say it ends up in a dist dir in the project. This is what it looks like

ProjectRoot dist ProjectRoot.jar

Now for the sake of this argument (and is actually the correct way), let's try and print the URL of the resource in out program, so that when you run the jar, it prints out the URL of the file

URL url = Test.class.getResource("/resources/image.png"); System.out.println(url.toString());

When we run the jar C:\ProjectRoot\dist> java -jar ProjectRoot.jar We will see the print out C:\ProjectRoot\dist\ProjectRoot.jar!\resources\image.png. You can obviously see even though the current working directory is the location of the jar, the paths no longer match, with the added jar ProjectRoot.jar! location.

</li> <li>

So why does it work when we extract it. Well when you extract it, then the path is correct

C:\ProjectRoot dist resources/image.png // from extracted jar ProjectRoot.jar

When you run from the C:\ProjectRoot\dist >, the resource dir is where is should be.

</li> </ul>

<strong>Ok enough with the explanation.</strong>

For this reason, when you want to read embedded resources, they should be read from an URL as Andrew Thompson mentioned. This url should be relative to the class calling it, or the class loader. Here are a couple different ways:


As shown already

URL url = getClass().getResource("/resources/image.png");

Notice the /. This will bring us to the root of the classpath, where the resources dir will be. URL can be passed to many constructors, like ImageIcon(URL) or `ImageI.read(URL)

</li> <li>

You can use:

InputStream is = getClass().getResourceAsStream("/resources/image.png");

Which will use an URL under the hood. You can use InputStream with many constructors also.

</li> <li>

There's also ways to use the class loader, which will start at the root, so you don't need the /

URL url = getClass().getClassLoader().getResource("resources/image.png"); </li> </ol>

So there are a few ways you can go about it. But in general, reading File with hard coded string paths is never a good idea, when using embedded resources. It's possible to obtain the path dynamically so you can use File, but you will still need to use one of the aforementioned techniques, which unless you really need a File would be pointless, as you can do what you need with the InputStream or URL

<hr /><h2>To make a long story short</h2>

This would work

ProjectRoot src\resources\image.png URL url = getClass().getResource("/resources/image.png"); Image image = ImageIO.read(url);


  • Where and How To Define An Application Property? - JHIpster
  • How to attach php documentation in eclipse
  • Is there a way to link a linux's thread TID and a pthread_t “thread ID”
  • findObjectsInBackgroundWithBlock block signature not correct
  • Let a function return any type in C++ class
  • Default parameter as generic type
  • Debugging VB6 Code From Visual Studio 2010
  • Spring boot 2.0.0.M4 required a bean named 'entityManagerFactory' that could not be found
  • d3 v4 drag and drop with TypeScript
  • Why does access(2) check for real and not effective UID?
  • Google Custom Search with transparent background
  • Checking free space on FTP server
  • Handling un-mapped Rest path
  • Paperclip, set path outside of rails root folder
  • Insert into database using onclick function
  • Illegal mix of collations for operation for date/time comparison
  • What is Eclipse's Declaration View used for?
  • How to recover from a Spring Social ExpiredAuthorizationException
  • script to move all files from one location to another location
  • ILMerge & Keep Assembly Name
  • Can I make an Android app that runs a web view in Chrome 39?
  • Symfony2: How to get request parameter
  • Large data - storage and query
  • Timeout for blocking function call, i.e., how to stop waiting for user input after X seconds?
  • WOWZA + RTMP + HTML5 Playback?
  • R: gsub and capture
  • SVN: Merging two branches together
  • Hibernate gives error error as “Access to DialectResolutionInfo cannot be null when 'hibernate.
  • Run Powershell script from inside other Powershell script with dynamic redirection to file
  • Matrix multiplication with MKL
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • Proper folder structure for lots of source files
  • Hits per day in Google Big Query
  • How to CLICK on IE download dialog box i.e.(Open, Save, Save As…)
  • Memory offsets in inline assembly
  • Can Visual Studio XAML designer handle font family names with spaces as a resource?
  • File not found error Google Drive API
  • How does Linux kernel interrupt the application?
  • How can I remove ASP.NET Designer.cs files?
  • Converting MP3 duration time