I'm trying to comprehend how creating executable jars and file paths work, so please bear with me.
I have a small program, which is supposed to upload some Firmware to Servers. These Firmwares have a combined size of about 650MB. All in all, the Project Folder takes up about 2.2GB of space.
In the program itself, I have some Strings that refer to the name of the folder that contains the firmware.
"src\\com\\java\\myProgram\\data\\bios_fw\\"+biosFWPath+"\\"+biosFW
When testing in the IDE, this works without problem.
So here's my question(s): Will this still work if I build the program as executable jar? I have already noticed that the jar I created holds only about 450MB. Does it even contain the firmware then? And if it does, will the program be able to find the path specified?
Furthermore, what would be the proper way of "installing" these folders together with the jar on a Users PC?
Thanks!
As a .jar file is a java archive file, you can open it and look yourself as we don't know how you build your .jar.
But considering the future, I would remove the absolute path and use a relative path to a directory where you can insert the firmware in case the fw got updated, so you don't have to build your program each time.
The proper way, when you want to keep the FW in your project is using ClassLoader.
Related
I have finally completed a program in Java and I have to upload it.
The problem is that I have to upload also the executable .jar file and not only the eclipse project.
The main functionality of my program consists by reading and writing .xml files (for example one file is used to read and add new users), and the files in the project folder are so located:
-Project Name
src
default package
main and all other classes
file1.xml
file2.xml
So the two .xml files are in the root of the project.
My question is: It is better to save the .xml files in the JAR and then writing and reading them from the executable program or it is better to store them in a folder outside the .JAR and reading and writing them as externally files?
It is a good practice to create a folder like that?:
-ProjectName
file1.xml
file2.xml
project.jar
I read in Stackoverflow a lot of people having my same issue and a lot of people doesnt know how to manage this problem properly.
Thank you in advance for the reply :)
Changing files in JAR-files can have all sorts of problems. That starts with simple things such as what should happen when you want to update your program to the newest version? Usually you'd just swap the jar, but then you loose everything you edited so far. You'd need a process to update inside the jar.
Other problems include that for changing the jar file you need to open it, possibly realign contents and rewrite the index which could conflict with the JVM that is reading the jar at the same time causing odd behaviour. On some systems (windows...) the Jar file might even be locked while the application is running and thus you cannot write to it at all.
I'd suggest that you add "default files" (in case that your files are initially not just empty) to you Jar file that represent the initial state. If the application is started you check if the XML files exist in the some normal writable directory and if they don't just copy the default files to that directory. This allows you to deploy still just a single jar file, but once started the appropriate files will be created.
You may read a XML file located inside the executable Jar but it is not possible to update (write) a XML file located inside that executable Jar file. So the best option would be:-
-ProjectName
file1.xml
file2.xml
project.jar
The jar should be kept read-only, the XML "files" inside the jar should be read using getResource[AsStream] (class path). You can use those resources as templates to create a copy in the user's (or application's) directory/sub-directory. For the user's directory:
System.getProperty("user.home")
I am developing a program that uses a sqlite file as a database. When I compile and test my program I haven't any problem:
Conection c = DriverManager.getConnection(
"jdbc:sqlite:/home/mehdi/my_database.sqite");
as you can see in above, the code shows a direct path that set to database file (this path is only in my system).
So it works fine, but my problem starts when I create an executable jar file of my program, if I create executable jar file and share it with other users, when they run the executable jar it doesn't work.
My first question: how do I set my database path for an executable jar file in my code?
My second question: is it possible for the database to be along side the executable jar? (and i can move my executable jar file with its database)
some_path/my_program_file.jar
some_path/my_database.sqite
The best option is externalizing the database path instead of hardcoding it, and letting the user choose where to put the actual sqlite file.
You could put the sqlite file in the same directory as the program archive, but please note that this does not really help in locating the file from your code, because relative paths are definitely resolved against the JVM (process) working directory, not the location of the JAR:
new File(".").getAbsolutePath()
There are ways to get the location of the JAR:
getClass().getProtectionDomain().getCodeSource().getLocation()
but they are deploy-dependent, so it's not a very robust strategy to rely on.
Most Java program are configured with external files put in well-known locations (like the current JVM directory or a .myapp/conf.properties in the user home), and individual properties can be overridden in the starting command line, as either system properties -Dkey=value or program arguments (there's a library to simplify this)
Java uses relative paths when you do not specify the absolute path. I'm not sure if it works for the DriverManager though. What this means is that if you call jdbc:sqlite:my_database.sqite it should look for my_database.sqite in the folder the jar is executed from. So if the user calls java -jar my_program_file.jar from the folder where the database is it will work. If the user calls the jar from another location it won't. To fix that, you have to grab the path where the jar is located, like so:
return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath());
This was showcased in another SO post.
I have started getting into game programming.
My question is, that when I am working with files, either parsing data, writing to files, etc. Should I be using relative path names, or absolute pathnames, or something else which is better. I've heard about using jar files, but I am not sure
1. how that works
2. if it is a good way to do it.
So when developing a game that will be cross platform, what is the best method for managing files that the program will need to read from and write to.
there are several ways in which you can ship your code as a product. the most common are
packaging everything in one executable jar file.
having a set of folders where you place all necessary resources.
minecraft, for example, is written in java and distributed as a single executable jar file that contains all necessary class files and resources. to run the game (assuming you have java installed) all you need to do is double-click the jar file.
read this short tutorial about how to add a main class to a jar file.
either way, always treat classes and resources in your code as if they're in your classpath. for example, if you have a my.properties file on the root of the source tree then load it by using 'my.properties'. if you put it under a 'conf' folder then use 'conf/my.properties'.
i think it is the safest way not to get lost.
are you using maven?
The jar file is a zip of all your compiled *.class files and your resources. You can safely load your resources and even default data FROM a jar if you package your program, but you can NOT safely write data back to the jar. This detail is answered in depth already at
How can an app use files inside the JAR for read and write?
For information on how to package a jar see
http://docs.oracle.com/javase/tutorial/deployment/jar/
I have written a java program which different classes where during the process it generates lots of files (say txt files) and then reads the files and operates on them. I have made the project as a JAR file where I can run it from command with no problem as JAR is in the same directory.
However, I want to run this JAR file on a remote server where the PATHs are not the same, so then it generates error, because in my project for instance it should read a file from /Programs/Folder/here whereas in the server this cannot happen as there is no /Programs/Folder... directory. Do I have to change all the paths in my program according to the new location I wanna put my jar or there is another way around it?
I would appreciate your help.
Best wishes
I would think the best way is to pass the directory name where the files in as an argumrnt to the java command line.
Read it from the parameter args in main
This simplest and best solution is to change all of your paths in files inside of your project to be relative paths. You can also simply pass the directory you would like the files stored in to String args[] as parameters
what i prefer is i use relative path and then read relative path using classloader.try it.
My file is located under the src directory. However, when I try to call it using "src/readme.txt" the file is not found.
In fact, it states that java is looking for "C:\Documents and settings\john\My Documents\Downloads\eclipse-win32\eclipse\coolCarsProject\src\readme.txt".
How do I fix this? I do not want to put in the absolute path all the time.
Do I need to fix the classpath, buildpath, or change the project root, etc? It is not at all obvious from the roughly 1000 settings in Eclipse for a newbie.
First, you have to decide if you want to load the file from the file system, or if the file will in fact be bundled with your application code.
If the former, then you should really think about how your application will be launched when actually deployed, because using a relative file path means that the program should always be started from the same location: a relative path is relative to the location from where the program is started (the current directory). If this is really what you want, then edit your launch configuration in Eclipse, go to the Arguments tab, and set the working directory you want. But the src directory is not where you should put this file, since this will copy the file to the target directory, along with the classes, that will probably be put in a jar once you'll deploy the application.
If the latter, then you should not treat the file as a file, but as a resource that is loaded by the ClassLoader, using ClassLoader.getResourceAsStream() (or Class.getResourceAsStream()). Read the javadoc of those methods to understand the path to pass. If you put the file directly under src, it will be copied by Eclipse to the target directory, along with your classes, in the default package. And you should thus use SomeClass.class.getResourceAsStream("/readme.txt") to load it.
Using paths relative to the current working directory is not a good idea in general, as it's often quite hard to establish what your current working directory will be. In Eclipse, it will be your project folder (unless you set it to something different in your launch configuration), in webapps it will be the webapp's root directory, in a command line app it could be anything.
Try this one:
String filePath = ".\\userFiles\\data.json";
where «.\» is a root for the Eclipse project, «userFiles» is a folder with the user's files inside of Eclipse project. Since we are talking about Windows OS, we have to use «\» and not «/» like in Linux, but the «\» is the reserved symbol, so we have to type «\\» (double backslash) to get the desired result.