Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (541)
Games in Android Showcase (133)
games submitted by our members
Games in WIP (603)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  File loads in eclipse but not in a runnable .jar [solved]  (Read 3410 times)
0 Members and 1 Guest are viewing this topic.
Offline nhmllr

Senior Devvie


Medals: 1
Projects: 3


slow and steady...


« Posted 2013-01-09 02:55:07 »

I have a game completely done, but I need to make a runnable jar of it. I have a res folder with subfolders that contain textures and sounds and midi music.
The images and sounds load perfectly, but the midi files, while they play when I run the game in eclipse, they do not run when I play the game as a runnable jar.

The problem is with the file loading. I checked and the game is throwing an IOException when I try to load the file.

I do not have this problem with other resources. Can anyone help me out here? I need to get the game runnable in the next few hours.

Thanks
Offline Agro
« Reply #1 - Posted 2013-01-09 02:56:43 »

Is the MIDI loader made by yourself or is it some other library?

Offline nhmllr

Senior Devvie


Medals: 1
Projects: 3


slow and steady...


« Reply #2 - Posted 2013-01-09 03:01:18 »

I got it from someone else. Here it is:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
import java.io.File;
import java.io.IOException;

import javax.sound.midi.*;

public class MusicPlayer {

    public static Song currentSong;
    private static Sequencer midiPlayer;

    //i know it's kinda stupid to have an enum for just this purpose but it makes some other code just slightly easier so cut me a break :p
    public static enum Song{
      MENU("menu"),
      LEVEL_1("level_1"),
      LEVEL_2("level_2"),
      LEVEL_3("level_3"),
      LEVEL_4("level_4"),
      LEVEL_5("level_5"),
      LEVEL_6("level_6"),
      LEVEL_7("level_7"),
      LEVEL_8("level_8"),
      LEVEL_9("level_9"),
      LEVEL_10("level_10"),
      ENDING("ending");
     
       public String name;
       
      Song(String n){
          name = n;
       }
    }
   
   public static void playMidi(Song song){
      try {
         midiPlayer = MidiSystem.getSequencer();
         midiPlayer.setSequence(MidiSystem.getSequence(new File("res/music/"+song.name+".mid")));
         midiPlayer.open();
         midiPlayer.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
         midiPlayer.start();
         currentSong = song;
        } catch (MidiUnavailableException ex) {
           System.err.println("Midi Unavailable! "+ex.toString());
        } catch (InvalidMidiDataException ex) {
           System.err.println("Midi Invalid! "+ex.toString());
        } catch (IOException ex) {
           System.err.println("File Not Found! "+ex.toString());
           //i hear this rejection sound in the runnable jar, but the music plays perfectly in eclipse
           Sound.shotFail.play();
        }
    }
   
   public static void stop(){
      if(midiPlayer != null){
         if(midiPlayer.isOpen()){
            midiPlayer.stop();
            midiPlayer.close();
         }
      }
   }
}
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Agro
« Reply #3 - Posted 2013-01-09 03:09:51 »

Well, it looks right, unless the file extension is wrong or unless you actually set the path wrong. Make some sort of debug message to print out what the filename is.

Offline nhmllr

Senior Devvie


Medals: 1
Projects: 3


slow and steady...


« Reply #4 - Posted 2013-01-09 03:14:57 »

I highly doubt the path is wrong. Like I said, this works in eclipse and I use a practically similar method to load the PNGs that work perfectly in the JAR. I think it's something with the midi, but I couldn't imagine what.
Offline Agro
« Reply #5 - Posted 2013-01-09 03:34:38 »

Oh, I also used to experience problems between using //, /, and \\ for file paths. Might want to try those alternatives. :O

Offline ctomni231

JGO Wizard


Medals: 99
Projects: 1
Exp: 7 years


Not a glitch. Just have a lil' pixelexia...


« Reply #6 - Posted 2013-01-09 03:43:06 »

It depends where the midi is.

If the midi is within your jar, you might want to try loading it like this...

1  
2  
3  
4  
5  
6  
7  
8  
9  
File newFile = null;
URL tempURL = Thread.currentThread().getContextClassLoader().getResource(filename);
if(tempURL != null){
    try {
                newFile = new File(tempURL.toURI());
    } catch (URISyntaxException ex) {
               System.err.println("File Resource Error! "+filename);
    }
}


or, you can also put a copy of the midi in that path in a zip with your jar. It'll look like this in the file system.

1  
2  
3  
4  
(yourgame).zip contents
-----------
(yourgame).jar
res(folder) -> music(folder) -> (songname).mid


That should solve your problem...

Offline nhmllr

Senior Devvie


Medals: 1
Projects: 3


slow and steady...


