Exporting image in runnable jar doesn't work - java

I'm having a weird problem in java. I want to create a runnable jar:
This is my only class:
public class Launcher {
public Launcher() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
String path = Launcher.class.getResource("/1.png").getFile();
File f = new File(path);
JOptionPane.showMessageDialog(null,Boolean.toString(f.exists()));
}
}
As you can see it just outputs if it can find the file or not. It works fine under eclipse (returns true). i've created a source folder resources with the image 1.png. (resource folder is added to source in build path)
As soon as I export the project to a runnable jar and launch it, it returns false.
I don't know why. Somebody has an idea?
Thanks in advance
edit: I followed example 2 to create the resources folder: Eclipse exported Runnable JAR not showing images

If you would like to load resources from your .jar file use getClass().getResource(). That returns a URL with correct path.
Image icon = ImageIO.read(getClass().getResource("imageĀ“s path"));
To access images in a jar, use Class.getResource().
I typically do something like this:
InputStream stream = MyClass.class.getResourceAsStream("Icon.png");
if(stream == null) {
throw new RuntimeException("Icon.png not found.");
}
try {
return ImageIO.read(stream);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
stream.close();
} catch(IOException e) { }
}
Still you're understand, Kindly go through this link.
Eclipse exported Runnable JAR not showing images

Because the image is not separate file but packed inside the .jar.
Use the code to create the image from stream
InputStream is=Launcher.class.getResourceAsStream("/1.png");
Image img=ImageIO.read(is);

try to use this to get image
InputStream input = getClass().getResourceAsStream("/your image path in jar");

Two Simple steps:
1 - Add the folder ( where the image is ) to Build Path;
2 - Use this:
InputStream url = this.getClass().getResourceAsStream("/load04.gif");
myImageView.setImage(new Image(url));

Related

ImageIO.read unable to find .png-file

sorry if this has been asked quite a few times, I'm new here.
I've used three different approaches to get a file to be loaded and nothing worked:
Using Toolkit:
Image image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("apple.png"));
Using a File:
BufferedImage img = null;
try {
img = ImageIO.read(new File("apple.png"));
} catch(IOException e) {
e.printStackTrace();
}
Using a FileInputStream:
Path path=Paths.get(".").toAbsolutePath().normalize();
String dir=path.toFile().getAbsolutePath()+"\\resources\\apple.png";
BufferedImage image = null;
try {
image = ImageIO.read(new FileInputStream(dir));
} catch(IOException e) {
e.printStackTrace();
}
path and dir are working fine getting me an absolute path but I alway end up with image = null.
/edit:
#DuncG: I don't get an exception so there's no stacktrace to post, sorry. new File("apple.png").exists() evaluates to false.
#Harald_K: It is a normal .png image-file I have on my local system. It is located in src/main/resources/apple.png.
The issue is that your program is NOT able to find the required file and then further read it as an Image. This is a common recurring problem statement in any modern-day app where a required resource is NOT found, halting subsequent operations.
I would suggest writing a common piece of code to always locate such files/resources in your project dir just by giving the filename and returning the path.
#Slf4j
public class PathFinder {
private static Path filepath;
public static Path getFilePathForFile(String filename) {
log.info("Looking for filepath for given filename: ".concat(filename));
try {
filepath = Files.walk(Paths.get("."))
.collect(Collectors.toList()).stream()
.filter(file -> !Files.isDirectory(file) &&
file.getFileName().toString().startsWith(filename))
.findFirst().get();
} catch (IOException exception) {
log.error(exception.getMessage());
} return filepath;
}
}
Now you can easily use the above Pathfinder utility class to look for any given file and further operate on it as shown below:
BufferedImage img = ImageIO.read(PathFinder.getFilePathForFile("apple.png")
.toFile());

Class path resource for JLabel ImageIcon

