I have this somewhat unusual process structure:
Launch4J starts my Java application. It creates a mutex to provide single-instance functionality for the Java application.
The Java application starts a VB6 application, which can have multiple instances.
When the Java application terminates, the VB6 application is still running. (Desired behaviour)
The problem is: The mutex created by Launch4J is only released after the VB6 application terminates. Because of that it's impossible to start the Java application again.
Why would this happen? I'm not opening the mutex explictly...
I first suspected it is because of Java using CreateProcess with bInheritHandles == true, but the problem does not occour when I start notepad.exe for example.
EDIT: I still have this problem. Any pointers are appreciated!
Does Launch4J release the mutex and close its handle before terminating? I'm sorry, but I don't know how Java wraps the OS Mutex functions, but you should ensure you explicitly release the mutex and close its handle before your thread ends.
I faced the same kind of issue and realized that Launch4J creates an inheritable mutex on startup and when launching a process from withing the JVM, this mutex is then inherited by the new process.
After JVM shutdown the mutex is still held by the new process.
The simplest solution I found to avoid the mutex to be inherited is to use an intermediate program that launches a process as a detached process without inheriting the parent handles.
A working c++ example of this program can be found here https://stackoverflow.com/a/1582197/6894604
Just compile the program (“ex: rujob.exe”) using a c++ compiler and change your command to use the launcher instead of directly calling the process, for example :
new ProcessBuilder().command(
"runjob.exe",
"vbprogram.exe",
"/PARAM1",
"/PARAM2").start();
This way your VB program will not inherit the java application mutex and will not prevent your java app to start again.
Why don't you provide single instance functionality using VB instead of java? IMO it is wrong to provide single instance for the VB app using Launch4j. There are other ways, check this:
https://www.vbforums.com/showthread.php?342810-Classic-VB-How-can-I-allow-only-one-instance-of-my-application-to-run-at-a-time
Related
I'm in the early stages of developing an API in C++, which I'm wrapping in Java using JNI. The native code creates a socket listener thread using WinAPI which should run indefinitely, thereby keeping the program open indefinitely (tested and works fine).
However, when I try to invoke this code in Java, the JVM still terminates when it reaches the end of main, ignoring the running thread. A little research has hinted that Java might think the thread is a daemon rather than a "user thread". But if that's the case, then I can't quite figure out how to convince Java that it actually is a user thread.
Does anyone have a clue about this?
You need to call AttachCurrentThread() for all your native threads, to ensure Java knows about them, so it will wait for them to finish.
Windows doesn't have daemon threads. The process exits when ExitProcess() is called or when the initial thread returns from the application's main function. (In principle, it will also exit if the last thread exits, but that can't be relied upon because Windows may create threads in your process that you don't know about.)
The Java runtime presumably waits for all of its own threads to exit (except for those that it considers daemon threads) before exiting the process. But your threads were created directly via the Win32 API, so Java doesn't know about them and therefore won't wait for them.
If your API wants to continue performing some task beyond the natural lifetime of the calling process, it should probably create a child process rather than a thread. (Or, if the API is Java-specific, it can presumably make use of JNI to ask that Java create the thread on its behalf, or to register the thread with Java.)
I know that threads and processes are related, and that threads are a small unit
of process. But I doubt that, how to implement a process using simple java code?
Please show me some code for doing this.
Thanks in advance.
You cannot implement a process using Java. Each Java program
runs within a single OS process; this OS process is the JVM.
If you want another process, start another (or the same) Java
program in another JVM instance.
I need to pass a signal from a .NET app to a Java app. No data is required, the signal itself is enough.
The most simple way that comes to my mind is by using a named synchronization object like this:
The .NET app creates a certain named synchronization object A.
The Java app creates a certain named synchronization object A - the name is the same as in (1).
The Java app has a thread waiting on the object to become signaled.
The .NET app signals the object.
The Java app thread awakens and acts upon the signal reception.
At least, this how I would do it if I knew how to create a named synchronization object in Java.
But looks like Java does not have any, which I find hard to believe. Does it mean that only Windows has named synchronization objects?
So, my question is this - how do I pass a simple signal (no data) from a non Java app to a Java app on Windows? Both processes run on the same host.
EDIT
Motivation - I want to signal to our headless Java process to terminate itself gracefully as soon as it can do so.
you can create a socket connection between your programs, and by send and receive specific pattern you can detect signal
I second thought, that i had done before by using ICE Framework, you can download and learn the ICE Framework from here,
ICE Framework is a cross framework for communication between processes a local system or on a network.
Download Ice Framework
For God's sake, I just want a single 1 bit signal from a C++/C# process to a Java process and there is no simple way to do it. I can't believe it.
Forget about it, I'll just use the file system. The C++/C# code is going to create an empty file at a well known location, which the Java code is going to poll every second.
Finito, end of story.
I have a program 'foo' running different threads, fooT1, fooT2, .. fooTn.
Now if I want write another program 'bar', which could kill the thread fooTr, is that possible?
Reason: One of the thread fooTr tracks product license. If this thread is killed; one may run this product indefinitely. And killing 'foo' itself is tolerable as 'foo' as that is exactly what is being done on license expiry.
System: Fedora Distribution of Linux
Note: The commands which start JVM and program foo are placed in /etc/init.d and anyone who has a decent knowledge of rc.1/rc.2/rc.3 structure can change/add the starting parameters to these.
I hope my question is clear. If not, I can always edit it.
Actually the java debugger will allow you to kill a thread by injecting an exception into it. I was just trying to work out how to use this feature to kill a thread without wiping out the whole jvm, when I came across this question. If you run the jvm with command line options like:
java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8888 your.app.Main
and connect the debugger with something like:
jdb -attach 127.0.0.1:8888
you can type:
threads
to get a list of the running threads, and use the kill command to kill a running thread. The bit I'm currently not sure about is the syntax of this kill command, I have tried the obvious:
kill 0xe2e new java.lang.IllegalArgumentException("er");
and I get the messages:
killing thread: Swank REPL Thread
Thread not suspended
Expression must evaluate to an object
("Swank REPL Thread" is the thread I want to kill, and yes, I've tried suspending it first ;)
Still my inability to use the java debugger aside, it looks to me like a thread can be killed at random. Maybe you can just make sure you ignore all exceptions and keep running and that will be enough, but I'm not sure about that.
To my knowledge it is not possible to do this directly. What you could consider however is to create some kind of service on your 'foo' that can be called from 'bar' to kill the thread. There are, of course, hundreds of ways to implement this. My first thought would be to do this using RMI.
You could do this even without a separate application. Write your own startup class, which performs a pass-through of parameters to the original startup class of the application. Your class's main method though would create a thread that periodically checks the list of all threads (e.g., Thread.getAllStackTraces or Thread.enumerate), finds the offending thread, and invokes stop() on it. Although Thread.stop is deprecated, it still works.
Another option is to run the application under a Java debugger, say, jdb and then suspend/kill the required thread. You could also add parameters to the application's startup so that the JVM can be attached to, then attach jdb to the running JVM and suspect/kill the thread.
Until now isn´t possible to run to diferent programs in the same JVM, but some people is investigating it, in order to reduce the startup time and the memory and cpu usage of diferent java programs runing in the same machine
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)