After looking at a couple of audio libraries, I settled on EasyOgg. Most of the samples report that you play sounds like this:
new OggClip("mysfx.ogg").loop();
This crashes with Couldn't find: mysfx.ogg at runtime. I tried several things:
Plain filename
Relative path from my project root directory
Forward-slashes and backslashes
I can't figure out where exactly the file goes, and how to specify the name. It seems like they should be somehow embedded in my application JAR. (I just have them sitting on the file system.)
I fiddled around with it for a while and came up with a solution using InputStreams:
FileInputStream stream = new FileInputStream("file.ogg");
OggClip clip = new OggClip(stream);
This works without including the files in the jar.
I'm not familiar with EasyOgg, but the first thing I would do is pass in the complete location to the file as a sanity check.
new OggClip("/home/someuser/audio/mysfx.ogg").loop();
If you can't count on java being run from the same location every time, you can use an environment variable to point to the location that your files are sitting in.
new OggClip(System.getenv("MY_APP_HOME") + "/audio/mysfx.ogg").loop();
As far as getting to a resource from inside a jar file, have you tried getResource()?
See: Access file in jar file?
I discovered that the OGG files need to be in the JAR file. This is clear from the working zip samples I found on the interwebz.
To use Gradle to zip up every .ogg file in audio, I add this to my jar task:
from fileTree(dir: '.', include: 'audio/**/*.ogg')
This works, except when I debug from Eclipse. A better solution is to create a separate project (I called mine EmbeddedResources) which creates a JAR that only contains .ogg files. Then, I reference this project from my game project, and I'm done.
Related
I tried to create an InputStream pointing at an .ico file, which is in a directory in the src directory. I also create an InputStream for a different jar file in my src.
InputStream inIco = Installer.class.getResourceAsStream("/res/" + iconName + ".ico");
InputStream inApp = Installer.class.getResourceAsStream("/res/" + applicationName + ".jar");
that is how I tried to load it. The inputstream for the jar file works, but the other one is null.
Edit: Sorry for the confusion guys. I didn't build the jar, I just ran it from my editor, which obviously gives me different results, now it is working. Thanks for your answers.
getResourceAsStream (gRAS) loads from the same place java loads class files. That's great - it means you can ship your app as a jar and put these resources inside. If it's not working for you, you've misconfigured your build. Specifically, java is first going to determine the classpath root of your Installer.class file and looks there. If you're not sure what that is, run this code:
System.out.println(Installer.class.getResource("Installer.class"));
which will print something like jar:file:/Users/carlos/projects/FooBar/dist/foobar.jar!com/foo/Installer.class
and this tells you that gRAS is going to look in that foobar.jar file.
From there, the resource is loaded relatively to the root (because of that leading slash): Within that jar, it will look for /res/app.ico. Without it, it loads relative to the same dir/package of Installer class (in this example above, gRAS("hello.txt") is the same as gRAS("/com/foo/hello.txt").
To make this work out, your build system is responsible. For maven and gradle, have src/main/java/com/foo/Installer.java along with src/main/resources/res/icon.ico and all should be well. If this is not working out, explain how you've set up your environment because something is misconfigured if this isn't working. If you're using another build tool (such as perhaps ant, sbt, or relying on your IDE to take care of it), name the tool and perhaps we can help address the misconfiguration.
I made a small Java program for academic purposes, its main focus is to read some .txt files and present the information to the user. These files are present in the resources folder, under the src folder.
The program runs as intended when launched from Eclipse.
Using the Launch4j app I was able to successfully create an exe which runs fine and does what's intended, up until I try to read the .txt files I have in the resources folder, which appears not to be able to reach.
I'm guessing that when I launch the exe the run time path would change to where the exe was created, so I created the program in a desktop folder and specified this path in the program, but that doesn't seem to solve the situation.
As an alternative, I moved the .txt files out of the program and once again created the exe in a desktop folder with said .txt files, linked the program to this path and once again it didn't work.
The command used to get the .txt files is:
Files.readAllLines(Paths.get(doc)).get(line)
And doc is simply the path to the intended .txt file.
It's worth noting that I have no previous experience in Java and throughout the development of the program I tried my best to use commands I'd fully understand and to keep it as simple as possible. I hope the solution can be along these lines! I'm very confident this must be a rookie mistake, but I can't seem to find the solution to this specific problem anywhere.
The paths to files in Eclipse are different than the paths to files in an .exe or JAR file.
I will let this other user explain it because I am lazy :p
Rather than trying to address the resource as a File just ask the
ClassLoader to return an InputStream for the resource instead via
getResourceAsStream:
InputStream in = getClass().getResourceAsStream("/file.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
As long as the file.txt resource is available on the classpath then
this approach will work the same way regardless of whether the
file.txt resource is in a classes/ directory or inside a jar.
The URI is not hierarchical occurs because the URI for a resource
within a jar file is going to look something like this:
file:/example.jar!/file.txt. You cannot read the entries within a jar
(a zip file) like it was a plain old File.
This is explained well by the answers to:
How do I read a resource file from a Java jar file?
Java Jar file: use resource errors: URI is not hierarchical
The original post is here, all credit to its author.
Fixing your URL should let you read from that file when you are using the .exe.
EDITED FOR CORRECTION. Thanks #VGR (see comments) for correcting my mistake.
I am doing some algorithmic problems on the website USACO, and for every submission they want us to make two files for input and output to test values. So if the problem was called "test", they would want users to make the files "test.in" and "test.out" which requires them to change their extensions to ".out" and ".in". How do I change their extensions from ".txt" to ".in" or ".out"?
Note: I am using Windows 8
Thank you
To make Java read files in Eclipse
One must make sure that the words typed in the code and in the name of the file match each other.
For example: The file referenced in must exist.
BufferedReader f = new BufferedReader(new FileReader("test.in"));
Also, you have to make the file under the project folder (in Eclipse or manually in Windows Explorer) because that folder is the directory at for that code, and if it is not in the folder the code will not be able to read it. You can also right-click the project to import files into the folder.
My reference: Trial and Error
http://www.coderanch.com/t/439615/java-io/java/Eclipse-won-read-text-file
I've managed to make resources finally get into the jar by using a class with inputstream getting resources from the class, and also adding the images and sounds to a folder within the project directory in eclipse and adding it to the buildpath.
With this images finally run from the within the jar. The same code using AudioinputStream instead of image.io works within the ide when you click run.
But from the jar file there are no sounds.
Here's the code in question
AudioInputStream audioIntStream = AudioSystem.getAudioInputStream(
Resourceloader.load("images/engine.wav"));
Clip clip = AudioSystem.getClip();
clip.open(audioIntStream);
clip.loop(Clip.LOOP_CONTINUOUSLY);
title = ImageIO.read(Resourceloader.load("images/title.png") );
The images files from the same directory read from both ide and jar, while as said the audio file only runs from within ide not jar yet jar contains audiofile
Resource loading in Java can be complicated. However, the following code snippet is almost always what you want:
Thread.currentThread().getContextClassLoader.getResourceAsStream(
"path/to/resource/from/jar/root.file");
I use that snippet so often that I could type it in my sleep. I'd adjust your code above to use it to load your resources. However, if that doesn't cut it, I'd look into the following:
Check the resources after loading, and throw an Exception if they're null.
Open up your JAR as a ZIP file and ensure that the resource is actually at the path you have listed in your code, starting from the root of the JAR.
Use Ant or Maven to build your JAR, rather than Eclipse's GUI. This will help ensure that your JAR is always built in the same way and reduces the chances for manual mistakes. Using Maven and the standard Maven src/main/resources/ directory is highly recommended.
I am using CLIPSJNI.
What I have is:
Environment clips = new Environment();
clips.load("main.clp");
where main.clp is put in the same level as src and bin folder.
This runs fine in Eclipse. However when I export to JAR. It cannot work.
I understand that there are some problems with the path when we export to JAR.
So I've seen people suggesting using this.getClass().getResourceStream() but this is not the case. Because what I need is the name of the file, not its content.
Any suggestions on how to fix this?
The issue is that the load is being done within the native library on the C side which is being passed a file name as an argument. The C code has no concept of a JAR file or how to extract files embedded within one. I think what you would need to do is always place your .clp files within the JAR file and then have a routine which extracts the data from the JAR file and saves it to a file. You can then load it using the load method and delete the file once done.