I want to add a image in JLabel that can display after building the project too in eclipse.
I have this code..
jLabel1.setIcon(new ImageIcon(getClass().getResource("/student/information/system/images/bk4.jpg")));
Goodness, why are you trying to read an image file in one line?
First, make sure that your resources folder is defined for your project and is on the build path.
Here's an example from one of my Java projects.
Next, code a method to read image files from the resources folder.
private Image getImage(String filename) {
try {
return ImageIO.read(getClass().getResourceAsStream(
"/" + filename));
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
Read the image file once, saving the result in a class variable ImageIcon.
imageIcon = new ImageIcon(getImage("image.png"));
Finally, reference the ImageIcon in your Swing code.
jLabel1.setIcon(imageIcon);

How to get file from my project (where code is written)

I'm trying to get file (readme.txt) from my project folder. Don't know how to get location of project. When I say project, I mean location where my application code is written and not runtime application. I've tried getting absolute path, relative path... and it always gives me folder of runtime application. Also tried something like this.getClass() and tried to extract path or System.getProperty("user.dir"). These two also gives me path of my eclipse.../.../...runtime app. I'm making eclipse plugin, and this file is suppose to be part of my plugin, so that when user click's on button, this file opens (it's some help txt file). This is my code for opening file, problem is path.
/**
* Help button listener. If button is pressed, help file is opened.
*/
private void listenButtonHelp() {
buttonHelp.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (Desktop.isDesktopSupported()) {
File helpFile = new File("\\readme.txt");
helpFile.setReadOnly();
Desktop desktop = Desktop.getDesktop();
try {
desktop.open(helpFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
It depends on where exactly the file is in your project. A clean point to put it might be ${project.root}/resources, so create a folder and put the file there. Mark it as a "source folder" in Eclipse (project properties -> build path -> source folders). Your current setup isn't a good idea because the file will not be included in your distribution by Eclipse's compile.
Now, when you compile the code, this gets copied into the target directors (bin per default); you can check by opening it in your file browser.
So to check the file is there, you can do
Path filePath = Paths.get("resources", "readme.txt");
System.out.println(Files.exists(filePath));
If you need it as a File, you can do
File readmeFile = filePath.toFile();
This reads the file from the source project folder, so it won't be much use after you run the program somewhere else.
For that, you can use the ClassLoader:
URL readmeUrl = ClassLoader.getSystemClassLoader().getResource("resources/readme.txt"));
File readmeFile = new File(readmeUrl.getFile());
I found answer, this works for me:
/**
* Help button listener. If button is pressed, help file is opened.
*/
private void listenButtonHelp() {
buttonHelp.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (Desktop.isDesktopSupported()) {
File file = null;
Bundle bundle = Platform.getBundle("TestProject");
IPath path = new Path("resources/readme.txt");
URL url = FileLocator.find(bundle, path, null);
/*
* After FileLocator, I get also this, like I commented before:
* D:\\eclipse-rcp-oxygen\\eclipse\\..\\..\\..\\eclipse_oxygen_workspace\\
* TestProject\\resources\\readme.txt and before it didn't work but if
* you add these lines:
* url = FileLocator.toFileURL(url);
* file = URIUtil.toFile(URIUtil.toURI(url));
* Like in my try bracket, it works. I guess it needs to be
* converted using URIUtil.
* Now it finds file, and it can be opened, also works for .html files.
*/
Desktop desktop = Desktop.getDesktop();
try {
url = FileLocator.toFileURL(url);
file = URIUtil.toFile(URIUtil.toURI(url));
// file.setReadOnly();
desktop.open(file);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
});
}

My .jar file won't open MP3 files (I'm using Jlayer - JZoom library)

I did this small Java project that in it's turn opens different MP3 files. For that I downloaded the JLayer 1.0.1 library and added it to my project. I also added the MP3 files to a package on my project -as well as some JPG images- so as to obtain them from there, and I'm using a hashmap (mapa) and this method to get them:
public static String consiguePath (int i) {
return AppUtils.class.getClass().getResource("/Movimiento/" + mapa.get(i)).getPath();
}
so as to avoid absolute paths.
When I open an MP3 file I do this:
try {
File archivo = new File(AppUtils.consiguePath(12));
FileInputStream fis = new FileInputStream(archivo);
BufferedInputStream bis = new BufferedInputStream(fis);
try {
Player player = new Player(bis);
player.play();
} catch (JavaLayerException jle) {
}
} catch (IOException e) {
}
The whole thing runs perfectly in NetBeans, but when I build a .jar file and execute it it runs well but it won't open the MP3 files. What called my attention is that it doesn't have trouble in opening the JPG files that are on the same package.
After generating the .jar I checked the MyProject/build/classes/Movimiento folder and all of the MP3 files were actually there, so I don't know what may be happening.
I've seen others had this problem before but I haven't seen any satisfactory answer yet.
Thanks!
Change the consiguePath to return the resulting URL from getResource
public static URL consiguePath(int i) {
return AppUtils.class.getClass().getResource("/Movimiento/" + mapa.get(i));
}
And then use it's InputStream to pass to the Player
try {
URL url = AppUtils.consiguePath(12);
Player player = new Player(url.openStream());
player.play();
} catch (JavaLayerException | IOException e) {
e.printStackTrace();
}
Equally, you could just use Class#getResourceAsStream
Resources are packaged into your Jar file and can no longer be treated as Files

Getting error when I attach an image to Classpath Resource in scheduler jobclass

protected void executeInternal(JobExecutionContext context) throws JobExecutionException
{
System.out.println("Sending Birthday Wishes... ");
try
{
for(int i=0;i<maillist.length;i++)
{
Email email = new Email();
email.setFrom("spv_it#yahoo.com");
email.setSubject("Happy IndependenceDay");
email.setTo(maillist[i]);
email.setText("<font color=blue><h4>Dear Users,<br><br><br>Wish you a Happy Independence Day!<br><br><br>Regards,<br>Penna Cement Industries Limited</h4></font>");
byte[] data = null;
ClassPathResource img = new ClassPathResource("newLogo.gif");
InputStream inputStream = img.getInputStream();
data = new byte[inputStream.available()];
while((inputStream.read(data)!=-1));
Attachment attachment = new Attachment(data, "HappyBirthDay","image/gif", true);
email.addAttachment(attachment);
emailService.sendEmail(email);
}
}
catch (MessagingException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
}
This is the error I'm getting:
java.io.FileNotFoundException: class path resource [newLogo.gif] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:135)
at com.mail.schedular.BirthdayWisherJob.executeInternal(BirthdayWisherJob.java:55)
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:66)
at org.quartz.core.JobRunShell.run(JobRunShell.java:223)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549)
The best practise is to read/write or to provide reference of any file is by mentioning the ABSOLUTE PATH of that file.
To your question, It shows the FileNotFoundException because, JVM failed to locate the file in your current directory which is by default your source path. So provide the absolute path in ClassPathResource or copy that image file to your current directory. It will solve your problem.
I think you need to put your file inside inside the src folder , if it's there then check whether it's under some directory which is inside the src directory.
Then give the correct location like given details below
src[dir]----->newLogo.gif
ClassPathResource img = new ClassPathResource("newLogo.gif");
or,
src[dir]----->images[dir]---->newLogo.gif
ClassPathResource img = new ClassPathResource("/images/newLogo.gif");
You got this error since the job is running in a separate quartz thread, I suggest that you locate your file newLogo.gif outside the jar and use the following to load it.
Thread.currentThread().getContextClassLoader().getResource("classpath:image/newLogo.gif");

Categories