Docker entrypoint.sh for self-updating programs - java

I want to run a (java) application in a docker container. This application has an update functionality. This is run automatically on startup and can be triggered manually from the (web) GUI. The update downloads the new files, then runs the new executable (with new PID) and exits itself.
Usually, I use the exec java -jar MyProgram.jar "$#" in entrypoint.sh. This will stop the container when an update occurs (because PID=1 exits).
Just using the line without exec does not correctly forward SIGTERM/SIGKILL for docker stop. While forwarding these signals is possible as explaned here in program.sh, I don't know how to track PIDs when an update occurred and a new process is spawned.
Update: Since I am not the developer of the application, I am looking for a solution without modifying the applications.
Update 2: I found out that the application creates a MyProgram.pid file which I can read to kill it with the help of a trap as explained in program.sh linked above.

Typically we bake jars into an image. If we update the jars in a container at runtime, when we stop the container we lose those changes. Normal upgrade practice is to update your app spec with the new jars and rebuild it into an image using a pipeline of some sort, then replace your containers with the new ones.

Related

How to track a program/process is running in Ubuntu?

I need to find a way to track that a program P is running. My program is in an Ubuntu docker container, it is a java one. I need another program to periodically tell me that my program P is running. If it fails to send me that message I will have to re-start the program. Is there a way to find out this? We are afraid that the program or the docker container could stop running and affect the user experience.
Though, the question is to broad to be answered clearly I'll try to offer some solutions.
First of all, if your java process 'fails' the container will end it's work. Based on this you can identify if your app is running simply by performing docker ps.
If you want some handwritten solution you can implement a health-check rest endpoint in you application and hit it periodically to ensure the app is running.
you could setup a restart policy on the docker container, that way if java encounters an exception and exits, it will automatically try to restart the container.
In the docker run command, just add --restart unless-stopped, this way it will always try to restart unless a stop command was send by docker itself.
more information on this functionality can be found at:
https://docs.docker.com/config/containers/start-containers-automatically/#restart-policy-details

Let java program run indefinitely - restart when it crashes

I have a java program that should run on a Windows machine. It should run "forever", i.e. when the JVM or the program crashes, it should be restarted. When the computer is restarted it should also be restarted.
I saw advice to wrap the program as a "Windows service", but the tools I found seem to be either costly, complicated or outdated.
Can somebody describe me a straightforward way to achieve the desired behaviour?
For the part where you want to start the program after restart you can create a simple batch (.Bat) file and u can put that file in the startup folder.
Also you can use the same file for running the program when it crashes. you can use tasklist command and check if your java program is running and if it is not .just start the program.
Just check our windows batch this is one of the best things you can get everything for doing anything on windows without anything expensive
Yet Another Java Service Wrapper is a tool that easily wraps your Java program into a Windows service. Just start the program, note down the PID and enter it into the wrapper. Two things, which are probably universal to services, should be noted:
For connection to the network, you need to specify an account with the necessary rights.
Connected network drives are not available.

How to start Tanuki Software Wrapper automatically on interval of 2 hours

I am using Tanuki Software Wrapper for building a java application as Windows Service . I follow the example Simple HelloWorldServer Java Class and it works fine . I have made configure in wrapper.conf file wrapper.ntservice.starttype = AUTO_START for automatically starting the service on windows system starting .
But i want that my service would be automatically started on every two hours , how can i do it , if any one has idea please help me .
Thanks a lot in advance .
Finally I have done through following configuration in the wrapper.conf file as
wrapper.pausable=TRUE
wrapper.pause-on-startup=TRUE
wrapper.timer.1.interval=minute=120
wrapper.timer.1.action=restart, resume
wrapper.on_exit.default=PAUSE
It basically pause the wrapper action after main jvm(java application) is closed , and then after 2 hours it automatically restart wrapper's local JVM and resume the required output with updated data .
Thanks to all for trying to help me .
It's better to keep your java application running, and schedule tasks from within your application.
E.g. use http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html
If you schedule a task in your main() method, a new Timer Thread is started, so the application will keep running after the main() has ended, and keep executing the scheduled task at the rate you specified.
Ajeet,
As GreyFairer said, it is usually a good idea to run tasks from within the JVM, especially if they happen often.
The Wrapper's ability to stop and start the JVM using the pausable feature definitely works as well. This approach can be better if your JVM is large, and the task it needs to complete is relatively infrequent. There is a bit of load to launch a JVM.
Relaunching the JVM as you are doing also has the benefit of allowing you to change the configuration for each invocation if you combine configuration include files with the wrapper.restart.reload_configuration=TRUE property. You can modify the include file as needed so each JVM runs with the needed information. (There are of course ways of getting the same results within a single JVM invocation if needed.)
Cheers, Leif

java.io.IOException: Access is denied

I need to update my application. To do this, I delete the .jar file my program is currently running from and create a new one with the same name, then restart the application.
However, when I attempt to do this I get a java.io.IOException: Access is denied.
How can I fix this?
Thanks!
The problem is, the jar files are been used by the JVM (specifically, the class loaders). Even under Java 7, where the jar files are closed by the class loaders when the are no longer needed, there is no guarantee that the underlying resources will be released, or more specifically, when they will be released.
For some more information, take a look at Closing a URLClassLoader
You have a few choices.
You Could...
Separate your update process from your application (so it's a standalone program) and use parentless execution process to update the application. This involves executing your program in such away that it allows the current process to terminate before the new process, under windows this can be achieved using something like...
cmd /c start /b /normal "" {command line to be executed}
Under Linux I believe you can use nohup, but I have no experience with that.
(Don't forget to use System.exit to terminate the current process ;))
You Could...
You could use Java Web Start which provides it's own updating capabilities

Stopping a daemon thread on the AS400 using QShell

I have a java program which I start with the comman java -jar MyProgram.jar, and I can stop the java program using the command java -jar MyProgram.jar stop. I am having trouble running my command in the same shell because the previous program is running, is there another way to open another QShell or a way to run another command in the same shell?
Qsh does not support job control, and you can only open one for each session.
The easiest is to open yet another green screen session and run a second qsh inthere
Note that typing SysReq-2 stops the current program, too.
A daemon is presumably intended to be a long-running background service. As such, you would normally be submitting this to run in a some batch subsystem. You would normally use ENDJOB on it from another session.
See your system administrator for details on where they want your job to run on this particular system. There are various options, and testing may be different than how they wish it to run in production.

Categories