How to delete the Executable Jar File by it self? - java

I developed a simple java application ,is it possiblefor the application (Executable Jar File) to find its current path and delete it self from both the current place and from Recycle Bin after a certain time.

No, when java runtime starts and uses this jar file, windows prevents it from being deleted. In other operating systems like Linux you can delete files even if they are used.

There are already questions/answers that show you how to get the currently running jar file. Keep in mind, the methods aren't consistent across platforms:
How to get the path of a running JAR file?
Deleting a file in Java is fairly straight forward as well:
import java.io.File;
...
new File("c:\\path\\to\\whatever.jar").delete();
On an operating system that doesn't have file locking, you can simply delete the jar you're running from as it's already loaded into memory. On operating systems that lock files, this may not be possible if the JVM decides to lock the currently executing jar(s).

Windows strictly restricts you from doing this untill the jar is in use
It is something like this :
In Linux you can do it here is How to delete a executing jar file

In order to delete the jar file, I recommend:
Creating a bat/sh file
Run the file
Close the jar file with System.exit method
Within the bat/sh file:
Loop until success deletion
Delete the bat/sh file within itself(unlike the jar file bat/sh file can delete itself)

Related

Reading and writing files within Jar

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

Serialized files don't work when project is converted to executable jar?

I made my java project into an executable jar using the export to jar option in eclipse. The jar runs as expected, except that it does not use any of the serialized files. I can see that clearly from the GUI. What could be the reason for this problem and how do I fix it ?
I saw this related question - Why does my JAR file not create a serialization?
But it does not tell me exactly how to get around this problem. It looks like you cannot pack a folder into a jar. Why ? Because code could accidentally/intentionally continue to add data into that folder and make the whole jar occupy the hard disk ?
How do I create some kind of structure in which I pack my executable jar and its serialization folder ?
Answering this question:
How do I create some kind of structure in which I pack my executable jar and its serialization folder ?
A common approach is to have a well-defined place to store serialized files, settings, etc, that does not depend on where the program has been executed from. Usually it is user's home directory, or Application Data in case of windows. I used this code to store my application settings:
String home = System.getenv("APPDATA");
if (StringUtils.isEmpty(home)) {
home = System.getProperty("user.home");
}
CONFIG_HOME = new File(home, ".myProgram").getAbsoluteFile();
CONFIG_HOME.mkdirs();
So on windows it will use AppData and on *nix systems it will use user's home. The dot in front of myProgram is to make it hidden on *nix platforms, which is a common practice.
EDIT For your question in your comment:
on my linux machine there is no APPDATA env variable so this code will create a directory /home/myUser/.myProgram. On windows it will be something like c:/Users/myUser/AppData/Local/.myProgram. On MacOSX, no idea.
You need your JAR to use the same path for reading the Serialized Files as your code in eclipse.
So you make a properties file containing the directory with your serialized objects.
Then, this is the same for both your JAR and our project.
See also: http://www.mkyong.com/java/java-properties-file-examples/
You can use
AClass.class.getResource(String str);
//or
AClass.class.getResourceAsStream(String str);
AClass: one of your classes.
str: file location which you want to read.
For example;
if your class hierarchy seem like this:
+src
+-com
+-test
|-AClass.java
+-util
+-PrintUtil.java
+-resources
|-Bouble.png
|-Mouse.png
+-Ocean.png
and for reading "Mouse.png" image, you can this with a lots of ways:
AClass.class.getResource("/resources/Mouse.png");
//or
PrintUtil.class.getResource("../resources/Mouse.png");
...
You can't write inside a jar file while you are using/running the jar file. When you put the jar file in you classpath or you run the program from jar directly, the jar will be locked by your jvm, hence it won't allow you to update the same jar file which you are currently using.
The solution given by people which says use resource as stream will work if your classes are there in a folder, not in an archive (which you are using).
As an archive you can't directly update it, you need to do following steps (by yourself or by 3rd party api),
Extract in temp location
update the files
re archive
Now as the jar file is locked, you won't be able to do the third operation, which is not even safe. As an example when you are running a jar file, try to rename it, it won't happen, if it happens, the jar file is not yet locked by the jvm, it gets locked whenever you call a class which is inside the jar file.
For better and secure serialization and file saving please look into this: java.util.prefs.Preferences.

Java + jar file

