I am looking for the best way to make my desktop java program run in the background (daemon/service?) across most platforms (Windows, Mac OS, Linux [Ubuntu in particular]).
By "best way" I am hoping to find a way that will:
require a minimum amount of platform-specific code.
not require the user to do anything a general computer user couldn't/wouldn't do
not be a resource hog.
I understand that my requirements may be unrealistic but I am hoping there is some sort of "best practice" for this type of situation.
How to go forward?
You can run a Java application as a service (Windows) or daemon (Linux) using the Apache Commons daemon code.
Structure
Daemon is made of 2 parts. One written in C that makes the interface to the operating system and the other in Java that provides the Daemon API.
Platforms
Both Win32 and UNIX like platforms are supported. For Win32 platforms use procrun. For UNIX like platforms use jsvc.
Java code
You have to write a Class (MyClass) that implements the following methods:
* void load(String[] arguments): Here open the configuration files, create the trace file, create the ServerSockets, the Threads
* void start(): Start the Thread, accept incoming connections
* void stop(): Inform the Thread to live the run(), close the ServerSockets
* void destroy(): Destroy any object created in init()
You can turn any Java program into a service/daemon using the Java Service Wrapper. It is used by multiple OSS projects, and ships as part of the Nexus Maven Repository Manager so that it can be installed as a service out of the box. To use it, you, the author, just need to create a configuration file and then run a simple batch file to create the service on Windows or copy an init script to the correct runlevel on Linux.
You can use the SystemTray classes and install your app as any other in the default platform.
For windows it could be an scheduled task that run at startup.
For Linux and OSX I don't know (besides crontab wich is somehow too technical) but I'm pretty sure they both have a way to do the same thing easily.
Unfortunately (as of today) Apple hasn't finished the 1.6 port.
It won't be a real demon, but an app like Google Desktop.
I've heard Quartz is a good option. But I've never used it.
If you dont need free solution, you can use Advanced Installer (www.advancedinstaller.com), it can make win-service as well as MacOS installer from your JAR, and more..
Check out JDIC, the Java Desktop Integration Components project. It supports desktop integration like system tray (or equivalent) with a cross-platform API.
Others have mentioned Quartz, which is an enterprise job scheduler. It can be lightweight, depending on the jobs that are scheduled, but it doesn't have any features that are inherently desktop-oriented. On the contrary, many of its features depend on enterprise support like a relational database. If your application is primarily scheduling tasks, a headless Quartz service executing jobs, with a desktop client to interact with the service is reasonable approach.
The Apache Directory Daemon project sounds like the best cross platform way to do this (with Java wrappers for JSVC under POSIX and procrun under windows).
People sometimes have difficulties finding prunsrv.exe and/or prunmgr.exe (components of procrun), its not well documented on the apache site, generally it can be found in the archives (note. they say that procrun is tomcat5.exe)
for windows you can find it here:
http://archive.apache.org/dist/commons/daemon/binaries/windows/commons-daemon-1.0.7-bin-windows.zip (contains both 32 and 64 bit versions)
you dont need to implement daemon interface nor download it at all, prunsrv can be used to turn any app to windows service
browse that archive for other platforms
Related
I have a Java Spring Boot application which I would like to run as a service, ideally in Mac, Windows and Linux. It should run 24/7 and be robust i.e. restart itself if it crashes.
Does anyone know the current best practice way of achieving this?
In order to make an app as a service it should confront to some Interface defined by Microsoft. Here it is:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms685942(v=vs.85).aspx
This is not the easiest solution and will make you app platform dependent. There are some wrappers that make what you want possible.
Check the Java Service Wrapper
https://wrapper.tanukisoftware.com/doc/english/introduction.html
It has options to wrap the app as windows service and unix daemon. I am not sure about macOs. There are other similar wrappers too
Best practice1 is to use the best practice solution for each platform. Unfortunately, that means different things for different platforms; e.g.
on Window, use the Windows Service mechanism
on UNIX / Linux, write a service script that uses the distro's native "init" framework
on Mac OSX, you typically use something like Automator to create a ZIP file that implements the service.
Unfortunately, in the UNIX / Linux case there are a number of different init frameworks, depending on the vintage; see this Wikipedia page.
Another answer mentions the Java Service Wrapper. I don't know how well it works with different Linux "init" frameworks, but it looks like it provides a one-size-fits-all init script written in "sh". It should be usable with systemd, though you won't get the full benefits of that framework.
1 - But read James Bach's No Best Practices article.
All of the solutions I found on stackoverflow suggest wrappers to register java application as windows service. My requirement is totally different. Please don't suggest wrappers for the purpose. The question is very simple I have java executable and I want to register it as windows service.
Phyiscal Path
Service Properties
Unfortunately we don't have backup of previous setup that installed it as windows service at the first place. Do I need some setup program or anything like that.
Not necessarily.
It is difficult to advise you on precisely what you need to do without more information on what you actually still have; e.g. an application installer, application JAR files, wrapper scripts, etc. Alternatively, if you told us what the application was, then maybe we could give you some hints on where to get installers, etc.
However, I can tell you definitely that registering java.exe or javaw.exe directly as a Windows Service will not work. These are not the executables for your Java application. Rather they executables for as Java Virtual Machine that will run your (real) Java application.
It is so easy task in case of Visual Studio. I want same support in Eclipse or anything else.
Well Java doesn't work like that. Java compiles to platform independent bytecode files, not to platform-specific native code. Sure, there are third party tools to generate exe's. However, using them is neither necessary, or desirable:
Why is creating an .exe from a java program not recommended?
(And asking for recommendations on what tools to use to do this is off-topic.)
Finally, if you take an arbitrary Java program and turn it into an ".exe" file, it won't necessarily be immediately registerable as a Windows service. This Q&A talks about turning an ".exe" into a Windows Service.
Create Windows service from executable
However, I can't tell you if the advice given there is appropriate for an ".exe" file created from an arbitrary Java app by some unspecified 3rd-part tool.
My recommendation:
If you are starting from scratch, use a Java Service Launcher / Wrapper.
If not, talk with whoever supplied and/or installed this application in the first place.
If you can't find any information about the application and where it came from, or if the vendor has gone out of business ... you need to urgently look for an alternative.
As I know there are two standard ways you can distribute a Java desktop application:
Through a runnable jar file
Through a bat file which calls a jar file to begin execution
I want to know what is the best way among these methods and what are the relative advantages and disadvantages?
The list is missing the best one!
..
..
Java Web Start.
Java Web Start (JWS) is the Oracle Corporation technology used to launch rich client (Swing, AWT, SWT) desktop applications directly from a network or internet link. It offers 'one click' installation for platforms that support Java.
JWS provides many appealing features including, but not limited to, splash screens, desktop integration, file associations, automatic update (including lazy downloads and programmatic control of updates), partitioning of natives & other resource downloads by platform, architecture or Java version, configuration of run-time environment (minimum J2SE version, run-time options, RAM etc.), easy management of common resources using extensions..
In case it is not clear, I vote JWS as the 'best' from a user point of view. The details of the advantages are pretty much expressed in the 2nd paragraph of the description, but also the last sentence of the first. Not to forget the 1st sentence of the next paragraph..
By default, an applet-like security sand-box is applied to code launched using JWS. ..
I think runnable jar would be a good option for desktop application. As I am using it for my desktop application is more comfortable and user friendly.
I think it will depend on who are the users of your application.
If the users are non-tech people you better go with a runnable jar because
they are less likely to pass an argument to your program.
In case they are your team members or other tech people, you may give them a .bat
to play around with your app.
For Windows, wrappers like Launch4j could be considered.
The open source software always use .bat or .sh file to distribute a java application.I think this way would be a good option.
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:
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.
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.
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?
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
Different solution: use (and pay for) install4j. Check out the auto-update features here
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:
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).
Terminate your application (first instance)
The script can overwrite needed artifacts and re-launch your application.
enjoy !
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?
It appears as though Webstart is the only built in way to do this at the moment.
I have a java application that I want to release as an exe or dwg etc so that users on different platforms can double click it and get it to start running.
But for my code to work really well I need it to work as a windows service and whatever the equivalent of this in other OS are.
Using Java web start is not a solution because as I understand it, if the client machine shuts down then the user will have to again double click on the exe.
I have tried java service wrapper but I can't see how to make it releasable.
Thanks
Pranabesh
If a commercial tool is acceptable for you, I'd recommend install4j. It can produce installers for the most common plaftforms, which specifically support installing the application as a service.
Quote from their Features page:
install4j offers full support for generating and installing services (daemons). For services, install4j generates service executables on Windows, startup items on Mac OS X and start/stop scripts on Unix/Linux platforms.
Java Service Wrapper is a way to go for Windows/Unix/OSX. I've been using it with no problems for some years. It's a great software and handles JVM crashes/hangs well automatically restarting the service if something bad happens.
What concerns the distribution of the application, I'd recommend NSIS on Windows. It can create a nice installer that will put the files where necessary and run the JSW stub to install the service on the target system. For Unix you can just package it in tar.gz and provide instructions on how to install the service (copy the sh script into /etc/init.d, install it using chkconfig or any other system dependent tool for managing startup scripts). On Mac you should package it into dmg.
You may also try izpack if you want a more cross-platform solution. izpack can run from the java web start, as a native windows application or mac application, check the utilities page.
IzPack is a one-stop solution for packaging, distributing and deploying applications.
It is fully cross-platform and generates a single installer. As such, it is an alternative to native solutions such as platform-specific installers and package managers.
IzPack-generated installers only require a Java virtual machine to run.
You would need to build a release package for each operating system you were to release on.
For Windows, for example, you will need to find an executable wrapper. It's been a while since I've done this, but I remember usign a couple that would actually build an installer as part of the proccess.
Launch4j is one I've just remembered