I am a new programmer to Java. I have a made a small Directory Application that I would like to export, but for some reason, whenever I try to export it to a runnable jar file, the result doesn't contain any of the images I specified within my program. Basically, I ran it in eclipse, and it worked fine, but when I ran it as an runnable JAR, it has no images. I have 5 .java files that are all bundled with eachother. My Images are found at Images/Image.png [I already made The Images folder a source folder.]
I have tried eveything, but for some reason i can't get it to work, if you have any knowledge on the topic, please tell me. I don't know if its because I'm a noob or something I'm doing wrong.
static ImageIcon logoicon = new ImageIcon("Images/Logo.png");
Here is the method I use:
public static ImageIcon createImageIcon(final String path) {
InputStream is = ImageLoader.class.getResourceAsStream(path);
int length;
try {
length = is.available();
byte[] data = new byte[length];
is.read(data);
is.close();
ImageIcon ii = new ImageIcon(data);
return ii;
} catch (IOException e) {
LogManager.logCriticalProblem("Image not found at {} - {}", new Object[]{path, e.getMessage()});
}
return null;
}
If you have problems with this method, try altering the path you're using:
"Images/Logo.png"
"/Images/Logo.png"
"src/Images/Logo.png"
"/src/Images/Logo.png"
Or other combinations depending on your package structure. For example, if your images are actually in net.blah.fizz.Images, your path would be "/net/blah/fizz/Images/image.png"
Did you try getResourceAsStream() method ? Checkout this page for more information
Related
I have my program in a JAR file, and some files in a folder in the same directory. After hours of searching I found some code that allowed me to list the files inside that folder (since File.listFiles() didn't work), but now readObject() gives me IOException. It works fine when I run it from the IDE or with cmd. It only throws the exception when running the JAR via double click.
Here's what I'm doing:
public static Template[] loadTemplates() throws IOException, ClassNotFoundException {
Path dirtemp = Paths.get(path.toString(), TEMPLATE_PATH);
DirectoryStream<Path> dirStream = Files.newDirectoryStream(dirtemp);
ArrayList<File> files = new ArrayList<>();
for (Path entry: dirStream) {
files.add(entry.toFile());
}
if (files.size() != 0) {
ArrayList<Template> templates = new ArrayList<>();
for (File file: files) {
FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
Object object = ois.readObject();
if (object instanceof Template) {
templates.add((Template) object);
}
ois.close();
fis.close();
}
Collections.sort(templates);
return templates.toArray(new Template[0]);
} else return null;
}
TEMPLATE_PATH is just a string that contains the name of the folder with the files.
path is a static variable inside my class that contains the current path to the JAR. I initialize it from the main method, since the location is not intended to change. Here's the code that I used to get it, if relevant:
public static void findJARPath() {
final Class<?> referenceClass = Main.class;
final URL url =
referenceClass.getProtectionDomain().getCodeSource().getLocation();
try {
final File jarPath = new File(url.toURI()).getParentFile();
path = Paths.get(jarPath.toURI());
} catch(final URISyntaxException ignored){}
}
Does anyone know why this happens?
I'm running on Windows but I want this to run on different OS as well. I'd appreciate if you pointed out if any of this code is not portable, too.
Edit:
The stack trace of the exception:
javax.swing.ImageIcon local class incompatible: stream class desc serialVersionUID = -962022720109015502, local class serialVersionUID = 532615968316031794
java.base/java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:689)
java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1903)
java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1772)
java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2060)
java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
java.base/java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2355)
java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2249)
java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2087)
java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:430)
Data.FileManager.loadTemplates(FileManager.java:108)
The code that writes the files:
public static void saveTemplate(Template template) {
new File(TEMPLATE_PATH).mkdir();
String filename = StringUtils.toFilename(template.getName(), "templ");
try {
FileOutputStream fos = new FileOutputStream(TEMPLATE_PATH + filename);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(template);
oos.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Edit: Figured it out. Apparently, for whatever reason, the ImageIcon UID from the image in my template class wouldn't match when running the jar via double click. Wrapping the image into another class with a fixed UID solved it.
Your plan defeats itself, of course: "The same directory as my jar file" would obviously contain..... your jar file.
Which will crash if you attempt to read it with an OIS. Apply some filtering as you dirstream through this directory. Does it have the right extension? Is it an actual file (vs. a directory)?
Also, your code has a memory leak; dirstreams are resources, as is a FileInputStream. You must close these. The only safe way to do so is with try/finally or try-with-resources. Search the web for "Java try with resources" if you're unfamiliar with these techniques.
You've saved a JDK11 ImageIcon, and are trying to deserialize it back on a VM that doesn't have that, because it has a JDK14 ImageIcon or whatnot.
More generally, you can't serialize anything if the intent is to allow it to deserialize on another system unless it is very carefully managed. ImageIcon by intent is not managed like that, therefore, you can't save ImageIcons with OIS and OOS. It looks like you can, but the caveat is: Breaks on different VMs.
You gotta toss all this code out and think of another way to serialize ImageIcon objects. Perhaps save the raw pixels, save it as a PNG, etc.
So we got this assignment in a basic java programming course and we're supposed to implement a kind of card deck. To help us with this they have given us resources that will present a GUI on the screen, but when running my program I get a IOException that says that it can't read the input file, most likely since the pathname is wrong. And I dont know how to fix it, we're not even supposed to be in meddling with this code. The error is thrown in this method:
private Image getImg(Card aCard) {
File pathToFile = null;
if (aCard == null) {
pathToFile = new File("cardset-oxymoron/shade.gif");
} else {
String suits = "cdhs";
char c = suits.charAt(aCard.getSuit());
String fileName = String.format("%s/%02d%c.gif", "cardset-oxymoron", aCard.getRank(), c);
pathToFile = new File(fileName);
}
Image img = null;
try {
img = ImageIO.read(pathToFile);
} catch (IOException ex) {
System.err.println("Failed to create image");
ex.printStackTrace();
}
return img;
}
And according to the error stack(?) it is at line 99, which is the
img = ImageIO.read(pathToFile);
line
The folder that the cards are in is inside the project folder, right in between bin and src. using IntelliJ debugger I can see that the the pathToFile is "cardset-oxymoron\02d.gif". The filename is correct as all the cards are "[01-13][c/d/h/s].gif". When I rightclicked and copied the path to the files inside IntelliJ it was using forwardsslashes and not backslashes. But then I checked in explorer and it was the other way around... I have no idea where this is going wrong, any input would be greatly appreciated!
According to your code your files are in directory cardset-oxymoron relative to your JVM run directory. I'm not sure about IntelliJ (I work all the time with Eclipse and Maven), but it could be bin directory.
You can check it by put those 2 lines to see what is it actually (somewhere before your actual code)
File currentDir = new File("./");
System.out.println(currentDir.getAbsolutePath());
Then your cardset-oxymoron must be in that directory. Or you can change file path appropriately.
E.g. if currentDir is bin then pathToFile will be
pathToFile = new File("../cardset-oxymoron/shade.gif");
as well as fileName for other case.
I'm trying to load an image from an executable JAR file.
I've followed the information from here, then the information from here.
This is the function to retrieve the images:
public static ImageIcon loadImage(String fileName, Object o) {
BufferedImage buff = null;
try {
buff = ImageIO.read(o.getClass().getResource(fileName));
// Also tried getResourceAsStream
} catch (IOException e) {
e.printStackTrace();
return null;
}
if (buff == null) {
System.out.println("Image Null");
return null;
}
return new ImageIcon(buff);
}
And this is how it's being called:
logo = FileConverter.loadImage("/pictures/Logo1.png", this);
JFrame.setIconImage(logo.getImage());
With this being a simple Object.
I'm also not getting a NullPointerException unless it is being masked by the UI.
I checked the JAR file and the image is at:
/pictures/Logo1.png
This current code works both in eclipse and when it's been exported to a JAR and run in a terminal, but doesn't work when the JAR is double clicked, in which case the icon is the default JFrame icon.
Thanks for you're help. It's probably only me missing something obvious.
I had a similar problem once, which turned out to be down to issues relative addressing and my path being in the wrong place somehow. I dug this out of some old code I wrote that made it use an absolute path. That seemed to fix my problem; maybe it will work for you.
String basePath = (new File(".")).getAbsolutePath();
basePath = basePath.substring(0, basePath.length()-1);
FileConverter.loadImage(basePath+"/pictures/Logo1.png", this);
public static void imRes(String pat) {
try {
BufferedImage bckimg = ImageIO.read(new File("c:/s/deneme.jpg"));
File s = new File(pat);
BufferedImage im = ImageIO.read(s);
BufferedImage im1 = resIm(im);
BufferedImage finIm = mergIm(im1, bckimg);
ImageIO.write(finIm, "jpg", new File("c:/s/deneme1.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
This is my first post, excuse me if I've done something wrong. This code was running properly untill i try to read an image from the source package. But now it can't read any image. What am I doing wrong? Or is it something about eclipse?
Exception:
javax.imageio.IIOException: Can't read input file!
at javax.imageio.ImageIO.read(Unknown Source)
at imRe.imRes(imRe.java:12)
at imReTest.main(imReTest.java:6)
Thanks...
Change / for \ if you are using windows.
A more cross-platform approach would be substitute
C: for File.listRoots()[0] and every / for File.separator.
Read more on the File api documentation
EDIT
(I didn't read this line, sorry)
This code was running properly untill i try to read an image from the source package
In order to get a file from inside your jar package, one must use the getClass().getResource() method.
Example:
application-package:
|-Main.java
|-resources
|-image.jpg
For the above directory structure:
BufferedImage im = ImageIO.read(new File(getClass().getResource("/resources/image.jpg").toURI()));
Would do the trick.
i'm trying to make a small project in java with no luck
if i'm compiling the program with eclipse everything is good, but when i'm i creating the jar file i get a blank window
this is the image i declared for:
public ImageIcon BACKGROUND = new ImageIcon() ;
I have tried to do the following stuff:
1.
new ImageIcon("Images/wood.jpg").getImage());
2.
this.BACKGROUND.setImage(Toolkit.getDefaultToolkit().getImage("Images/wood.jpg"));
3.
this.BACKGROUND = new ImageIcon(getClass().getResource("Images/wood.jpg"));
4.
/** Returns an ImageIcon, or null if the path was invalid. */
protected ImageIcon createImageIcon(String path,
String description) {
java.net.URL imgURL = getClass().getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL, description);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
1 & 2 showing the images after compiling and 3 & 4 returns null
another think is that i'm using mac and when i'm working with windows no image is displayed after compiling.
Here's a small working example if that helps:
public class ImageIconApplet extends JApplet {
public void init() {
URL url = getClass().getResource("/images/WhiteFang34.jpg");
ImageIcon icon = new ImageIcon(url);
JLabel label = new JLabel(icon, JLabel.CENTER);
add(label);
}
}
The jar for the applet on that page contains two files:
/com/whitefang34/ImageIconApplet.class
/images/WhiteFang34.jpg
I'm not sure if you're deploying an applet or a desktop swing app, however the code to load images and the packaging requirements are the same either way.
I have something...
ImageIcon icon = new ImageIcon(getClass().getResource("/package/image.png"));
JFrame.setIconImage(icon.getImage());
Place this inside your constructor.
Are you sure Images/wood.jpg is present in the .jar file?
I suggest you unzip the jar file and make sure that it's there. Otherwise you'll have to revise your build scripts (or what ever technique you use) that builds the jar.
Related questions:
adding non-code resources to jar file using Ant
Add image to JAR Java