Search code examples
javanetbeansjettyembedded-jettyjetty-9

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 runningmvn 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)

Solution

  • 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