Write a file into Java archive (JAR) - java

I would like to write a file into Java archive (JAR).
What do I need to modify in my code?
private void menu_savegame(ActionEvent e) {
File config = new File("config");
try {
FileWriter fw = new FileWriter(config);
fw.append(Integer.toString(level.current));
fw.append("\n");
if (win){
fw.append(Integer.toString(ballCount));
}
else{
fw.append(Integer.toString(G));
}
fw.append("\n");
fw.append(Integer.toString(liveLeft));
fw.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
}
I just would like this file to be written not to the folder, but into the Game.jar file - I have there all the game resources (images).

Dont forget that JAR is a typical ZIP file. In provided link you can see how it is performed.
zip manipulation with java
eventually, use external libraries like JBoss ShrinkWrap.
here's link to api
good luck!

Related

properties files in jar with windows path

We are working on a project wehre there are some legacy jar files getting used in an application. Some of the JAR files have the ".properties" file path hardcoded in code (in class files).
private static Configuration getGlobalConfigInstance() {
if (global_config_instance == null)
try {
global_config_instance = (Configuration) new PropertiesConfiguration("D:/Apps/config/properties/MyWeb.properties");
} catch (ConfigurationException configurationException) {
configurationException.printStackTrace();
} catch (Exception exception) {
exception.printStackTrace();
}
return global_config_instance;
}
Now we are moving this application from Windows to Linux, is there a way to use these JAR files without recompiling?

Properties file not loading and updating for relative path but working fine for absolute path

I am trying to access a properties file from the src/main/resources folder but when I try to load the file using a relative path it is not getting updated. But it is working fine for an absolute path.
I need the dynamic web project to work across all platforms.
public static void loadUsers() {
try(
FileInputStream in = new FileInputStream("C:\\Users\\SohamGuha\\Documents\\work-coding\\work-coding\\src\\main\\resources\\users.properties")) {
// write code to load all the users from the property file
// FileInputStream in = new FileInputStream("classpath:users.properties");
users.load(in);
System.out.println(users);
in.close();
}
catch(Exception e){
e.printStackTrace();
}
First of all you are using Spring, at least that is what the tags at the bottom say. Secondly C:\\Users\\SohamGuha\\Documents\\work-coding\\work-coding\\src\\main\\resources\\users.properties is the root of your classpath. Instead of loading a File use the Spring resource abstraction.
As this is part of the classpath you can simply use the ClassPathResource to obtain a proper InputStream. This will work regardless of which environment you are in.
try( InputStream in = new ClassPathResource("users.properties").getInputStream()) {
//write code to load all the users from the property file
//FileInputStream in = new FileInputStream("classpath:users.properties");
users.load(in);
System.out.println(users);
} catch(Exception e){
e.printStackTrace();
}
NOTE: you are already using a try with resources so you don't need to close the InputStream that is already handled for you.
Changing things inside your application simply won't work, as this would mean you could change resources (read classes) in your jar which would be quite a security risk! If you want something to be changable you will have to make it a file outside of the classpath and directly on the file-system.
Try the following code
import java.io.FileInputStream;
import java.io.IOException;
public class LoadUsers {
public static void main(String[] args) throws IOException {
try(FileInputStream fis=new FileInputStream("src/main/resources/users.properties")){
Properties users=new Properties();
users.load(fis);
System.out.println(users);
}catch(IOException ioe) {
ioe.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

Exporting image in runnable jar doesn't work

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));

Writing to a file inside of a jar

I am having a problem writing to a .xml file inside of my jar. When I use the following code inside of my Netbeans IDE, no error occurs and it writes to the file just fine.
public void saveSettings(){
Properties prop = new Properties();
FileOutputStream out;
try {
File file = new File(Duct.class.getResource("/Settings.xml").toURI());
out = new FileOutputStream(file);
prop.setProperty("LAST_FILE", getLastFile());
try {
prop.storeToXML(out,null);
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.toString());
}
try {
out.close();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.toString());
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.toString());
}
}
However, when I execute the jar I get an error saying:
IllegalArguementException: uri is not hierachal
Does anyone have an idea of why it's working when i run it in Netbeans, but not working when i execute the jar. Also does anyone have a solution to the problem?
The default class loader expects the classpath to be static (so it can cache heavily), so this approach will not work.
You can put Settings.xml in the file system if you can get a suitable location to put it. This is most likely vendor and platform specific, but can be done.
Add the location of the Settings.xml to the classpath.
I was also struggling with this exception. But finally found out the solution.
When you use .toURI() it returns some thing like
D:/folderName/folderName/Settings.xml
and hence you get the exception "URI is not hierarchical"
To avoid this call the method getPath() on the URI returned, which returns something like
/D:/folderName/folderName/Settings.xml
which is now hierarchical.
In your case, the 5th line in your code should be
File file = new File(Duct.class.getResource("/Settings.xml").toURI().getPath());

Categories