java 带有 Maven 示例的嵌入式 Jetty 无法重新启动:地址已在使用中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37419969/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 02:29:21  来源:igfitidea点击:

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

javanetbeansjettyembedded-jettyjetty-9

提问by Alexander Farber

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

在 NetBeans 中尝试使用 Maven 示例重复运行嵌入式 Jetty 时,不幸的是我收到错误消息:

NetBeans screenshot

NetBeans 屏幕截图

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_REUSEADDRlimitation when binding listening sockets - then probably ServerSocket.setReuseAddress(true)would help.

如果根本原因是绑定侦听套接字时的SO_REUSEADDR限制 - 那么可能ServerSocket.setReuseAddress(true)会有所帮助。

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

但是在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:

我正在使用以下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:

Lars Gendner 是正确的,我的 Macbook 上确实有 HelloWorld 进程仍在运行:

# 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:

并且端口 8080 正在使用中:

# 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 killworkaround)

相反(作为 NetBeans 和 Jetty 新手)我想知道如何在 NetBeans 中正确停止嵌入式 Jetty?(除了awk /HelloWorld/ '{print $2}'| xargs kill解决方法)

UPDATE 2:

更新 2:

Adding jetty-maven-pluginto the pom.xmland runningmvn jetty:rundoes start a web server at port 8080, but it only displays the red text:

添加jetty-maven-pluginpom.xml并运行mvn jetty:run确实在端口 8080 启动了一个 web 服务器,但它只显示红色文本:

Directory: /

Here is the full Maven output:

这是完整的 Maven 输出:

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

采纳答案by Lucky

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

您应该添加jetty-maven-plugin到您的 pom 并尝试停止服务器。jetty stop 目标查找插件配置。请参阅此码头文档Jetty Stop 目标

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.

stop 目标会停止一个正在运行的 jetty 实例。要使用它,您需要使用特殊的端口号和密钥配置插件。启动 jetty 的其他目标也将使用相同的端口号和密钥。

Here's the plugin configuration for jetty-stop,

这是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,

在jetty启动后,发出以下命令,

mvn jetty:stopmvn jetty:stop

or simply try the

或者干脆试试

mvn jetty:stop

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

mvn jetty:run命令将启动服务器。对于其他目标/配置,请参阅配置 Jetty Maven 插件

回答by Lars Gendner

I am pretty sure that you already have a process running on port 8080. If you track down that process and end it (maybe you are trying to start Jetty twice instead of ending an already running Jetty instance properly?), your process should start just fine.

我很确定您已经有一个在端口 8080 上运行的进程。如果您跟踪该进程并结束它(也许您试图启动 Jetty 两次而不是正确结束已经运行的 Jetty 实例?),您的进程应该刚刚开始美好的。

You can also try and use some other port instead of 8080 (e.g. 8090).

您也可以尝试使用其他端口而不是 8080(例如 8090)。