« Reply #7 - Posted 2013-01-09 04:09:36 »

Sorry to be such a pain, but is there something I'm missing here? I can't get Thread.currentThread().getContextClassLoader().getResource() to work for any resource, including resources that I know are there for a fact. The code doesn't work in eclipse or in a Jar. Is there some special common setup that is necessary for this to function that I don't have implemented?

Just a note, I tested it and "Thread.currentThread().getContextClassLoader()" does return an object, so the problem is only with the getResource() method

Thanks
Online CaptainJester

JGO Knight


Medals: 12
Projects: 2
Exp: 14 years


Make it work; make it better.


« Reply #8 - Posted 2013-01-09 04:15:54 »

1  
midiPlayer.setSequence(MidiSystem.getSequence(getClass().getResourceAsStream("/res/music/"+song.name+".mid")));

The res folder needs to be placed at the root of your package tree (Typically the root of the jar).

Offline ctomni231

JGO Wizard


Medals: 99
Projects: 1
Exp: 7 years


Not a glitch. Just have a lil' pixelexia...


« Reply #9 - Posted 2013-01-09 04:16:11 »

There is another way to get files from a .jar...

1  
2  
3  
4  
5  
6  
7  
8  
9  
File newFile = null;
URL tempURL = getClass().getResource("/"+filename);
if(tempURL != null){
      try {
                newFile = new File(tempURL.toURI());
      } catch (URISyntaxException ex) {
               System.err.println("File Resource Error! "+filename);
      }
}


EDIT: ninja'd...

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline nhmllr

Senior Devvie


Medals: 1
Projects: 3


slow and steady...


« Reply #10 - Posted 2013-01-09 04:19:19 »

Shouldn't the "getClass()" method be called from an object? How is it just floating there?

"Cannot make a static reference to the non-static method getClass() from the type Object"
?

EDIT: OOOH Because I'm calling the method statically.... hmm...
Offline nhmllr

Senior Devvie


Medals: 1
Projects: 3


slow and steady...


« Reply #11 - Posted 2013-01-09 04:36:17 »

Hrmm... even when I call this method non-statically it doesn't work. I'm not gonna lie, I have no idea what any of this is or why it isn't working.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
public void playMidi1(Song song){
      String filename = "res/music/"+song.name+".mid";
      File newFile = null;
      URL tempURL = getClass().getResource(filename);
      if(tempURL != null){
            try {
                      newFile = new File(tempURL.toURI());
            } catch (URISyntaxException ex) {
                     System.err.println("File Resource Error! "+filename);
            }
      }
     
      try {
         midiPlayer = MidiSystem.getSequencer();
         midiPlayer.setSequence(MidiSystem.getSequence(newFile));
         midiPlayer.open();
         midiPlayer.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
         midiPlayer.start();
         
         currentSong = song;
        } catch (MidiUnavailableException ex) {
           System.err.println("Midi Unavailable! "+ex.toString());
        } catch (InvalidMidiDataException ex) {
           System.err.println("Midi Invalid! "+ex.toString());
        } catch (IOException ex) {
           System.err.println("File Not Found! "+ex.toString());
           Sound.shotFail.play();
        }
   }


I'm not butchering the order of code or anything, am I? The resource is always null
Offline SHC
« Reply #12 - Posted 2013-01-09 04:41:15 »

Try this
1  
URL tempURL = getClass().getClassLoader().getResource(filename);

instead of
1  
URL tempURL = getClass().getResource(filename);

Offline nhmllr

Senior Devvie


Medals: 1
Projects: 3


slow and steady...


« Reply #13 - Posted 2013-01-09 04:49:25 »

Err... didn't work. Somebody commented about saving it in the root of the project? I'm not sure what this means and I wasn't able to figure it out with google, probably because I wasn't using the right key words. Is this music folder in the root?
Offline zngga
« Reply #14 - Posted 2013-01-09 04:52:26 »

This might not help at all, as you said the images loaded fine, just not the midis; but...

Did you add your res folder as a class folder? (java build path, libraries, add class folder)

Did you tell eclipse to export your res folder to the jar? (java build path, order and export, check res folder)

Finally did you tell eclipse to bundle libraries with your jar when it generated it? If not users would need your jar file, plus a resources folder in the same directory.

Like I said, might not help (or you already did these) just didn't want something simple to be overlooked on accident.

My code never has bugs... it just develops unexpected features!
Offline SHC
« Reply #15 - Posted 2013-01-09 04:58:43 »

Instead of using a folder, make it a package and add drag the resources into the package and delete the folder. Like in this image.


Offline nhmllr

Senior Devvie


Medals: 1
Projects: 3


slow and steady...


