I need to run .exe file, and after launching this file execute some script once the process is loaded and running, before it has terminated. So script will throw an exception if previous .exe is not fully loaded..
How I can know that .exe file is fully loaded?
I can use Timer to schedule script execution to some time, but it's not good idea, because .exe file may still not be launched after some scheduling time.
Check out Apache Commons Exec which handles a lot of the pain of process launching. In particular look at the DefaultExecuteResultHandler, which will get a callback when the launched process exits. So long as you don't receive that callback your launched process is still running.
Note (in case it's not clear) that if your Java process launches an executable it will get an immediate callback when that process dies, provided Process.waitFor() has been called.
As the last thing in your exe files duty create a file in a shared location. Check for the file from your other code. So that shared file will act as the lock.
You could check the list of running processes regularly until you find the executable in the list - once you see it you know it has been launched.
Note: if the executable ends after 1 second for example, and you check the processes every 10 seconds, you might miss it.
Related
I use Windows.
I have a java application wrapped in an exe with launch4j. When I run it, I see two processes in my task manager: the exe wrapper, and the underlying java. When the program ends, both processes disappear.
When I run the exe with the command line, if I want to stop the process prematurely, I Ctrl-C, and both processes are terminated.
But in some cases, the program is run by another java application, with the process api. In this case, if the application must be stopped prematurely, I tried using myProcess.destroy(), but only the exe wrapper was stopped, the underlying java continued to run. I also tried destroyForcibly() with the same result.
Why the difference in behavior? How can I really emulate the behavior of Ctrl-C and kill both processes?
I have a Java application that needs to run several times. Every time it runs, it checks if there's data to process and if so, it processes the data.
I'm trying to figure out what's the best approach (performance, resource consumption, etc.) to do this:
1.- Launch it once, and if there's nothing to process make it sleep (All Java).
2.- Using a bash script to launch the Java app, and when it finishes, sleep (the script) and then relaunch the java app.
I was wondering if it is best to keep the Java app alive (sleeping) or relaunching every time.
It's hard to answer your question without the specific context. On the face of it, your questions sounds like it could be a premature optimization.
Generally, I suggest you do what's easier for you to do (and to maintain), unless you have good reasons not to. Here are some possible good reasons, pick the ones appropriate to your situation:
For sleeping in Java:
The check of whether there's new data is easier in Java
Starting the Java program takes time or other resources, for example if on startup, your program needs to load a bunch of data
Starting the Java process from bash is complex for some reason - maybe it requires you to fiddle with a bunch of environment variables, files or something else.
For re-launching the Java program from bash:
The check of whether there's new data is easier in bash
Getting the Java process to sleep is complex - maybe your Java process is a complex multi-threaded beast, and stopping, and then re-starting the various threads is complicated.
You need the memory in between Java jobs - killing the Java process entirely would free all of its memory.
I would not keep it alive.
Instead of it you can use some Job which runs at defined intervals you can use jenkins or you can use Windows scheduler and configure it to run every 5 minutes (as you wish).
Run a batch file with Windows task scheduler
And from your batch file you can do following:
javac JavaFileName.java // To Compile
java JavaFileName // to execute file
See here how to execute java file from cmd :
How do I run a Java program from the command line on Windows?
I personally would determine it, by the place where the application is working.
if it would be my personal computer, I would use second option with bash script (as resources on my local machine might change a lot, due to extensive use of some other programs and it can happen that at some point I might be running out of memory for example)
if it goes to cloud (amazon, google, whatever) I know exactly what kind of processes are running there (it should not change so dynamically comparing to my local PC) and long running java with some scheduler would be fine for me
I have a cluster with 2 nodes and a shared file system. Each of these nodes runs has a java process that runs periodically. That process accesses the file system and handles some files and after the processing it deletes those files.
The problem here is that only one of the schedules processes should access the files. The other process should, if the first process runs, skip the execution.
My first attempt to solve this issue to create a hidden file .lock
. When the first process starts the execution it should move the file
into another folder and start handling files. When the other
scheduled process starts the execution it first checks if the .lock
file is present and if it isn't the process skips the execution.
When the first process finishes the execution it moves the .lock
file back to its original folder. I was using the Files.move()
method with ATOMIC_MOVE option but after a certain amount of time I
got unexpected behaviour.
My second attempt was to use a distributed lock like Hazelcast. I did some tests and it seems ok but this solution seems a bit complicated for a task that is this simple.
My question is: Is there any other smarter/simpler solution for this problem or my only option is to use Hazelcast? How would you solve this issue?
I have few java application running 24/7. I'd like to write another java application, which checks if any of this applications crashes or not. If some application has crashed i'd like to restart it. Is there any solutions for this?
I see some ways but there should be better ways to do it :
If you have control over your running applications you can make each of them listen to a given port on the machine and reply to any request on it. Then you can simply ping that port to see if the app is running.
If you launch the apps by yourself you can store their pid and then check if the process with that pid is still alive.
Each app can create a file and update it regularly. Then your monitoring app can check if the file has been updated. if not, then the app is dead.
What i can think is you can define a new custom exception in those 24/7 running programs, add that exception to blocks where you think crash can occur, and then call some method of the another java application when this exception is called by the crash.
You can use wmic utility.
Like this : Process proc = Runtime.getRuntime().exec("wmic.exe");
Then you may check for the different params associated with your java app (javaw.exe) application.
You can perhaps use the ( http://quartz-scheduler.org/ ) Quartz scheduler, or the java.util.Timer api to wake up recurrently.and check for the process. Ever time u run the process I believe u can get the PID or process ID which can be stored.
Wake up at regular intervals and invoke a shell sript to check if the process is running. If not then spawn new Process using Runtime.getRuntime()
If you can use a simple solution, your application must update an external resource from inside the core functionality of the application. If the external resource is not updated for a while, you know that the core of your application has stopped.
If you use a separate thread to update the resource, your core functionality will crash but the thread keeps on running and you detect nothing.
The external resource can be a file. Write the current time stamp there. If the time stamp is not updated for a while, then the app has crashed. Or write to a network socket if your monitor is on a separate machine to detect hardware crashes (a monitor is pretty useless if it crashes with your application).
Your monitor must know the process identifier of the Java process so that it can kill it and restart it when needed. you can write the process identifier into a file if you start the app from a shell script.
There exists a billion dollar industry that produces this kind of software monitors. It is not a trivial task.
I need to spawn a process in Java (under Linux exclusively) that will continue to run after the JVM has exited. How can I do this?
Basically the Java app should spawn an updater which stops the Java app, updates files and then starts it again.
I'm interested in a hack & slash method to just get it working as well as a better design proposal if you have one :)
If you're spawning the process using java.lang.Process it should "just work" - I don't believe the spawned process will die when the JVM exits. You might find that the Ant libraries make it easier for you to control the spawning though.
It does actually "just work", unless you're trying to be clever.
My wrapped java.lang.Process was trying to capture the script's output, so when the JVM died, the script didn't have anywhere to send output so it just dies. If I don't try to capture the output, or the script doesn't generate any or redirects everything to a file or /dev/null, everything works as it should.
I was having trouble with this and the launched process was getting killed when the JVM shutdown.
Redirecting stdout and stderr to a file fixed the issue. I guess the process was tied to the launched java app as by default it was expecting to pass its output to it.
Here's the code that worked for me (minus exception handling):
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectOutput(logFile);
pb.redirectError(logFile);
Process p = pb.start();
I thought the whole point of Java was that it's fully contained within the JVM. It's kinda hard to run bytecode when there's no runtime.
If you're looking to have a totally separate process you might look into trying to start a second java.exe instance. Although for your application, it might be easier to simply make a synchronized block that stops (but doesn't kill) your app, does the updating, and then re-initializes your app's data.
It won't always "just work". When JVM spawns the child and then shuts down, the child process will also shutdown in some cases. That is expected behaviour of the process. Under WIN32 systems, it just works.
E.g. If WebLogic server was started up by a Java process, and then that process exits, it also sends the shutdown signal to the WebLogic via shutdown hook in JVM, which causes WebLogic to also shutdown.
If it "just works" for you then there is no problem, however if you find yourself in a position that child process also shutsdown with JVM it is worth having a look at the "nohup" command. The process won't respond to SIGTERM signal, but will respond to SIGKILL signal, as well as normal operations.
Update: The way described above is a bit of an overkill. Another way of doing this would be to use "&" on the end of command. This will spawn a new process that is not a child of current java process.
P.S. Sorry for so many updates, I have been learning and trying it from scratch.
>>don't believe the spawned process will die when the JVM exits.
Child process is always dying on my box(SuSE) whenever I kill java. I think, the child process will die if it's dealing with I/O of the parent process(i.e., java)
If you're looking at making an updater on Linux, you're probably barking up the wrong tree. I believe all major linux distros have a package manager built in. You should use the package manager to do your updating. Nothing frustrates me more than programs that try to self-update... (I'm looking at you, Eclipse)