I have written a quick Java wrapper that fires off the NMAP executable and waits for it to finish. I am using Eclipse. I would like to include the NMAP source/executable
in my Java jar file so that I have a self-contained package.
Within Eclipse I have added the NMAP folder hierarchy. Within Eclipse I can see Java firing off the NMAP utility correctly, and waiting for the utility to end before exiting.
So far, so good. I then export a JAR file for with eclipse. I can see the NMAP folder hierarchy present. However when I try to run the JAR file it is having trouble finding nmap.exe. Can a foreign executable be called from with a jar file? if not, what are
my options? If so, why can't it find it within the jar file when it could find it within Eclipse?
Thanks.
You will need extract the .exe and its required support files onto the disk before you can access them as regular files (which execution through standard methods requires, I believe). You can look up examples of how to copy a resource from a jar to a file using getResourceAsStream() on one of your class files in the jar.
Once extracted, you can execute is as you are doing now (you might need to ensure execution rights, etc. based on your OS)
The "execute native program" facility does not understand how to invoke EXE-files inside other files (like ZIP or JAR).
If you want to do this, you must extract the files to a file system location and invoke it there. Due to the diversity of Linux distributions (PowerPC? other library versions etc) you should probably ask the user to install it instead and invoke that instead of bringing your own.
To my knowledge, you cannot execute an executable embedded in a jar file.
One solution would be to embed the executable in the jar file. Then use getClass().getResourceAsStream("/path/to/executable") to retrieve the bytes and output them to a temporary file (File.createTempFile()). On UN*X system, you will have to chmod u+x file before trying to execute. Eventually, you could delete the temp file or create the file once and reuse it everytime and call deleteOnExit().
Of course, this solution implies that you have executable(s) that work on all platforms.
Your solution probably works in eclipse because your "executable" file is not in a jar.
You may also have to be careful of how you are distributing this because Nmap isn't free for use in commercial software.
There is an open source library for Java to call Nmap but it assumes that Nmap is installed on the OS on which you are running your code. That API is Nmap4j and it is on sourceforge.net.

executable JAR file not showing resources

i created an executable JAR file using eclipse.. I have resources in the project folder that
does not appear when the frame is open..I mean when i double-click on the JAR file. More
so,After I try to delete the JAR file I get a warning that the JAR file is being used on the
Java Se platform .How can I eliminate this problem other than using a resource loader class?
Some times when we run a jar file the resources gets used by jvm and they are not released due to this we cant delete the jar file.So trying killing the processes from the task manager so that you can delete the jar file.For me killing explorer.exe worked.Try killing that process andf then try deleteing jar file.
Use ClassLoader to get the InputStream if your resources is in the source folder.
ClassLoader.getResourceAsStream(String name);
Close your application before you delete the JAR file. Or explicitly exit your application with the following code.
System.exit(0);
There can be a possibility that the resources are not exported at all. Sometimes it happens that you need to tick the check box against each resource name and then hit finish while exporting it with Eclipse.
Also, please check that there is no warnings when the export process is finished.
Kill all the java.exe and javaw.exe process from task manager and then try to delete.

Add files in jar during runtime

Project is to create exe file. If we run exe file it will open one admin page (designed in Swing) that page contains browse button, max install, max install sys, and create build, while click the browse button we need to select one exe file from system and that file need to save it inside one folder of jar file. The maxinstall, max install sys value is stored in SQL lite database. This admin page will open for first time only,to get condition from admin. Next if we run the exe file it must check maxinstall and all parameter and then install that selected exe file.
My problem is, I created jar from my java program. While running the jar each time, the admin page only opening (i.e) the database file is not updated inside jar, but its works fine in eclipse. After that I need to create jar to exe.
..it is possible to extract jar in runtime,addfile in the extracted jar and create a new jar in runtime..?
Most JREs will place a file lock on the Jars. Therefore they cannot be updated while the JRE is running. Check a sub-directory of user.home for an altered version of the resource. If it is not found, use the one in the Jar. If it is altered, save the changed data to the sub-dir.
Use a sub-directory based on the package name of the main class, to help avoid overwriting the resources of another app. (or other apps. over-writing your resources).
I think that I understand your problem. Your application stores its state into its own jar file. the fact that you are using SQLite etc. does not matter. It works from Eclipse because in this case the class files and resources are not packaged into archive and your program changes files on file system easily.
The answer is: yes, you can change jar file programmatically. Jar is just a zip. You can use ZipInputStream, ZipOutputStream, JarInputStream, JarOutputStream to modify any zip including your own.
But it is very very not recommended for too many reasons. The right solution is to separate your data from your application. You have to store runtime data on file system, DB etc. For example you can create files in user home directory. It is platform independent. You can also use Preferences class that has portable implementations for all platforms.
Yet another reason to do this is your requirement to create exe. OK, you can change jar file but once you created exe file from your jar you cannot change it anymore.
Once an executable .jar is created it will be "locked". I you add more files to a locked .jar, those files will not be recognized internally by the .jar itself at runtime. So, the better approach is to extract your dependent .jar and then add it to a new, executible .jar containing the new file(s) that you need. Then moving forward you can run this new .jar.

Categories