« Reply #16 - Posted 2013-01-09 05:00:12 »

I've done all of those, except for the class folder. But when I do that, I get this:

So I'm not sure that's the problem
Offline SHC
« Reply #17 - Posted 2013-01-09 05:02:00 »

Make it like in the image i've shown. Then the class loader loads it well. Dont use class folders.

Offline nhmllr

Senior Devvie


Medals: 1
Projects: 3


slow and steady...


« Reply #18 - Posted 2013-01-09 05:06:46 »

I cannot make it like the image you've shown, I can't put a package in a package. Maybe my version of eclipse is just old.

However, when I do this:


and make the filename this:
1  
      String filename = "src/music/"+song.name+".mid";


It still says the URL is null
Offline SHC
« Reply #19 - Posted 2013-01-09 05:08:20 »

Just click the src folder and create a package with name res.

Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #20 - Posted 2013-01-09 05:11:01 »

Oh my god so much misinformation and confusion in this thread. I will attempt to solve them all.

Using this image as what your current setup:


You load by doing <classname>.class.getClassLoader().getResource("level/.....")

If you put the "res" folder under the "src" folder, then you begin by "res/level/...."

The getResource method returns a URL. DO NOT convert this to a URI and give it to a File object. It won't work.

Give the URL directly to whatever you are loading.

Offline nhmllr

Senior Devvie


Medals: 1
Projects: 3


slow and steady...


« Reply #21 - Posted 2013-01-09 05:44:32 »

YYYYYYYYYYYEEEEEEEEEEEEEEEEEEEEEEEEESSSSSSSSSSSSSSSSSSSSSS!

The working code, for those interested:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
public static void playMidi(Song song){
      String filename = "/music/"+song.name+".mid";
      URL tempURL = MusicPlayer.class.getResource(filename);
     
      try {
         midiPlayer = MidiSystem.getSequencer();
         midiPlayer.setSequence(MidiSystem.getSequence(tempURL));
         midiPlayer.open();
         midiPlayer.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
         midiPlayer.start();
         
         currentSong = song;
        } catch (MidiUnavailableException ex) {
           System.err.println("Midi Unavailable! "+ex.toString());
        } catch (InvalidMidiDataException ex) {
           System.err.println("Midi Invalid! "+ex.toString());
        } catch (IOException ex) {
           System.err.println("File Not Found! "+ex.toString());
        }
   }


I realized that the "MusicPlayer.class.getResource" was the way to go. I dunno why those other methods weren't working, but they weren't, so that's that. I was looking over my working texture loading code I wrote months ago and saw that "getResource()" worked there so I tried it here and it's glorious.


Thank you to all to all who responded! Couldn't have done it without you! What a confusing mess, truly one for the ages.
Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #22 - Posted 2013-01-09 06:03:11 »

It's not that confusing really. It's just so many people here are misinformed. Resource loading is very simple if you understand how the methods work.

Also the difference between getResource(String) and getClassLoader().getResource(String) is that the String you pass to getResource(String) begins with a forward slash, like in your example, it removes the forward slash and calls getClassLoader().getResource(String) so it's much more efficient to directly call getClassLoader().getResource(String) without a leading forward slash.

Offline Sparky83

Senior Devvie


Medals: 6
Projects: 1



« Reply #23 - Posted 2013-01-09 07:36:36 »

Is there any article or tutorial about this topic anywhere? Maybe a chapter in a book? I had nearly the same problem yesterday with resources not being loaded and it took me one hour to get it working. What a waste of time. I don't have the feeling though that I actually know what I am doing. But I didn't find any place in the depths of the internet where someone took the time and had the knowledge to explain these things. It seems to be like in this thread: everyone says "do it this way, it works for me... at least it should" but there is no background to why it should work and how it does.
And maybe even more important: why other methods that don't work in this case might be used in other cases too.
Offline Cero
« Reply #24 - Posted 2013-01-09 13:59:05 »

I never ever used the "class.getResource" method in my life ever
and assets do no belong into the src folder in my eyes, and fortunately libgdx agrees.

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Mr.CodeIt (24 views)
2014-12-23 03:34:11

rwatson462 (55 views)
2014-12-15 09:26:44

Mr.CodeIt (45 views)
2014-12-14 19:50:38

BurntPizza (89 views)
2014-12-09 22:41:13

BurntPizza (112 views)
2014-12-08 04:46:31

JscottyBieshaar (83 views)
2014-12-05 12:39:02

SHC (92 views)
2014-12-03 16:27:13

CopyableCougar4 (100 views)
2014-11-29 21:32:03

toopeicgaming1999 (160 views)
2014-11-26 15:22:04

toopeicgaming1999 (159 views)
2014-11-26 15:20:36
Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!