exec-maven-plugin
exec-maven-plugin copied to clipboard
Maven exec plugin java goal with RMI exits early
The org.codehaus.mojo:exec-maven-plugin:3.3.0
plugin “java” goal documentation states that “daemon threads are joined and interrupted once all known non daemon threads have quit”. That is not what I observe with some code involving an RMI thread (except that I do not know what is an “unknown” thread). It looks like either a bug or a problem in the documentation.
Details
My “Server” program starts a non-daemon thread (through RMI) and when I run it using the “java” goal, the JVM exits when reaching the end of the main
method. I’d expect that it keeps running due to the non daemon thread still running. When I run it using direct invocation of java
, as expected, the program keeps running even after main
finishes.
Code
Here is the Server.
public class Server {
public static void main(String[] args) throws Exception {
Registry registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
RemoteTest engine = new RemoteTestImpl();
RemoteTest stub = (RemoteTest) UnicastRemoteObject.exportObject(engine, 0);
registry.rebind("RemoteTestJ2", stub);
Thread.sleep(3000);
Thread.getAllStackTraces().keySet().forEach(thread -> {
System.out.println("Thread: " + thread.getName() + " is daemon: " + thread.isDaemon());
});
}
}
Here is the Client.
public class User {
public static void main(String[] args) throws Exception {
Registry registry = LocateRegistry.getRegistry(Registry.REGISTRY_PORT);
RemoteTest rem = (RemoteTest) registry.lookup("RemoteTestJ2");
while(true) {
System.out.println("Tested: " + rem.test(0, 1));
}
}
}
The full code is here.
Reproduce the problem
-
git clone https://github.com/oliviercailloux/JGradLib-Additioner.git ; cd JGradLib-Additioner ; git checkout rmistop
- Start Server:
mvn -Dexec.mainClass=io.github.oliviercailloux.javagrade.graders.Server compile org.codehaus.mojo:exec-maven-plugin:3.3.0:java
. - Start Client (in parallel, just after having started Server):
java -cp "target/classes/" io.github.oliviercailloux.javagrade.graders.User
.
Expected: The RMI mechanism starts a non-daemon thread in the background and prevents exit of the JVM, so that the Server stays alive indefinitely and the Client prints forever the result of the test
call.
Actual: the Server starts, RMI starts a non-daemon thread as expected (as well as daemon threads), the Server sleeps for three seconds, prints its threads, and exits. The Client, meanwhile, starts flooding the terminal with results of the test
calls, but after three seconds, crashes with a stack trace complaining that it cannot reach the remote end any more.
Variants with no problem
Both the exec
plugin and the RMI aspect seem required to trigger this odd behavior.
If running the server with java -cp "target/classes/" io.github.oliviercailloux.javagrade.graders.Server
instead of the exec
plugin, the server keeps running as expected. Same if I use exec:java
(with appropriate options).
Alternatively, if I change the server code to simply start a new Thread that is kept busy (sleeps in a while loop), the server keeps running as expected.
Also posted on SO.