Alexander Farber Alexander Farber - 5 months ago 80
Java Question

Embedded Jetty with Maven example fails to restart: Address already in use

When trying to repeatedly run the Embedded Jetty with Maven example in NetBeans, I unfortunately get the error:

NetBeans screenshot

cd /Users/afarber/src/JettyMavenHelloWorld; JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home "/Applications/NetBeans/NetBeans 8.1.app/Contents/Resources/NetBeans/java/maven/bin/mvn" "-Dexec.args=-classpath %classpath org.example.HelloWorld" -Dexec.executable=/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
Running NetBeans Compile On Save execution. Phase execution is skipped and output directories of dependency projects (with Compile on Save turned on) will be used instead of their jar artifacts.
Scanning for projects...

------------------------------------------------------------------------
Building Jetty HelloWorld 0.1-SNAPSHOT
------------------------------------------------------------------------

--- exec-maven-plugin:1.2.1:exec (default-cli) @ hello-world ---
2016-05-24 19:01:26.748:INFO:oejs.Server:main: jetty-9.0.2.v20130417
2016-05-24 19:01:26.817:WARN:oejuc.AbstractLifeCycle:main: FAILED ServerConnector@7591083d{HTTP/1.1}{0.0.0.0:8080}: java.net.BindException: Address already in use
java.net.BindException: Address already in use
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:437)
at sun.nio.ch.Net.bind(Net.java:429)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at org.eclipse.jetty.server.ServerConnector.open(ServerConnector.java:227)
at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:80)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:69)
at org.eclipse.jetty.server.Server.doStart(Server.java:309)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:69)
at org.example.HelloWorld.main(HelloWorld.java:29)
2016-05-24 19:01:26.818:WARN:oejuc.AbstractLifeCycle:main: FAILED org.eclipse.jetty.server.Server@77a567e1: java.net.BindException: Address already in use
java.net.BindException: Address already in use
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:437)
at sun.nio.ch.Net.bind(Net.java:429)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at org.eclipse.jetty.server.ServerConnector.open(ServerConnector.java:227)
at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:80)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:69)
at org.eclipse.jetty.server.Server.doStart(Server.java:309)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:69)
at org.example.HelloWorld.main(HelloWorld.java:29)
Exception in thread "main" java.net.BindException: Address already in use
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:437)
at sun.nio.ch.Net.bind(Net.java:429)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at org.eclipse.jetty.server.ServerConnector.open(ServerConnector.java:227)
at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:80)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:69)
at org.eclipse.jetty.server.Server.doStart(Server.java:309)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:69)
at org.example.HelloWorld.main(HelloWorld.java:29)


If the root cause for this is the SO_REUSEADDR limitation when binding listening sockets - then probably
ServerSocket.setReuseAddress(true)
would help.

But how and where to call it in the HelloWorld.java?

package org.example;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;

public class HelloWorld extends AbstractHandler
{
public void handle(String target,
Request baseRequest,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
response.setContentType("text/html;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
baseRequest.setHandled(true);
response.getWriter().println("<h1>Hello World</h1>");
}

public static void main(String[] args) throws Exception
{
Server server = new Server(8080);
server.setHandler(new HelloWorld());
server.start();
server.join();
}
}


I am using the following pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>hello-world</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Jetty HelloWorld</name>

<properties>
<jettyVersion>9.3.9.v20160517</jettyVersion>
</properties>

<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jettyVersion}</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution><goals><goal>java</goal></goals></execution>
</executions>
<configuration>
<mainClass>org.example.HelloWorld</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>


UPDATE:

Lars Gendner is correct and I do have HelloWorld processes still running at my Macbook:

# ps -ef | grep HelloWorld
501 944 1 0 6:58pm ?? 0:04.20 /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java -classpath /Users/afarber/src/JettyMavenHelloWorld/target/classes:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-server/9.0.2.v20130417/jetty-server-9.0.2.v20130417.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/orbit/javax.servlet/3.0.0.v201112011016/javax.servlet-3.0.0.v201112011016.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-http/9.0.2.v20130417/jetty-http-9.0.2.v20130417.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-util/9.0.2.v20130417/jetty-util-9.0.2.v20130417.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-io/9.0.2.v20130417/jetty-io-9.0.2.v20130417.jar org.example.HelloWorld
501 948 1 0 6:58pm ?? 0:03.89 /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java -classpath /Users/afarber/src/JettyMavenHelloWorld/target/classes:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-server/9.0.2.v20130417/jetty-server-9.0.2.v20130417.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/orbit/javax.servlet/3.0.0.v201112011016/javax.servlet-3.0.0.v201112011016.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-http/9.0.2.v20130417/jetty-http-9.0.2.v20130417.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-util/9.0.2.v20130417/jetty-util-9.0.2.v20130417.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-io/9.0.2.v20130417/jetty-io-9.0.2.v20130417.jar org.example.HelloWorld


