26

Problem: I have a standalone Java app (henceforth known as "the agent") that runs as a service on internal company servers. It acts as a remote agent for some central servers. As the agent gets deployed in more places, managing them is getting more complicated. Specifically: pushing updates is painful because it's a fairly manual process, and getting access to the logs and other info about the environments where the agents are running is problematic, making debugging difficult. The servers under discussion are headless and unattended, meaning that this has to be a fully automated process with no manual intervention, hence Java Web Start isn't a viable solution.

Proposed solution: Make the agent phone home (to the central servers) periodically to provide agent status and check for updates.

I'm open to other suggested solutions to the problem, but I've already got a working prototype for the "status and self-updates" idea, which is what this question is focused on.

What I came up with is actually a separate project that acts as a wrapper for the agent. The wrapper periodically calls the central server via HTTP to check for an updated version of the agent. Upon finding an update, it downloads the new version, shuts down the running agent, and starts the new one. If that seems like an odd or roundabout solution, here are a few other considerations/constraints worth noting:

  1. When the wrapper gets a new version of the agent, there may be new JAR dependencies, meaning class path changes, meaning I probably want to spawn a separate Java process instead of fiddling with ClassLoaders and running the risk of a permanent generation memory leak, which would require manual intervention--exactly what I'm trying to get away from. This is why I ended up with a separate, "wrapper" process to manage the agent updates in my prototype.
  2. Some servers where the agents are deployed are resource-limited, so any solution needs to be low on CPU and memory usage. That makes me want a solution that doesn't involve spinning up a new JVM and is a stroke against having a separate wrapper process.
  3. The agent is already deployed to both Windows and RHEL servers, so the solution must be cross-platform, though I wouldn't have a problem duplicating a reasonable amount of the process in batch and bash scripts to get things rolling.

Question: As stated, I want to know how to make a self-updating Java app. More specifically, are there any frameworks/libraries out there that would help me with this? Can someone with experience in this area give me some pointers?

Ryan Stewart
  • 126,015
  • 21
  • 180
  • 199
  • 2
    http://stackoverflow.com/questions/305461/automatic-updates-of-java-desktop-application – Amir Afghani Apr 20 '12 at 03:49
  • See Jenkins examples: https://wiki.jenkins-ci.org/display/JENKINS/Distributed+builds#Distributedbuilds-LaunchslaveagentviaJavaWebStart – Mark O'Connor Apr 20 '12 at 21:38
  • Your solution wouldn't let you update the wrapper itself, right? – Miquel Apr 20 '12 at 22:01
  • @Miquel: Correct. An ideal solution would be one where there's nothing deployed that can't be updated. My wrapper prototype is certainly not that, but ideally (again), the wrapper won't need updates because it has one, simple job and few moving parts. – Ryan Stewart Apr 20 '12 at 22:08
  • @MarkO'Connor: Good link. I'll have to think about that one. The Jenkins model suggests to me changing from a pull to a push, where the central servers could be directed to install an agent or an update to a remote server over SSH or some other protocol. – Ryan Stewart Apr 20 '12 at 22:15
  • After 2 years, which solution you have taken? Written your own wrapper or use existing frameworks/libraries like http://ace.apache.org? I have the same problem to manage > 3000 agents. – Lee Chee Kiam Aug 09 '14 at 04:32
  • @LeeCheeKiam can you verify my added answer ? – Amr Lotfy Jun 18 '15 at 02:26

5 Answers5

4

If your application is OSGi based, you could let OSGi handle bundle updates for you. It is similar to the wrapper approach you suggest, in that the OSGi container itself is "the wrapper" and some of it won't be updated. Here's a discussion on this

Community
  • 1
  • 1
