Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 22 of 22

Thread: Program running okay in Eclipse, not running okay when exported as JAR.

  1. #1
    Member
    Join Date
    May 2013
    Posts
    106
    My Mood
    Amused
    Thanks
    16
    Thanked 9 Times in 9 Posts

    Default Program running okay in Eclipse, not running okay when exported as JAR.

    Hey all. New member. Learning Java in class, but not really truly getting it until I poke around in Eclipse and see what commands do what. Learn by doing, I guess. It's been a good approach so far, but now I've hit a roadblock I just can't suss out. I'm sorry if this has been asked before but I couldn't figure out what search terms to look up that wouldn't give too broad an answer.

    So I wrote this program. Well, rather than describe it, here's a screenshot.

    mycardgame.gif

    So you start with 100 coins. Wager 1 to 100. Then you click a card from one of the 4 face down cards. If you pick a higher card, your wager is doubled, and you have the option to go double or nothing on another round. You can keep going double or nothing until your winnings from that hand are 100,000 coins or higher. If you tie, you have to draw again, and if you lose, you lose your wager.

    The project consists of 3 separate files in a package called higherNumber. I'm trying to get the hang of programming with different sections of code in different files when appropriate. So there are three .java files.

    • HigherNumber.java: Contains most of the code for the program
    • Deck.java: Contains the definition for the Deck class representing a deck of cards.
    • Card.java: Contains the definition for the Card class representing a single card.



    So the cards are actually JButtons with ImageIcons attached. The images are all GIF files stored in a folder called "multimedia". Originally, when setting up the ImageIcons, I just passed a string, so I had lines like:

    faceDown = new ImageIcon("multimedia/redback.gif");

    Except when I did this and exported it as a JAR, the images wouldn't show up.

    Then I learned about URLs, and decided to switch over everything to URLs. So now it's more like:

    faceDownURL = this.getClass().getResource("multimedia/redBack.gif");
    faceDown = new ImageIcon(faceDownURL);

    The multimedia folder was relocated to the bin\higherNumber folder, with all the .class files, because I read that when using URLs you need to put your resources in the Classpath.

    So like I said, it all works great if I run from Eclipse. It doesn't work when exported as a Runnable JAR file. If run through Windows it just flashes and nothing happens. If run through a command prompt, I get a Null Pointer Exception at this line in the Card class:

    //Create a URL based on the constructed string.
    URL cardIconURL = this.getClass().getResource(iconName); 
     
    return new ImageIcon(cardIconURL);

    So I did some snooping. I tossed in System.out.println(cardIconURL); right before the return statement, and it just said "NULL". Which I'm guessing means that the this.getClass().getResource(iconName) statement isn't working because it isn't finding the multimedia folder or its GIF files. I think what's happening is that they are there in the file system in Windows, so Eclipse finds them, but they AREN'T there in the exported runnable JAR. I browsed the JAR with 7Zip and confirmed this.

    So the runnable JAR isn't working because the images aren't being included with it. Why this is happening and how to fix it I cannot figure out. There's something about using Eclipse that I don't understand. Please help!


  2. #2
    Crazy Cat Lady KevinWorkman's Avatar
    Join Date
    Oct 2010
    Location
    Washington, DC
    Posts
    5,424
    My Mood
    Hungover
    Thanks
    144
    Thanked 636 Times in 540 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    You can use the command prompt to view the contents of the jar: Viewing the Contents of a JAR File (The Java™ Tutorials > Deployment > Packaging Programs in JAR Files)

    Are the images inside the jar?

    If so, there's a problem in your code and we'll need to see an SSCCE that demonstrates exactly what you're doing.

    If not, then you have to tell eclipse about the multimedia folder. Simply moving the folder to the bin directory isn't enough- eclipse doesn't know to export that to the jar. There are a couple ways to do this: either add the multimedia directory as a source folder, or put it inside the actual src folder, or include them in the export dialog.
    Useful links: How to Ask Questions the Smart Way | Use Code Tags | Java Tutorials
    Static Void Games - Play indie games, learn from game tutorials and source code, upload your own games!

  3. The Following User Says Thank You to KevinWorkman For This Useful Post:

    mstabosz (June 3rd, 2013)

  4. #3
    Member
    Join Date
    May 2013
    Posts
    106
    My Mood
    Amused
    Thanks
    16
    Thanked 9 Times in 9 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    Hi Kevin, thanks for your reply.

    Quote Originally Posted by KevinWorkman View Post
    I've seen that link, and it makes such little sense that it just added to my aggravation.


    Are the images inside the jar?
    I don't think so. I've looked with 7Zip and didn't see them in there.

    If not, then you have to tell eclipse about the multimedia folder. Simply moving the folder to the bin directory isn't enough- eclipse doesn't know to export that to the jar. There are a couple ways to do this: either add the multimedia directory as a source folder, or put it inside the actual src folder, or include them in the export dialog.
    This is the part that keeps stumping me. I cannot figure out how to do this.

    If I put the multimedia directory inside the src folder (but not in the bin folder), the program won't run from Eclipse either. I think it's looking for them in the bin folder?

    I don't understand what you mean by "add the multimedia directory as a source folder" and "include them in the export dialog". Exporting as a runnable JAR through Eclipse doesn't offer me any options. I get a group of radio buttons reading "Extract required libraries into generated JAR", "Package required libraries into generated JAR", and "Copy required libraries into a sub-folder next to the generated JAR". None of these helped get the images into the exported JAR. There's an option to "Save as ANT script". Haven't tried that, but it doesn't look like it will do anything.

  5. #4
    Super Moderator jps's Avatar
    Join Date
    Jul 2012
    Posts
    2,642
    My Mood
    Daring
    Thanks
    90
    Thanked 263 Times in 232 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    Quote Originally Posted by mstabosz View Post
    If I put the multimedia directory inside the src folder (but not in the bin folder), the program won't run from Eclipse either. I think it's looking for them in the bin folder?
    In eclipse you should be able to put them in any of the folders, normally I use a package within the project for images. When you export eclipse will give options to include referenced resources in the jar, read the options and press next instead of finish until next is no longer active. There are (should be) several pages of options, one should fix the problem if the images are not in the jar. Otherwise changing the path to point to the correct folder would fix it. ("multimedia/redback.gif") might become ("src/multimedia/redback.gif") or ("bin/multimedia/redback.gif") .....or where ever the class looking for the gif is in relation to where the gif is going to land in the jar

  6. The Following User Says Thank You to jps For This Useful Post:

    mstabosz (June 3rd, 2013)

  7. #5
    Member
    Join Date
    May 2013
    Posts
    106
    My Mood
    Amused
    Thanks
    16
    Thanked 9 Times in 9 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    Okay I somehow got this working after tooling around with it. I wrote the below post while doing so, and I think it helped me collect my thoughts better. Even though it's working, I hope you folks don't mind, but I'm gonna leave the post intact for further reference for me.

    What I think I did was make a copy of the multimedia folder inside the src folder, and that automagically created another copy within the bin folder. Then I changed the pictureRoot string (see below, it's a String class variable I use to pass to the .getResource() command) from "multimedia/" to "../multimedia".

    Thanks for your help jps and Kevin Workman. It was much more helpful than what I could get over at StackOverflow.

    ------------------------------

    Quote Originally Posted by jps View Post
    In eclipse you should be able to put them in any of the folders, normally I use a package within the project for images. When you export eclipse will give options to include referenced resources in the jar, read the options and press next instead of finish until next is no longer active.
    There are (should be) several pages of options, one should fix the problem if the images are not in the jar. [/quote]

    I don't see anything like that. I see this when I export to runnable JAR.

    runnablejar.jpg

    There's a "Next" option down there, but it's always grayed out.

    Otherwise changing the path to point to the correct folder would fix it. ("multimedia/redback.gif") might become ("src/multimedia/redback.gif") or ("bin/multimedia/redback.gif") .....or where ever the class looking for the gif is in relation to where the gif is going to land in the jar
    How do I change the path? I have some String variables that are used in the .getResource() calls. So in the main HigherNumber class I have:

    //Directory with all the pictures.
    private final String pictureRoot = "multimedia/";
    //Icon for a face down card.
    private ImageIcon faceDown;

    as a class variable and then down int he constructor I have:

    //Set URL for default faceDown icon.
    faceDownURL = this.getClass().getResource(pictureRoot +"redBack.gif");
    System.out.println(faceDownURL);
    //Set location for default back face of cards.
    faceDown = new ImageIcon(faceDownURL);

    I do a println statement to see what the value of faceDownURL is, and I get:

    file:/C:/Documents%20and%20Settings/mstabosz/My%20Documents/Dropbox/Projects/Java/HigherNumber/bin/higherNumber/multimedia/redBack.gif

    I can change the pictureRoot string to "../multimedia" and the URL becomes:

    file:/C:/Documents%20and%20Settings/mstabosz/My%20Documents/Dropbox/Projects/Java/HigherNumber/bin/multimedia/redBack.gif

    But I can't go any higher up the directory tree than that. "../../multimedia" makes the URL equal to "null" even if the multimedia folder is up there.
    I get the same results if I change pictureRoot to "src/multimedia". The program cannot seem to conceive of resource outside the bounds of the bin folder.

  8. #6
    Member
    Join Date
    May 2013
    Posts
    106
    My Mood
    Amused
    Thanks
    16
    Thanked 9 Times in 9 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    Okay now it's back to not working again. I don't understand. The images are in the JAR file now, but I'm getting the same stupid Null pointer exceptions. I didn't really do anything different.... I deleted the multimedia folder from the SRC folder and re-added it, just to see if it would in fact add a copy to the bin folder like I thought it was. It did that, but now I'm getting the same old Null pointer exceptions.

    The extra bizarre part is that before I deleted and re-added the multimedia folder, I made a backup copy of the whole folder, including the working JAR file, over to C:\temp, and now THAT isn't working either and literally no changes were made to it. Here is how I set up the URLs in the Card class, inside a function called "setImage". The function builds a string to match the name of the .gif file with the card images. The string building part is working; it works without flaw in Eclipse and worked before I was using URLs. Below is just the part with the base string and the URL creation.

    //Build a string to represent the location of the corresponding card icon.
    //Start with the basic file folder.
    String iconName = "../multimedia/";
     
    //Create a URL based on the constructed string.
    URL cardIconURL = this.getClass().getResource(iconName); 
     
    return new ImageIcon(cardIconURL);

    Again it's working fine in Eclipse but not in the runnable JAR. This time, though, the images are in the JAR, within the multimedia folder:

    runnablejar_contents.jpg

    EDIT: Okay I realize what I did change. The runnable JAR was sitting in Windows in the same folder as another copy of the multimedia folder. After I declared victory and made my backup copy to C:\temp, I also deleted this spare copy of the multimedia folder. That's when the JAR stopped working. My runnable JAR has the multimedia folder and its GIF files within it, but it seems like it is still relying on resources outside the JAR. Why?

  9. #7
    Crazy Cat Lady KevinWorkman's Avatar
    Join Date
    Oct 2010
    Location
    Washington, DC
    Posts
    5,424
    My Mood
    Hungover
    Thanks
    144
    Thanked 636 Times in 540 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    Here's the easiest way to accomplish this:

    Step 1: Put your multimedia folder inside your src folder. It should be at the same level as any packages you have declared, or any classes with the default package.

    Step 2: Consider the src directory your top-level folder. You can go above that when running from eclipse, but not from the jar, since it's going to package everything inside the src folder into the jar. In other words, get rid of the ".." part of your multimedia path.

    Step 3: Use the getResource() function with the above 2 things in mind.

    However, looking at your code, you're trying to pass in a directory as an ImageIcon path. Not sure how a directory can be an ImageIcon.
    Useful links: How to Ask Questions the Smart Way | Use Code Tags | Java Tutorials
    Static Void Games - Play indie games, learn from game tutorials and source code, upload your own games!

  10. #8
    Member
    Join Date
    May 2013
    Posts
    106
    My Mood
    Amused
    Thanks
    16
    Thanked 9 Times in 9 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    Quote Originally Posted by KevinWorkman View Post
    Here's the easiest way to accomplish this:

    Step 1: Put your multimedia folder inside your src folder. It should be at the same level as any packages you have declared, or any classes with the default package.
    Already did that.

    Step 2: Consider the src directory your top-level folder. You can go above that when running from eclipse, but not from the jar, since it's going to package everything inside the src folder into the jar. In other words, get rid of the ".." part of your multimedia path.
    I don't understand. If I get rid of the "../" it looks in bin/higherNumber instead of bin/multimedia


    Step 3: Use the getResource() function with the above 2 things in mind.
    I don't understand what you mean by this. Unless I'm misusing .getClass().getResource.

    However, looking at your code, you're trying to pass in a directory as an ImageIcon path. Not sure how a directory can be an ImageIcon.
    Huh? I'm passing in a file name with a full directory path. When the URL works, it passes a URL such as
    file:/C:/Documents%20and%20Settings/mstabosz/My%20Documents/Dropbox/Projects/Java/HigherNumber/bin/multimedia/redBack.gif. Isn't that how the ImageIcon constructor works?

    Wait, I think I see the problem. I only did a snippet of the code from the setImage function and that could have been confusing. Here's the whole function, which builds a string equal to an entire file name path.

    //Method to set the current card's image icon.
    	private ImageIcon setImage()
    	{
    		//Build a string to represent the location of the corresponding card icon.
    		//Start with the basic file folder.
    		String iconName = "/multimedia/";
     
    		//If card is a joker, set that as the next part of the string.  
    		if(this.suit.compareToIgnoreCase("joker") == 0)
    			if(useBlack)
    				iconName += "jb";
    			else
    				iconName += "jr";	
    		else
    		{
    			//Add the first letter of the suit to get the first part of the icon file name.
    			iconName += (this.suit.charAt(0));
    			//If the rank is a 10, the next 2 characters are 10.
    			//If the rank is an Ace, the next character is a 1.
    			//Otherwise, the next character is the first letter of the rank. 
    			if(this.rank.compareToIgnoreCase("10") == 0)
    				iconName += "10";
    			else
    				if(this.rank.compareToIgnoreCase("Ace") == 0)
    					iconName += "1";
    				else
    					iconName += this.rank.charAt(0);	
    		}
    		//Add the file type extension to the end.
    		iconName += ".gif";
     
    		//Create a URL based on the constructed string.
    		URL cardIconURL = this.getClass().getResource(iconName); 
     
    		return new ImageIcon(cardIconURL);
    	}

  11. #9
    Crazy Cat Lady KevinWorkman's Avatar
    Join Date
    Oct 2010
    Location
    Washington, DC
    Posts
    5,424
    My Mood
    Hungover
    Thanks
    144
    Thanked 636 Times in 540 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    Quote Originally Posted by mstabosz View Post
    I don't understand. If I get rid of the "../" it looks in bin/higherNumber instead of bin/multimedia
    Your jar doesn't have a bin folder. It doesn't have anything above the src folder. So using ../multimedia doesn't really make any sense in the jar.

    Quote Originally Posted by mstabosz View Post
    I don't understand what you mean by this. Unless I'm misusing .getClass().getResource.
    You're calling the method correctly. It's what you're passing into the method that looks wonky to me. I just included the step to be complete.

    Quote Originally Posted by mstabosz View Post
    Huh? I'm passing in a file name with a full directory path. When the URL works, it passes a URL such as
    file:/C:/Documents%20and%20Settings/mstabosz/My%20Documents/Dropbox/Projects/Java/HigherNumber/bin/multimedia/redBack.gif. Isn't that how the ImageIcon constructor works?
    I'm not sure about that full path. You don't want to use full paths for resources inside jars. But I was simply responding to this code:

    String iconName = "../multimedia/";
     
    //Create a URL based on the constructed string.
    URL cardIconURL = this.getClass().getResource(iconName);

    Quote Originally Posted by mstabosz View Post
    Wait, I think I see the problem. I only did a snippet of the code from the setImage function and that could have been confusing. Here's the whole function, which builds a string equal to an entire file name path.
    I recommend printing out the iconName String before passing it into ImageIcon. What does it print out from eclipse? What does it print out when running the jar?
    Useful links: How to Ask Questions the Smart Way | Use Code Tags | Java Tutorials
    Static Void Games - Play indie games, learn from game tutorials and source code, upload your own games!

  12. #10
    Member
    Join Date
    May 2013
    Posts
    106
    My Mood
    Amused
    Thanks
    16
    Thanked 9 Times in 9 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    Quote Originally Posted by KevinWorkman View Post
    Your jar doesn't have a bin folder. It doesn't have anything above the src folder. So using ../multimedia doesn't really make any sense in the jar.
    I see your point, though it shouldn't cause trouble because it's basically acting the same as it does if you're navigating through a DOS prompt, right? If the JAR is at the top level ../multimedia will try to go up one level, fail (since there is no higher level), and just look for multimedia in its current directory? Anyway it's a moot point I think because I've adjusted the code and gotten rid of the dots. pictureRoot = "/multimedia/" now.

    I'm not sure about that full path. You don't want to use full paths for resources inside jars.
    I'm not sending it a full path. That's the URL that Java is creating. I guess the program is sending a full path and maybe that's why it's not working inside the JAR (there is no C:/Documents and Settings/...... within the JAR).

    I recommend printing out the iconName String before passing it into ImageIcon. What does it print out from eclipse? What does it print out when running the jar?
    Good idea. I put this line in the Card class's setImage function: System.out.println("Icon name: " +iconName); This is the first line of the 54 lines of output it produces:

    Via Eclipse: Icon name: /multimedia/S2.gif
    Via JAR in the DOS console: Icon name: /multimedia/S2.gif

    So the same thing.

    Do you think that the root cause of the problem could be the URL that .getResource is creating? Eclipse DOES understand the existence of the C:\Documents and Setting\.... folder path but the JAR doesn't.

  13. #11
    Crazy Cat Lady KevinWorkman's Avatar
    Join Date
    Oct 2010
    Location
    Washington, DC
    Posts
    5,424
    My Mood
    Hungover
    Thanks
    144
    Thanked 636 Times in 540 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    Try changing this line:

    this.getClass().getResource(iconName);

    To this:

    this.getClass().getClassLoader().getResource(iconName);
    Useful links: How to Ask Questions the Smart Way | Use Code Tags | Java Tutorials
    Static Void Games - Play indie games, learn from game tutorials and source code, upload your own games!

  14. #12
    Member
    Join Date
    May 2013
    Posts
    106
    My Mood
    Amused
    Thanks
    16
    Thanked 9 Times in 9 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    Quote Originally Posted by KevinWorkman View Post
    Try changing this line:

    this.getClass().getResource(iconName);

    To this:

    this.getClass().getClassLoader().getResource(iconName);
    Hi Kevin. Sorry for not replying sooner. It's been a crazy busy week. Thanks for your help so far.

    I actually implemented your changes last week, but didn't get a chance to update this thread with the results until now.

    So now I'm getting the same results running through Eclipse and running the JAR through DOS. It's consistent, but not in a good way It's the same old Null Pointer Exception.

    Line 150 of my Card class is the first place the program tries to make an ImageIcon. Here are lines 146 through 150.

    		System.out.println("Icon name: " +iconName);
    		//Create a URL based on the constructed string.
    		URL cardIconURL = this.getClass().getClassLoader().getResource(iconName); 
     
    		return new ImageIcon(cardIconURL);

    And here is the output, which is the same via Eclipse or the JAR.

    Icon name: /multimedia/S2.gif
    Exception in thread "main" java.lang.NullPointerException
    at javax.swing.ImageIcon.<init>(Unknown Source)
    at higherNumber.Card.setImage(Card.java:150)
    at higherNumber.Card.<init>(Card.java:36)
    at higherNumber.Deck.<init>(Deck.java:22)
    at higherNumber.HigherNumber.<init>(HigherNumber.java :16)
    at higherNumber.HigherNumber.main(HigherNumber.java:8 63)

  15. #13
    Crazy Cat Lady KevinWorkman's Avatar
    Join Date
    Oct 2010
    Location
    Washington, DC
    Posts
    5,424
    My Mood
    Hungover
    Thanks
    144
    Thanked 636 Times in 540 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    Can you take a screenshot of your directory hierarchy in eclipse so we know exactly where everything is located?

    If your multimedia folder is indeed inside your src folder, and that multimedia folder does include a file named S2.gif (check spelling and capitalization), then I would expect that code to work.
    Useful links: How to Ask Questions the Smart Way | Use Code Tags | Java Tutorials
    Static Void Games - Play indie games, learn from game tutorials and source code, upload your own games!

  16. The Following User Says Thank You to KevinWorkman For This Useful Post:

    mstabosz (June 12th, 2013)

  17. #14
    Forum VIP
    Join Date
    Jul 2010
    Posts
    1,676
    Thanks
    25
    Thanked 329 Times in 305 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    Have you tried using ImageIO?

    BufferedImage cardIconImage = ImageIO.read(this.getClass().getResource(iconName));
    return new ImageIcon(cardIconImage);
    NOTE TO NEW PEOPLE LOOKING FOR HELP ON FORUM:

    When asking for help, please follow these guidelines to receive better and more prompt help:
    1. Put your code in Java Tags. To do this, put [highlight=java] before your code and [/highlight] after your code.
    2. Give full details of errors and provide us with as much information about the situation as possible.
    3. Give us an example of what the output should look like when done correctly.

    Join the Airline Management Simulation Game to manage your own airline against other users in a virtual recreation of the United States Airline Industry. For more details, visit: http://airlinegame.orgfree.com/

  18. The Following User Says Thank You to aussiemcgr For This Useful Post:

    mstabosz (June 12th, 2013)

  19. #15
    Member
    Join Date
    May 2013
    Posts
    106
    My Mood
    Amused
    Thanks
    16
    Thanked 9 Times in 9 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    Quote Originally Posted by KevinWorkman View Post
    Can you take a screenshot of your directory hierarchy in eclipse so we know exactly where everything is located?

    Here's part of it, the SRC with a few of the images.. I hope that's enough of it.

    eclipse_folder_structure.jpg

    If your multimedia folder is indeed inside your src folder, and that multimedia folder does include a file named S2.gif (check spelling and capitalization), then I would expect that code to work.
    I didn't think capitalization mattered. But I rewrote the code that builds the iconName string so that the iconName (for the first card, the 2 of Spades) is s2.gif instead of S2.gif. It made no difference.

  20. #16
    Member
    Join Date
    May 2013
    Posts
    106
    My Mood
    Amused
    Thanks
    16
    Thanked 9 Times in 9 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    Quote Originally Posted by aussiemcgr View Post
    Have you tried using ImageIO?

    BufferedImage cardIconImage = ImageIO.read(this.getClass().getResource(iconName));
    return new ImageIcon(cardIconImage);
    No but I'll give that a shot later when I have some time. Thanks.

  21. #17
    Forum VIP
    Join Date
    Jul 2010
    Posts
    1,676
    Thanks
    25
    Thanked 329 Times in 305 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    Ok. Tell me how that goes. I'm pretty sure that jars do not like you accessing their resources with anything other than Streams. URL is not a Stream, but accessing the Image with the ImageIO.read() method preserves its Stream.
    Using URL would work fine in Eclipse, since the resources for the project are not in a compressed format, so they do not require Stream access. But when you package it in a jar (which is effectively a zip folder), you must use Streams to access the data.
    NOTE TO NEW PEOPLE LOOKING FOR HELP ON FORUM:

    When asking for help, please follow these guidelines to receive better and more prompt help:
    1. Put your code in Java Tags. To do this, put [highlight=java] before your code and [/highlight] after your code.
    2. Give full details of errors and provide us with as much information about the situation as possible.
    3. Give us an example of what the output should look like when done correctly.

    Join the Airline Management Simulation Game to manage your own airline against other users in a virtual recreation of the United States Airline Industry. For more details, visit: http://airlinegame.orgfree.com/

  22. The Following User Says Thank You to aussiemcgr For This Useful Post:

    mstabosz (June 12th, 2013)

  23. #18
    Crazy Cat Lady KevinWorkman's Avatar
    Join Date
    Oct 2010
    Location
    Washington, DC
    Posts
    5,424
    My Mood
    Hungover
    Thanks
    144
    Thanked 636 Times in 540 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    Quote Originally Posted by mstabosz View Post
    Here's part of it, the SRC with a few of the images.. I hope that's enough of it.

    eclipse_folder_structure.jpg

    I didn't think capitalization mattered. But I rewrote the code that builds the iconName string so that the iconName (for the first card, the 2 of Spades) is s2.gif instead of S2.gif. It made no difference.
    Capitalization doesn't matter on linux; it does on Windows. Not sure about mac.

    But reading aussiemcgr's advice makes sense. Either try his approach or use the getResourceAsStream() method.
    Useful links: How to Ask Questions the Smart Way | Use Code Tags | Java Tutorials
    Static Void Games - Play indie games, learn from game tutorials and source code, upload your own games!

  24. The Following User Says Thank You to KevinWorkman For This Useful Post:

    mstabosz (June 12th, 2013)

  25. #19
    Member
    Join Date
    May 2013
    Posts
    106
    My Mood
    Amused
    Thanks
    16
    Thanked 9 Times in 9 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    Quote Originally Posted by aussiemcgr View Post
    Ok. Tell me how that goes. I'm pretty sure that jars do not like you accessing their resources with anything other than Streams. URL is not a Stream, but accessing the Image with the ImageIO.read() method preserves its Stream.
    Using URL would work fine in Eclipse, since the resources for the project are not in a compressed format, so they do not require Stream access. But when you package it in a jar (which is effectively a zip folder), you must use Streams to access the data.
    It seems to be working so far. The JAR still isn't running, BUT.... it's failing in completely different places. And that's progress.

    Actually I think I see the root of the problem. After I spent some time converting all the ImageIcon constructors to read an IO Image Stream instead of a URL, and got the program to run okay in Eclipse, I tried again with a new JAR. I had a line of code in there to do a println and show the value of iconName for every successful image icon that was loaded. I noticed that it got as high as s10.gif (the 10 of Spades) but then threw and IllegalArgument Exception when it tried to do sJ.gif (Jack of Spades). Come to realize that it's the case-sensitivity finally biting me in the butt: the actual file name is sj.gif. Luckily the logic to build that string was set up in such a way that I could change that J (along with the Q and K for queen and king) to a lowercase just by altering a few characters in a switch statement from the Card class's setRank method.

    It's still throwing IllegalArgument Exceptions, but they're in the main HigherNumber class, and they all seem to have the same cause; case insensitivity. I guess I'll just flip a coin to see if I change the strings in the program to accommodate the existing file names or change the file names to match the program. Six of one, half dozen of the other I suppose.

    --- Update ---

    Success! It works perfectly both through Eclipse and in the runnable JAR!

    Thanks a bunch aussiemcgr, KevinWorkman, and jps. I spent so much time beating my head against the wall on this one. I haven't been doing Java programming for that long (only about 6 months) and admittedly I haven't done anything hugely complex (though I found client/server programming to be a real mindbender...), but this was the first thing I couldn't figure out on my own.

    Here's the finished game if you feel like playing it.

    One curiosity persists. I added some menus that would let you change around the background color and the card background design. It's in a listener class for some JMenuItem objects. What perplexes me is why this still works in the JAR even though it's still using URLs.

    //Listener for card back options.
    	class CardDesignOptionListener implements ActionListener
    	{
    		public void actionPerformed(ActionEvent e)
    		{			
     
    			//Ignore this on double or nothing or tie rounds.
    			if((isDoubleOrNothing) || (isTie))
    			{
    				JOptionPane.showMessageDialog(null, "Cannot change card design during double or nothing or tie round!", 
    						"Invalid option.", JOptionPane.ERROR_MESSAGE);
    				return;
    			}
    			else
    				//Disable cheat mode when new card design is chosen, then continue.
    				cheatCodeEnabled = false;
     
    			//Send message warning user that this will force a new hand to be dealt.  Exit
    			//method if user declines to proceed.
    			if(!proceed())
    				return;
     
    			//Get the URL for the new face down face.
    			faceDownURL = this.getClass().getResource(pictureRoot +e.getActionCommand() +"back.gif");
     
    			//Set the new face down image.
    			faceDown = new ImageIcon(faceDownURL);
     
    			//Start a new game.
    			newGame(false);
    		}
    	}

  26. #20
    Crazy Cat Lady KevinWorkman's Avatar
    Join Date
    Oct 2010
    Location
    Washington, DC
    Posts
    5,424
    My Mood
    Hungover
    Thanks
    144
    Thanked 636 Times in 540 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    I'm not convinced the URLs were ever really your actual problem- I think your problem was confusing absolute and relative paths. Anything that starts with a / is an absolute path. Plus the getClass().getResource() methods look next to the class, not at the top-level src directory, which is why I said to use getClass().getClassLoader().getResource() instead. But using an absolute path starting with / still won't work with that method, since it's looking outside the jar anyway.
    Useful links: How to Ask Questions the Smart Way | Use Code Tags | Java Tutorials
    Static Void Games - Play indie games, learn from game tutorials and source code, upload your own games!

  27. #21
    Forum VIP
    Join Date
    Jul 2010
    Posts
    1,676
    Thanks
    25
    Thanked 329 Times in 305 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    I've never been able to access compressed content (such as the resources in a jar) using URLs. I have always had to use Streams. I assume because the URLs can't decompress the files or something. I'm not sure what the exact reasoning is off the top of my head, but I just know that Streams are required. If you look at the ZipFile and JarFile class in the API, it only allows access via InputStreams. While he is not using those classes, it stands to reason that reading the content of an executable's own jar is restricted by the same rules as attempting to read the content of a different jar directly using the JarFile class.
    NOTE TO NEW PEOPLE LOOKING FOR HELP ON FORUM:

    When asking for help, please follow these guidelines to receive better and more prompt help:
    1. Put your code in Java Tags. To do this, put [highlight=java] before your code and [/highlight] after your code.
    2. Give full details of errors and provide us with as much information about the situation as possible.
    3. Give us an example of what the output should look like when done correctly.

    Join the Airline Management Simulation Game to manage your own airline against other users in a virtual recreation of the United States Airline Industry. For more details, visit: http://airlinegame.orgfree.com/

  28. #22
    Crazy Cat Lady KevinWorkman's Avatar
    Join Date
    Oct 2010
    Location
    Washington, DC
    Posts
    5,424
    My Mood
    Hungover
    Thanks
    144
    Thanked 636 Times in 540 Posts

    Default Re: Program running okay in Eclipse, not running okay when exported as JAR.

    Sorry, that's not right, and it's pretty easy to test, which we should have done sooner.

    I create a project in eclipse. In the src directoy, I put an image file named Duke.png. I also create a package named test and create this class inside it:

    package test;
    import java.net.URL;
    public class JarResourceTester {
    	public static void main(String... args){
    		URL url = JarResourceTester.class.getResource("Duke.png");
    		System.out.println(url.toString());
    	}
    }

    If you run that class, you get a NPE because it can't find Duke.png. Sound familiar? The problem is that using class.getResource() is looking *beside the class*, so it's looking inside the test package directory. We could do this instead:

    package test;
    import java.net.URL;
    public class JarResourceTester {
    	public static void main(String... args){
    		URL url = JarResourceTester.class.getResource("../Duke.png");
    		System.out.println(url.toString());
    	}
    }

    This will work because it starts in the package directory next to the class, then goes up a level to the src directory. But that is gross and error-prone if we move stuff around. Plus it won't work in the jar. This is the OP's original problem.

    You could also do this:

    package test;
    import java.net.URL;
    public class JarResourceTester {
    	public static void main(String... args){
    		URL url = JarResourceTester.class.getResource("/Duke.png");
    		System.out.println(url.toString());
    	}
    }

    Which works both from eclipse and from the jar. The / indicates that it's an absolute path (starting from the classpath), so it sees the file.

    Eclipse outputs: file:/C:/Users/kworkman/Desktop/Tests/bin/Duke.png
    Jar outputs: jar:file:/C:/Users/kworkman/Desktop/Test.jar!/Duke.png

    But that seems confusing because you can mix absolute paths with paths that are relative to the class, so my preferred approach is this:

    package test;
    import java.net.URL;
    public class JarResourceTester {
    	public static void main(String... args){
    		URL url = JarResourceTester.class.getClassLoader().getResource("Duke.png");
    		System.out.println(url.toString());
    	}
    }

    That way it's clear you're independent from the location of the class.

    Digging into it a bit further, we can read about the logic Java is using to locate that file by reading the API for the ClassLoader.getResource() method:

    Finds the resource with the given name. A resource is some data (images, audio, text, etc) that can be accessed by class code in a way that is independent of the location of the code.

    The name of a resource is a '/'-separated path name that identifies the resource.

    This method will first search the parent class loader for the resource; if the parent is null the path of the class loader built-in to the virtual machine is searched. That failing, this method will invoke findResource(String) to find the resource.

    Parameters:
    name - The resource name
    Returns:
    A URL object for reading the resource, or null if the resource could not be found or the invoker doesn't have adequate privileges to get the resource.
    And in fact, if we look at the source code of the ClassLoader.getResourceAsStream() method, we can see that the method internally uses a URL to open a stream to it:

        public InputStream getResourceAsStream(String name) {
            URL url = getResource(name);
            try {
                return url != null ? url.openStream() : null;
            } catch (IOException e) {
                return null;
            }
        }

    So, the problem has nothing to do with streams versus URLs, and everything to do with trying to use the "up one level" .. notation in a jar URL, which won't work.
    Useful links: How to Ask Questions the Smart Way | Use Code Tags | Java Tutorials
    Static Void Games - Play indie games, learn from game tutorials and source code, upload your own games!

  29. The Following User Says Thank You to KevinWorkman For This Useful Post:

    aussiemcgr (June 12th, 2013)

Similar Threads

  1. error when running with jar
    By bczm8703 in forum What's Wrong With My Code?
    Replies: 8
    Last Post: June 24th, 2013, 01:25 AM
  2. Running .JAR file issue.
    By JosPhantasmE in forum What's Wrong With My Code?
    Replies: 12
    Last Post: January 27th, 2013, 07:07 AM
  3. Code is working in Eclipse but when exported to Runnable Jar doesn't work
    By jjain.jitendra@gmail.com in forum What's Wrong With My Code?
    Replies: 1
    Last Post: August 24th, 2011, 07:12 AM
  4. Program Runs in Eclipse but Not When Exported
    By Pantheon8 in forum Java IDEs
    Replies: 2
    Last Post: August 17th, 2011, 05:57 PM
  5. [SOLVED] jar file Built(clean and build) perfectly, but not running as jar
    By chronoz13 in forum What's Wrong With My Code?
    Replies: 18
    Last Post: July 11th, 2011, 11:41 AM

Tags for this Thread