And the port 8080 is in use:

# netstat -an | grep -w 8080
tcp46 0 0 *.8080 *.* LISTEN


But of course I do not want to change port number again and again (and spawn more processes).

Instead (being NetBeans and Jetty newbie) I wonder how to properly stop embedded Jetty in NetBeans? (besides of
awk /HelloWorld/ '{print $2}'| xargs kill
workaround)

UPDATE 2:

Adding
jetty-maven-plugin
to the pom.xml and running
mvn jetty:run
does start a web server at port 8080, but it only displays the red text:

Directory: /


Here is the full Maven output:

# mvn jetty:run
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Jetty HelloWorld 0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] >>> jetty-maven-plugin:9.3.9.v20160517:run (default-cli) > test-compile @ hello-world >>>
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello-world ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/afarber/src/jetty-newbie/JettyMavenHelloWorld/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ hello-world ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file to /Users/afarber/src/jetty-newbie/JettyMavenHelloWorld/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ hello-world ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/afarber/src/jetty-newbie/JettyMavenHelloWorld/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ hello-world ---
[INFO] No sources to compile
[INFO]
[INFO] <<< jetty-maven-plugin:9.3.9.v20160517:run (default-cli) < test-compile @ hello-world <<<
[INFO]
[INFO] --- jetty-maven-plugin:9.3.9.v20160517:run (default-cli) @ hello-world ---
[INFO] Configuring Jetty for project: Jetty HelloWorld
[INFO] webAppSourceDirectory not set. Trying src/main/webapp
[INFO] webAppSourceDirectory /Users/afarber/src/jetty-newbie/JettyMavenHelloWorld/src/main/webapp does not exist. Trying /Users/afarber/src/jetty-newbie/JettyMavenHelloWorld/target/webapp-tmp
[INFO] Reload Mechanic: automatic
[INFO] Classes = /Users/afarber/src/jetty-newbie/JettyMavenHelloWorld/target/classes
[INFO] Logging initialized @3610ms
[INFO] Context path = /
[INFO] Tmp directory = /Users/afarber/src/jetty-newbie/JettyMavenHelloWorld/target/tmp
[INFO] Web defaults = org/eclipse/jetty/webapp/webdefault.xml
[INFO] Web overrides = none
[INFO] web.xml file = null
[INFO] Webapp directory = /Users/afarber/src/jetty-newbie/JettyMavenHelloWorld/target/webapp-tmp
[INFO] jetty-9.3.9.v20160517
[INFO] Started o.e.j.m.p.JettyWebAppContext@58a63629{/,file:///Users/afarber/src/jetty-newbie/JettyMavenHelloWorld/target/webapp-tmp/,AVAILABLE}{file:///Users/afarber/src/jetty-newbie/JettyMavenHelloWorld/target/webapp-tmp/}
[INFO] Started ServerConnector@75a118e6{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
[INFO] Started @4608ms
[INFO] Started Jetty Server
[INFO] Using Non-Native Java sun.nio.fs.PollingWatchService
[WARNING] Quiet Time is too low for non-native WatchService [sun.nio.fs.PollingWatchService]: 1000 < 5000 ms (defaulting to 5000 ms)

Answer

You should add jetty-maven-plugin to your pom and try stopping the server. The jetty stop goal looks for the plugin configuration. Please refer this jetty doc Jetty Stop goal

The stop goal stops a running instance of jetty. To use it, you need to configure the plugin with a special port number and key. That same port number and key will also be used by the other goals that start jetty.

Here's the plugin configuration for jetty-stop,

<plugin>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <version>@project.version@</version>
  <configuration>
    <stopPort>9966</stopPort>
    <stopKey>foo</stopKey>
    <stopWait>10</stopWait>
  </configuration>
</plugin>

And after jetty is started, issue the following command,

mvn jetty:stopmvn jetty:stop

or simply try the

mvn jetty:stop

And mvn jetty:run command would start the server. For other goals/configurations please refer to Configuring Jetty Maven plugin

Comments