Export resource in jar file - java

I have a problem to export my Jframe app with the background resource into jar file (without any external resource folder. I prefer to have everything into jar file for better portability).
Here's the code. On Eclipse all work correctly, but when I export into jar file the app doesn't load because the resource "cccc.jpg" is not found.
I have already tried the getResource() but it didn't work as well.
// Load Background image
BufferedImage img = null;
try {
img = ImageIO.read(new File("cccc.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
// Set Background image
Image dimg = img.getScaledInstance(640, 480, Image.SCALE_SMOOTH);
ImageIcon imageIcon = new ImageIcon(dimg);
setContentPane(new JLabel(imageIcon));

like
BufferedImage bufferedImage = ImageIO.read(MyClass.class.getResource("/images/cccc.jpg"));
see: Loading image from a resource Can't read input file

Saying that your code works in ecplise is a hint that you have located the "cccc.jpg" file in the root of your project folder (this is the current folder when you run the application or a unit test within eclipse).
For having the file packed as resource into your jar: simply put it somewher into your source folder. If you have your source packages named like "my.app.main" you could place your image file directly beside the your "my" folder and load it by:
InputStream is = ClassLoader.getSystemResourceAsStream( "cccc.jpg" )
Or place it into a sub package (e.g. "my.app.images") and load it by:
InputStream is = ClassLoader.getSystemResourceAsStream( "my/app/images/cccc.jpg" )
BTW: ImageIO.read can also take an InputStream as parameter.

I solved the problem. Now everything is loaded correctly when I open the jar file.
Link to the picture of the problem solved

Related

When exporting project to a runnable JAR, I am unable to access the resources files [duplicate]

I have a Java project with a toolbar, and the toolbar has icons on it. These icons are stored in a folder called resources/, so for example the path might be "resources/icon1.png". This folder is located in my src directory, so when it is compiled the folder is copied into bin/
I'm using the following code to access the resources.
protected AbstractButton makeToolbarButton(String imageName, String actionCommand, String toolTipText,
String altText, boolean toggleButton) {
String imgLocation = imageName;
InputStream imageStream = getClass().getResourceAsStream(imgLocation);
AbstractButton button;
if (toggleButton)
button = new JToggleButton();
else
button = new JButton();
button.setActionCommand(actionCommand);
button.setToolTipText(toolTipText);
button.addActionListener(listenerClass);
if (imageStream != null) { // image found
try {
byte abyte0[] = new byte[imageStream.available()];
imageStream.read(abyte0);
(button).setIcon(new ImageIcon(Toolkit.getDefaultToolkit().createImage(abyte0)));
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
imageStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} else { // no image found
(button).setText(altText);
System.err.println("Resource not found: " + imgLocation);
}
return button;
}
(imageName will be "resources/icon1.png" etc). This works fine when run in Eclipse. However, when I export a runnable JAR from Eclipse, the icons are not found.
I opened the JAR file and the resources folder is there. I've tried everything, moving the folder, altering the JAR file etc, but I cannot get the icons to show up.
Does anyone know what I'm doing wrong?
(As a side question, is there any file monitor that can work with JAR files? When path problems arise I usually just open FileMon to see what's going on, but it just shows up as accessing the JAR file in this case)
Thank you.
I see two problems with your code:
getClass().getResourceAsStream(imgLocation);
This assumes that the image file is in the same folder as the .class file of the class this code is from, not in a separate resources folder. Try this instead:
getClass().getClassLoader().getResourceAsStream("resources/"+imgLocation);
Another problem:
byte abyte0[] = new byte[imageStream.available()];
The method InputStream.available() does not return the total number of bytes in the stream! It returns the number of bytes available without blocking, which is often much less.
You have to write a loop to copy the bytes to a temporary ByteArrayOutputStream until the end of the stream is reached. Alternatively, use getResource() and the createImage() method that takes an URL parameter.
To load an image from a JAR resource use the following code:
Toolkit tk = Toolkit.getDefaultToolkit();
URL url = getClass().getResource("path/to/img.png");
Image img = tk.createImage(url);
tk.prepareImage(img, -1, -1, null);
The section from the Swing tutorial on How to Use Icons shows you how to create a URL and read the Icon in two statements.
For example in a NetBeans project, create a resources folder in the src folder. Put your images (jpg, ...) in there.
Whether you use ImageIO or Toolkit (including getResource), you must include a leading / in your path to the image file:
Image image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/resources/agfa_icon.jpg"));
setIconImage(image);
If this code is inside your JFrame class, the image is added to the frame as an icon in your title bar.

Java: Null pointer when trying to set app icon

I'm trying to set an icon for my Java app, with the image being in assets/images.
Setting it as so:
java.net.URL url = ClassLoader.getSystemResource("assets/images/ravens.jpg");
Toolkit kit = Toolkit.getDefaultToolkit();
Image img = kit.createImage(url);
frame.setIconImage(img);
Error I'm receiving:
Uncaught error fetching image:
java.lang.NullPointerException
at sun.awt.image.URLImageSource.getConnection(URLImageSource.java:115)
at sun.awt.image.URLImageSource.getDecoder(URLImageSource.java:125)
at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:263)
at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:205)
at sun.awt.image.ImageFetcher.run(ImageFetcher.java:169)
Any help would be appreciated!
There is a better way to do this without getting a NullPointerException by using a BufferedImage. I've tested this and it works. Replace your code with this:
BufferedImage img = null;
try {
img = ImageIO.read(new File("assets/images/ravens.jpg"));
} catch (IOException e) {}
frame.setIconImage(img);
Given what you've stated in your comments, your assets directory is at the same level as src, so something like
/project
/src
/assets
What you need to do to make this
java.net.URL url = ClassLoader.getSystemResource("assets/images/ravens.jpg");
work is to have assets/images/ravens.jpg be on the classpath.
Eclipse puts anything inside a source folder on the root of the classpath when running your app.
Therefore, create a folder resources (or whatever you want to call it), make it a source folder, and put assets in it. It should look like
/project
/src
/resources
/assets
/...
Now, assets will be at the root of the classpath and you can retrieve it with the code above.
Use:
setIconImage(new ImageIcon("assets/images/ravens.jpg").getImage());

Load image in jar, error in code

I want to reference an image in my project that I will package into a Jar file.
This code is not working:
ImageIcon image = new ImageIcon("Images/buttonBackgroundSelected.png");
Any ideas? thanks
This constructor only works if the image is available in the file system outside the JAR file
new ImageIcon("Images/buttonBackgroundSelected.png");
You almost never want to do this. You could use:
ImageIcon imageIcon =
new ImageIcon(getClass().getResource("/Images/buttonBackgroundSelected.png"));
when the folder and image and the have been included in the JAR file.
However, loading images this way fails silently if any issues loading the image. Therefore use ImageIO.read should be used:
Image image =
ImageIO.read(getClass().getResource("/Images/buttonBackgroundSelected.png"));
The resultant image can be wrapped in an ImageIcon if required.

Why won't my BufferedImage show in the .jar file?

Alright, so I have created a Buffered Image to display on a JLabel. When I display the File location, it requires a src/ in front of the folder I want to access, or else an error will arise and I will not see the Buffered Image... I know that if I put the 'src/' in front of the resImg, the BufferedImage will not display outside of the IDE. Can anyone help?
This is the code that works inside of the IDE. When running outside from the .jar file, the image doesn't display.
static File f = new File("src/resImg/banner.png");
try {
banner = ImageIO.read(f);
picLabel = new JLabel(new ImageIcon(banner));
LabelPanel.add(picLabel);
} catch (IOException ex) {
Logger.getLogger(GameStart.class.getName()).log(Level.SEVERE, null, ex);
}
When the resource is in a jar file, it isn't a file on the local file system. You should use
URL imageSource = getClass().getResource("/resImg/banner.png");
if (imageSource == null) {
// Handle the resource being missing
}
picLabel = new JLabel(new ImageIcon(imageSource));
Here you're fetching the resources from the classloader, which will obviously have access to the files in your jar file.
If you want get image from jar, use smth like this:
URL imageurl = getClass().getResource("/images/imagename");
You cannot create a File object for a resource in the JAR file. Use this instead.
URL imgurl = this.getClass().getClassLoader().getResource("resImg/banner.png");
picLabel - new JLabel(new ImageIcon(imgurl));
Hope this helps.
You have to find a parent directory, the relativ path can start from like
workspace directory
directory the process starts
the relativ path is "realtiv" from where the java process is started from, so the path can change from time to time.
If the picture is placed in the jar, you can use
getClass().getResource("relativ jar path")
for finding the image. the jar itself knows, where it is placed.
Most probable cause is that your image is not packed inside jar file ( verify this with jar / zip tool ).
If image is there but does not display, it is because you trying to read this from file system relative to working directory ( and it is certainly not there )
So, proper solution would be to read image from class path:
Thread.currentThread().getContextClassloader().getResourceAsStream(... path to your image relative to jar root ---)

Cannot find the image in the java dynamic web project

I have the following problem:
I created the servlet which should draw a dynamic graph. During the drawing process it should fetch the picture from another directory and to draw it upon another image. Everything should work fine:
try {
BufferedImage temp = ImageIO.read(new File("image/arrow.png"));
tempIm = temp.getScaledInstance(55, 55, Image.SCALE_SMOOTH);
} catch (IOException e) {
e.printStackTrace();
}
But it prints the following:
SEVERE: javax.imageio.IIOException: Can't read input file!
at javax.imageio.ImageIO.read(ImageIO.java:1275)
at CertificateDraw.doGet(CertificateDraw.java:36)
I tried to change the path of the File object in all possible ways it just gives the same problem even though the part of the image is still sent to the browser. So the problem is with the ImageIO.read part - how can I find why it does not load the image?!
I am working in Eclipse - servlet is in the src folder. The image is in "image" folder under the rot directory "WebContent".
Relative paths in java.io.File are relative to the current working directory (CWD). This is the folder which is currently opened when the command is given to start the Java runtime environment (in your case, the webserver). When starting the server in Eclipse, this is usually the /bin folder of the project. You can figure this by printing new File(".").getAbsolutePath().
But you shouldn't be relying on relative paths in File at all. The CWD is not controllable from inside the code.
As it's in the webcontent folder already, just get it by ServletContext#getResourceAsStream() instead.
InputStream input = getServletContext().getResourceAsStream("/image/arrow.png");
BufferedImage image = ImageIO.read(input);
// ...
Note that the getServletContext() is inherited from the GenericServlet class which the HttpServlet extends from, so you don't need to provide the method yourself.

Categories