views:

75

answers:

2

Hello Stack Overflow friends. I have a simple problem which i fear doesnt have a simple solution and i need advice as to how to proceed. I am developing a java application packaged as and executable JAR but it requires to modify some of its JAR file contents during execution. At this stage i hit a problem because some OS lock the file preventing writes to it.

It is essential that the user sees an updated version of the jar file by the time the application exits allthough i can be pretty flexible as to how to achieve this. A clean and efficient solution is obviously prefereable but portability is the only hard requirement.

The following are three approaches i can see to solving the problem, feel free to comment on them or suggest others.

  1. Tell Java to unlock the JAR file for writing(this doesnt seem possible but it would be the easyest solution)
  2. Copy the executable class files to a tempory file on application startup, use a class loader to load these files and unload the ones from the initial JAR file.(Not had much experience with the classloaders but hopefully the JVM would then be smart enough to realize that the original JAR is nolonger in use and so unlock it)
  3. Put a Second executable JAR File inside the First, on startup extract the inner jar to e temporaryfile, invoke a new java process using the copyed inner JAR and pass it the location of the Outer JAR, first process exits, second process modifys the Outer jar unincumbered.(This will work but im not sure there is a platform independant way of one java app invoking another)

I know this is a weird question but any help would be appreciated.

+2  A: 

One option:

Have the program write a modified copy of the JAR file.

Include in the JAR file a second JAR with a utility that, when executed, deletes the original JAR file and renames the modified copy to match that of the original.

When your program exits (and changes have been made) extract this utility and launch it in its own JVM (using Runtime.getRuntime().exec()). The utility would wait for the lock to go off the original, unmodified JAR and then do its business and exit.

To the user the JAR file would seem to update on exit (or close enough!).

Kris
Hey, thx for your answer, thats definetly another solution although it does still suffur from the same problem as my option 3. I suppose using exec("java") is fairly portable i just was hoping there was some truly platform independant way of spawning one Java app from another.
While Java is much more platform-independent than many other languages, it's imperfect in a lot of ways, and it's not really that big a deal to have something like the way you execute a jar file be done in a switch based on the platform (if it even needs to be different - I think 'java <jarfile>' works on unix and windows, not sure about osx).
Chris
A: 

I honestly think your approach is wrong headed. This is simply not a good fit to the default way of deploying java. Your modified files will just have to persist to a db or xml file somewhere - that is the ONLY sensible approach.

Anything is just "fighting against the wind" - you might with some struggling get it to work, but it WILL bite you or customer eventually.

MJB
I'm sorry you don't like this answer. What with renaming, locking, etc, I was just expressing my opinion that you were trying to force a solution that doesn't fit the problem well.
MJB