Fixing Forked Jetty Stop Issues | Generated by AI

Home 2025.09

You actually did most things right—the hang is almost always because the stop goal can’t reach the forked Jetty (wrong stopHost/port/key scope) or because run-forked keeps Maven attached unexpectedly. Two solid fixes below; pick one.

Option A — Reliable pattern: jetty:start (daemon) + jetty:stop

This avoids run-forked entirely and is the most stable for IT lifecycles.

What to change

  1. Pin the plugin version and use start with daemon=true in pre-integration-test.
  2. Keep your Python ITs in integration-test.
  3. Use stop in post-integration-test.
  4. Provide the same stopHost/stopPort/stopKey in both executions.
<plugin>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <version>9.4.54.v20240208</version>

  <configuration>
    <httpConnector>
      <port>8080</port>
      <host>127.0.0.1</host>
    </httpConnector>
  </configuration>

  <executions>
    <execution>
      <id>start-jetty</id>
      <phase>pre-integration-test</phase>
      <goals>
        <goal>start</goal>
      </goals>
      <configuration>
        <daemon>true</daemon>
        <stopHost>127.0.0.1</stopHost>
        <stopPort>8081</stopPort>
        <stopKey>stop</stopKey>
        <jvmArgs>
          -javaagent:${settings.localRepository}/org/jacoco/org.jacoco.agent/${jacoco.version}/org.jacoco.agent-${jacoco.version}-runtime.jar=destfile=${jacoco.it.exec},append=true
        </jvmArgs>
        <webApp>
          <contextPath>/</contextPath>
        </webApp>
      </configuration>
    </execution>

    <execution>
      <id>stop-jetty</id>
      <phase>post-integration-test</phase>
      <goals>
        <goal>stop</goal>
      </goals>
      <configuration>
        <stopHost>127.0.0.1</stopHost>
        <stopPort>8081</stopPort>
        <stopKey>stop</stopKey>
        <stopWait>15</stopWait>
      </configuration>
    </execution>
  </executions>
</plugin>

Why this fixes the “stuck”


Option B — Keep run-forked, but make stop actually work

If you prefer run-forked, the common pitfalls are:

Tighten config like this:

<plugin>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <version>9.4.54.v20240208</version>

  <executions>
    <execution>
      <id>start-jetty</id>
      <phase>pre-integration-test</phase>
      <goals>
        <goal>run-forked</goal>
      </goals>
      <configuration>
        <stopHost>127.0.0.1</stopHost>
        <stopPort>8081</stopPort>
        <stopKey>stop</stopKey>
        <stopWait>15</stopWait>

        <httpConnector>
          <host>127.0.0.1</host>
          <port>8080</port>
        </httpConnector>

        <jvmArgs>
          -javaagent:${settings.localRepository}/org/jacoco/org.jacoco.agent/${jacoco.version}/org.jacoco.agent-${jacoco.version}-runtime.jar=destfile=${jacoco.it.exec},append=true
        </jvmArgs>
        <webApp>
          <contextPath>/</contextPath>
        </webApp>
      </configuration>
    </execution>

    <execution>
      <id>stop-jetty</id>
      <phase>post-integration-test</phase>
      <goals>
        <goal>stop</goal>
      </goals>
      <configuration>
        <stopHost>127.0.0.1</stopHost>
        <stopPort>8081</stopPort>
        <stopKey>stop</stopKey>
        <stopWait>15</stopWait>
      </configuration>
    </execution>
  </executions>
</plugin>

Extra guardrails


Optional safety net — kill the child if stop fails

Add a tiny helper to forcibly kill the forked Jetty by PID written to a file:

  1. In run-forked/start config:
<pidFile>${project.build.directory}/jetty.pid</pidFile>
  1. After post-integration-test, add an exec-maven-plugin in verify that checks the pid file and nukes the process if it’s still alive.

A couple of minor notes from your log


If you want, paste your full Jetty plugin block + any settings.xml mirrors (for local repo path) and I’ll tailor the exact minimal diff for your repo.


Back Donate