Miquel
  • 15,405
  • 8
  • 54
  • 87
  • Good thought. I considered OSGi, but there's the resource constraint to consider. The OSGi containers I've tried out have significant memory footprints without even having any bundles deployed to them. I'd be happy to be corrected on that point, though. – Ryan Stewart Apr 21 '12 at 00:02
  • 1
    Another resource to consider is your time. OSGi is extremely invasive into the architecture of your app, and the classloading rules it imposes can take a while to learn. It's fine once you are up and running (and having someone implement update is great!) but don't think this would be a day's work. – Dan Gravell Jun 14 '12 at 11:20
4

Different solution: use (and pay for) install4j. Check out the auto-update features here

Miquel
  • 15,405
  • 8
  • 54
  • 87
  • That's the best lead I've seen yet, which I picked up from [another question](http://stackoverflow.com/questions/207557/whats-the-best-way-to-add-a-self-update-feature-to-a-java-swing-application), though I haven't dug deep enough to see if it really meets my needs. – Ryan Stewart Apr 21 '12 at 00:03
3

No need for wrapper (save memory) or java web start (adds more restrictions on your application), simply let a thread in you application check periodically for updates (e.g. from cloud) and download updates if available, then code these two calls in you application:

  1. launch a shell script (.sh or .cmd) to update your artifacts and launch your application after few seconds pause in the script(to avoid having two instances of your application at the same time).
  2. Terminate your application (first instance)

The script can overwrite needed artifacts and re-launch your application.

enjoy !

Amr Lotfy
  • 2,937
  • 5
  • 36
  • 56
2

Have a look at Java Web Start.

It is technology that's been part of Java since... 1.5? maybe 1.4? and allows deployment and install of standalone Java-based apps through a web browswer. It also enables you to always run the latest app.

http://www.oracle.com/technetwork/java/javase/overview-137531.html

http://en.wikipedia.org/wiki/JNLP#Java_Network_Launching_Protocol_.28JNLP.29

also see this question: What's the best way to add a self-update feature to a Java Swing application?

Community
  • 1
  • 1
Cheeso
  • 189,189
  • 101
  • 473
  • 713
  • 1
    I'm sorry. I meant to make it clear that these are headless servers, and the app runs as a background daemon. These aren't workstations. They don't have a desktop environment, much less a Web Start-capable brower. I visited Web Start but came to the conclusion that it was geared toward delivering an application to a user. This is to be completely automated and unattended. I'll update my question to make that clear. – Ryan Stewart Apr 20 '12 at 04:01
  • Webstart can be invoked from command line (does not require a browser) using the javaws command: http://docs.oracle.com/javase/1.5.0/docs/guide/javaws/developersguide/javaws.html – Mark O'Connor Apr 20 '12 at 21:41
  • 1
    I'm not sure, but I think there's no way to prevent the security pop-up when using javaws, even from the command line. For people wanting to deploy Java applications without paying for a trusted security certificate or silently update existing Java applications, Java Web Start is becoming unfavorable. – Andy Nov 11 '13 at 23:37
0

It appears as though Webstart is the only built in way to do this at the moment.

Amir Afghani
  • 37,814
  • 16
  • 84
  • 124
  • See my comment to the other "Web Start" answer. – Ryan Stewart Apr 20 '12 at 04:04
  • It wasn't me, but I expect it's because Webstart isn't a solution to the question. – Ryan Stewart Apr 20 '12 at 19:06
  • Based on what you're looking for, I guess you're right. Is doing it in a 'platform neutral' way important for you? – Amir Afghani Apr 20 '12 at 20:04
  • Yes. We're already deployed to both Windows and RHEL servers. I'll add that to the "additional considerations". – Ryan Stewart Apr 20 '12 at 20:18
  • This is going to make it 'hard'. You'll need to poll some sort of update server, download the latest, and have a mechanism to shutdown and restart the daemon. – Amir Afghani Apr 20 '12 at 20:20
  • Well, yes. If you read the middle part of my "Proposed solution", then you'll see that's exactly what I've already prototyped. I'm asking for best practices, advice, supporting frameworks, etc. from the community because this is new territory for me. – Ryan Stewart Apr 20 '12 at 20:55