Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The reason why java process started by Maven cannot be stopped by Ctrl+C on Windows

Tags:

java

maven

tomcat

I created an executable Tomcat jar application that can be run by Maven (mvn clean install exec:exec). This application can be stopped by Ctrl+C on Linux. However, it cannot on Windows. Does anyone know the reason and solution?

Environment:

$ mvn -version
Apache Maven 3.2.2 (45f7c06d68e745d05611f7fd14efb6594181933e; 2014-06-17T22:51:42+09:00)
Maven home: c:\apache-maven-3.2.2
Java version: 1.8.0_121, vendor: Oracle Corporation
Java home: c:\Program Files\Java\jdk1.8.0_121\jre
Default locale: ja_JP, platform encoding: MS932
OS name: "windows 7", version: "6.1", arch: "amd64", family: "dos"

Excerpt of pom.xml:

<plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.1</version>
    <executions>
        <execution>
            <id>tomcat-run</id>
            <goals>
                <goal>exec-war-only</goal>
            </goals>
            <phase>package</phase>
            <configuration>
                <path>/</path>
                <enableNaming>true</enableNaming>
                <finalName>embtest.jar</finalName>
                <charset>utf-8</charset>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.6</version>
    <configuration>
        <failOnMissingWebXml>false</failOnMissingWebXml>
        <warName>ROOT</warName>
    </configuration>
</plugin>
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.2.1</version>
    <executions>
        <execution>
            <id>startup-uber-tomcat</id>
            <phase>install</phase>
            <goals>
                <goal>exec</goal>
            </goals>
            <configuration>
                <classpathScope>test</classpathScope>
                <executable>java</executable>
                <arguments>
                    <argument>-jar</argument>
                    <argument>target/embtest.jar</argument>
                </arguments>
            </configuration>
        </execution>
    </executions>
</plugin>

Steps to reproduce:

(1) Run the commands on Windows:

$ git clone https://github.com/k-tamura/embtest.git
$ cd embtest
$ mvn clean install exec:exec

(2) Access to http://localhost:8080 -> Main page is displayed.

(3) Press Ctrl+C

(4) Access to http://localhost:8080 -> Main page is still displayed (Tomcat is not stopped).

like image 992
Kohei TAMURA Avatar asked Jun 01 '17 04:06

Kohei TAMURA


1 Answers

What actually happens when you start mvn is that you start a JVM instance outside the bash process. The output IS redirected to bash.

To avoid this, and maintain control over your bash shell, is to start the process in the background by adding &

$ mvn clean install exec:exec&

After this, you get output from the process. You can find the processes PID in the Windows context (!) by issuing ps

$ ps
      PID    PPID    PGID     WINPID   TTY         UID    STIME COMMAND
     1475    1474    1475      15204  pty0      197610 10:38:32 /usr/bin/bash
     1666    1475    1666      18688  pty0      197610 10:54:48 /c/Program Files/AdoptOpenJDK/jdk-11.0.7.10-openj9/bin/java
     1685    1475    1685       4524  pty0      197610 10:54:57 /usr/bin/ps
     1474       1    1474      15544  ?         197610 10:38:32 /usr/bin/mintty

Here you can see that the Windows PID is 18688 for the Java runtime.

Now, you can kill this process by issuing taskkill on it, with the -f (force) option parameter:

$ taskkill -pid 18688 -f
SUCCESS: The process with PID 18688 has been terminated.
[1]+  Exit 1                  ./mvnw spring-boot:run

But the underlying Tomcat (or whatever servlet you're using) may still be running, if it has been started from the parent java session. To effectivly kill all (note: ALL) java processes, issue taskkill with -f on processes with the java.exe image name:

taskkill -im "java.exe" -f
SUCCESS: The process "java.exe" with PID 14452 has been terminated.
SUCCESS: The process "java.exe" with PID 12380 has been terminated.
[1]+  Exit 1                  ./mvnw spring-boot:run

It's litterally an overkill, but you're sure nothing java is running anymore.

like image 143
GerardV Avatar answered Nov 15 '22 00:11

GerardV