I have created an application, in which based on an operation, it modifies the properties file inside the jar.
I'm able to create a new temp jar with the updated changes. But can't rename the jar file to the existing jar file name. Since it is running, I am not able to delete and rename it.
Can any one suggest any operations or suggestions to delete the jar (Currently Executing) and rename the temp jar to that name?
I have doing for the Application:
http://java.net/projects_tags/jeazyprops
You're problem is the default ClassLoader that pre-java 1.7 uses - it locks any jar that it loads and doesn't release the jar until execution completes. The easiest solution is to use Java 1.7 which should solve this problem. Otherwise you can write your own custom ClassLoader (ugh). Default ClassLoader: http://docs.oracle.com/javase/6/docs/api/java/net/URLClassLoader.html
EDIT
And here's the note from Oracle saying they fixed it in Java 1.7: http://openjdk.java.net/projects/jdk7/features/#f584
I dont see a possibility of replacing the jar that you are executing from within the program. Suggested Approach. Create a new jar with a simple class that just launches your existing application. Before tha launch it should check if the temp.jar exists and if exists delete original and rename the temp.jar to original. In your application after creating the temp.jar, lauch the launcher class using Runtime.exec and exit. Your app will restart with new jar.
May be you would need to write a custom class loader(extending ClassLoader) which enables you to load/unload the jar. You should be able to delete the jar if you can unload the jar.
Useful links
http://docs.oracle.com/javase/tutorial/deployment/jar/jarclassloader.html
Can I dynamically unload and reload (other versions of the same) JAR?
Related
I have jar client that has an auto updater built in, when you open it if there is a new version it will download it. I made it so it downloads the new version to the same directory that the user is running the current one from so that it's easy for the end user.
The problem with this is that it can't overwrite itself because it's in use obviously. As of right now it downloads a new version and I have the version in the name so it downloads a new one with like v1.1 or v1.2 in the jar name.
This works but just seems to messy in my opinion, does anyone know of a way to make it so I can just always have the same file name? IE does anyone know of a way to overwrite a file that's in use, or a work around that will close the current and replace then reopen the new one?
Here is my downloader class - http://pastebin.com/KJdDndhh
I think the best solution to this problem is to not have 1 Jar file both manage itself as the application and the updater. Have a separate Jar for updating and your current one act as the application alone.
This seems to be similar to how many applications with auto updating works.
League of Legends has a separate updater that runs before the main application launches
Antivirus usually loads their signature files into memory and close their connection to them allowing them to overwrite those files.
When a JRE executes a JAR file, it loads the classes it needs and then releases the JAR file. So you will be able to overwrite the JAR file even from the code within the JAR file.
I have implemented the same update mechanism and it works fine for me on Windows 7, Ubuntu and Mac OS.
But if it's not able to overwrite for you, then from your code you are probably using up some resource which it has to keep the lock on (I am not really sure what, it's just my guess).
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)
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.
Consider a Java program, launched from a main method, that needs something from tools.jar. In this case, some utility code for connecting to JMX services. Do we have any choice but to wrap it in a shell script that uses -cp to manage the class path? We'd much rather use a MANIFEST.MF classpath.
from http://java.sun.com/developer/Books/javaprogramming/JAR/basics/manifest.html
the URLs in the Class-Path header are given relative to the URL of the JAR file of the applet or application.
I do not believe you have a choice about using a shell wrapper to get the tools.jar on your classpath. unless you write some custom classloader internally to allow you to find external jars.
If incorporating classes from the dependency jar is an option, I'd go with creation of a "Runnable JAR file". Basically you extract the classes from it and put them with your own classes in the JAR. That eliminates the need for a wrapping script.
To do that in Eclipse, select your project, File -> Export -> Java -> Runnable JAR file; that option will require that you have executed the main class at least once to know what profile to run when you actually run produced JAR.
I would like to ship my application as a self-contained jar file. The jar file should contain all the class files, as well as two shared libraries. One of these shared libraries is written for the JNI and is essentially an indirection to the other one (which is 100% C).
I have first tried running my jar file without the libraries, but having them accessible through the LD_LIBRARY_PATH environment variable. That worked fine.
I then put the JNI library into the jar file. I have read about loading libraries from jar files by copying them first to some temporary directory, and that worked well for me (note that the 100% C library was, I suppose, loaded as before).
Now I want to put both libraries into the jar, but I don't understand how I can make sure that they will both be loaded. Sure I can copy them both to a temporary directory, but when I load the "indirection" one, it always gives me:
java.lang.UnsatisfiedLinkError: /tmp/.../libindirect.so: /libpure.so: cannot open shared object file: No such file or directory
I've tried to force the JVM to load the "100% C" library first by explicitely calling System.load(...) on its temporary file, but that didn't work better. I suspect the system is looking for it when resolving the links in libindirect.so but doesn't care about what the JVM loaded.
Can anyone help me on that one?
Thanks
One way would be to spawn another Java process from the first, generating the appropriate invocation script.
The jar is invoked by the user
The libraries are extracted to a temp directory
A (bash) script is written to the temp directory
this sets/exports the necessary environment variables
this launches the second JRE instance
The code makes the script executable
The code invokes the script
I know, spawning two JRE instances to launch one app would not be my first choice either.
If you are using Eclipse IDE, then this answer might help you.
I had same problem in eclipse windows that I couldn't added dependant .class files from the JNI.
After searching for a while I came to know that "Its a known bug inside Eclipse", In order resolve the same, I ported all the code to NetBeans IDE.
Can not add all the classes files from the JNI folder in Eclipse (JAVA, Windows 7)