Java Load From Reasource In Jar - java

I am having some difficulty loading files from resources in eclipse. In the IDE, loading works fine. In a compiled jar everything breaks.
This works for loading an image inside and outside of a jar:
ImageIO.read(this.getClass().getResourceAsStream("E.png"))
This works only in the IDE for a file object (I know it's messy):
File f = new File(Thread.currentThread().getContextClassLoader().getResource("Overworld.mp3").getPath().replace("%20", " "));
I was hoping that there was a constructor for a file object File(InputStream) so I could use the first method of loading an image (which works flawlessly so far) for a file. This, however doesn't exist.
Is there any other method of loading a file into a file object in such a way that it works in the IDE and in a compiled jar?
Thanks in advance.
(Separate but related question: why does File f = new File(this.getClass().getResource("Overworld.mp3").getFile()); give a MEDIA_UNAVAILABLE exception? The file is in the same package as "E.png" with all other source files in my project)

getResourceAsStream() returns a java.io.InputStream that you can use to read the contents of a resource in a jar as a byte array.
Will this work for you?
Why do you require a java.io.File?

Another way to load resource that placed with your class/jar.
URL url = getClass().getClassLoader().getResourceAsStream(filePath);

Related

Images not loading after creating Jar

im wring a simple program and my images load in fine in the project but as soon as i export it into a jar file none of them load. i have little to no experiance creating artifacts or jar files.
project structure:
project:
src:
myclass1, myclass2...
res:
image1.png image2.png...
im using Toolkit.getdefaultToolkit to load in images
in my class i am loading the images in the constructor by writing
myImage = toolkit.getImage("res/image1.png");
this works perfectly fine in the project. does not work in the jar
i have also tried
myImage = toolKit.getImage("image1.png");
which does not work in the project or while opening the jar
i know toolkit is not the best way to go about loading images but i would like to know how i can fix this issue while using toolkit.
ive even tried using the absolute path to a folder on my desktop and once again they load in fine in my project but they do not get loaded when opening the jar. please help ive tried everything. thanks
(btw) if i open the jar file in intellij the images load but if i open the jar file in finder or from my desktop they do not. i want to be able to send the finished project to someone
The toolkit.createImage(String) method takes in a string, and interprets it as a path, looking for a file at that path. An entry in a jar file is not itself a file. It is therefore impossible to use this method to read image files that are in a jar.
However, that's not the only createImage method. There's also toolkit.createImage(URL) and that is the one you want.
SomeClass.class.getResource("something.png")
This expression works on any class (Foo.class gets you the class instance for Foo, and all class instances have the getResource method), and will look for the named entry in the exact same place SomeClass.class (the file) lives. If SomeClass.class currently lives in a jar file, then that's where it'll look.
Thus, ensure that img.png is in the same place your class file is (ensure it is jarred along with the rest), and that will work. You can also ask for e.g. SomeClass.class.getResource("/foo/bar/img.png"); this will then look from the 'root' of where SomeClass is. So if you have a jar such that if you run jar tvf thatjar.jar and you get:
....
/com/foo/yourpackage/SomeClass.class
....
/foo/bar/img.png
then /foo/bar/img.png works.
thus: Once you know where you put that stuff in your jar file:
toolkit.createImage(YourClass.class.getResource("image1.png"))
is what you're looking for.

Getting location of file as string in resource folder

I have completed a program in eclipse and now I would like to export it as a single runnable jar file. The program contains a resource folder with images and text files in it. This is located beneath the source folder.
The res file is not added to the build path however when I run the program in Eclipse it still works.
The thing that is confusing me is that the res file is being saved into the runnable jar file when I export it as I can open the Jar file with WinRar and I see the folder is there with all the objects in it. But when I run the problem it stops at the point that the resource folder is referenced. To add to my confusion when I manually copy and paste the res folder next to where the runnable jar file is saved and run the program it works exactly as it should do.
Now I know this is something to do with how I reference the files in my code. At the moment I have it like this
reader = new LineNumberReader(new FileReader("res/usernames.txt"));
This works exactly how I want and accesses the res folder without any exceptions - in Eclipse and when I move the resource folder next to the Jar file.
I would like it to work normally but without having a folder outside of the Jar file I would like it all encapsulated in one Jar file.
I did a lot of research and what seems to be a common fix - may I add I don't really know how it works but everyone seems to mention it - is to somewhere use:
myClass().getResource()
When I create a new FileReader it needs a String input however when I use myClass().getResource() it returns a resource and not a string. I also don't have a clue how it is meant to reference the resource folder. Should I move the resource folder into the source folder?
Does anyone know how I can reference the resource folder from within the runnable jar file?
Sorry for rambling question I know what I want for my final product but I'm getting confused by the build paths and referencing from within classes and I have searched online for a long time trying to figure it out.
Resources, when you deploy your software, are not deployed as files in a folder. They are packaged as part of the jar of your application. And you access them by retrieving them from inside the jar. The class loader knows how to retrieve stuff from the jar, and therefore you use your class's class loader to get the information.
This means you cannot use things like FileReader on them, or anything else that expects a file. The resources are not files anymore. They are bundles of bytes sitting inside the jar which only the class loader knows how to retrieve.
If the resources are things like images etc., that can be used by java classes that know how to access resource URLs (that is, get the data from the jar when they are given its location in the jar), you can use the ClassLoader.getResource(String) method to get the URL and pass it to the class that handles them.
If you have anything you want to do directly with the data in the resource, which you would usually do by reading it from a file, you can instead use the method ClassLoader.getResourceAsStream(String).
This method returns an InputStream, which you can use like any other InputStream - apply a Reader to it or something like that.
So you can change your code to something like:
InputStream is = myClass().getResourceAsStream("res/usernames.txt");
reader = new LineNumberReader( new InputStreamReader(is) );
Note that I used the getResourceAsStream() method from Class rather than ClassLoader. There is a little difference in the way the two versions look for the resource inside the jar. Please read the relevant documentation for Class and ClassLoader.

Problems with loading CLP file from JAR

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.

putting picture in java program using MyEclipse GUI

I want to add a picture to my GUI program created using Eclipse and MyEclipse (for GUI visual design) from the resource pictures I pasted earlier in the project.
I managed to load pictures that lies just beside the .JAR file using
image = ImageIO.read(new File("imageFile.jpg"));
But I want to use the image from my resources "src" folder directly , so that the .JAR file is a standalone file yet loads pictures nicely.
I tried to make it
image = ImageIO.read(new File("src/ldtlogo3.jpg"));
I use this method when exporting the .JAR file
Java: export to an .jar file in eclipse
Use the overloaded ImageIO.read method taking an InputStream as a parameter, and use MyClass.class.getResourceAsStream() to get this input stream. getResourceAsStream loads a resource from the classpath (and thus from the JAR of your application). Its api doc will tell you which path it expects.
Note that the src directory is used to hold your Java source files. The jar doesn't contain it. It contains the .class files, in a hierarchy which directly maps the package hierarchy. Eclipse will automatically "compile" the image file by copying to the output directory, along with the .class files.

Images will not work in a .jar file

When a JAR of an application is created, the images in the application no longer appear. An example of our code for loading images is:
ImageIcon placeHolder = new ImageIcon("src\\Cards\\hidden.png");
We have no idea why this is happening. The application runs as expected if we do not compress it to a JAR; as a JAR, the images simply disappear. We also tried using URLs instead of ImageIcons, but that just causes the program not to run at all.
Any ideas?
EDIT: We are putting the image files into our JAR file in the correct paths, so that's not the problem.
Check the API for the constructor you're calling. The string you pass in is a file path - when the resources are packaged in a JAR, there is no file on the filesystem containing the image, so you can't use this constructor any more.
Instead you'd need to load the resources from a stream, using the classloader, and pull them into a byte array:
byte[] buffer = new byte[IMAGE_MAX_SIZE];
InputStream imageStream = getClassLoader().getResourceAsStream("src\Cards\hidden.png");
imageStream.read(buffer, 0, IMAGE_MAX_SIZE);
ImageIcon placeHolder = new ImageIcon(buffer);
Needs more exception and edge-case handling, of course, but that's the gist of it.
You should load resources from the classpath as such:
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("Cards/hidden.png")
This of course assumes that when you create the JAR, you are actually putting the image files into it.
There is also a method for getting the resource as a URL.
Question: Does the folder src exist in the jar?
Tip: You can open .jar with any unpacking program which supports ZIP to see its contents.
Answer: The way you reference the resource is incorrect, you should do something like getClass().getClassLoader().getResource("Cards/hidden.png") instead.

Categories