【问题标题】:Embedded Jetty with Maven example fails to restart: Address already in use带有 Maven 示例的嵌入式 Jetty 无法重新启动:地址已在使用中
【发布时间】:2016-09-22 01:04:10
【问题描述】:

当尝试在 NetBeans 中重复运行 Embedded Jetty with Maven example 时,不幸的是我收到了错误:

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)

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

但是在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();
    }
}

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

更新:

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

并且8080端口正在使用中:

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

但我当然不想一次又一次地更改端口号(并产生更多进程)。

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

更新 2:

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

Directory: /

这是完整的 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)

【问题讨论】:

  • 你在 pom.xml 中使用jetty-maven-plugin 吗?请在您的问题中发布。
  • 我已将pom.xml 添加到我的问题中,我还没有使用jetty-maven-plugin
  • 这篇文章有更详细的杀死进程的答案。 stackoverflow.com/questions/7082476/…

标签: java netbeans jetty embedded-jetty jetty-9


【解决方案1】:

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

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

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

在码头启动后,发出以下命令,

mvn jetty:stopmvn jetty:stop

或者干脆试试

mvn jetty:stop

mvn jetty:run 命令将启动服务器。其他目标/配置请参考Configuring Jetty Maven plugin

【讨论】:

  • 谢谢,但我已经在 Win 7 和 Mac OSX 上尝试过你的建议,mvn jetty:run 现在确实启动了 Web 服务器,但它只显示红色文本 Directory: /(请参阅更新2 在我的问题中)
  • @Alexander 是的,您的 web 应用程序已成功启动,您应该能够访问位于 http://localhost:8080 的站点。这将显示码头注册的可用上下文。日志显示您没有 webapp 文件夹。码头停止目标是否有效?
  • 是的,但是我的处理程序 response.getWriter().println("&lt;h1&gt;Hello World&lt;/h1&gt;"); 出于某种原因没有被调用?
  • 您的 web.xml 中是否有针对 HelloWorld servlet 的 servlet 映射?您应该在其中添加 servlet 映射请求 URL 和 servlet 类以使其正常工作。
  • 这篇文章Servlet Mapping using web.xml 应该可以帮助您将 servlet 处理程序方法与请求 url 进行映射。或者按照答案中的建议,您可以使用 @WebServlet 从 Servlet 3.0 开始。
【解决方案2】:

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

您也可以尝试使用其他端口来代替 8080(例如 8090)。

【讨论】:

  • 是的,你是对的 - 有进程正在运行......所以我的问题(我已经更新了)是:如何正确停止嵌入式 Jetty,这样我可以再次调试我的处理程序吗?
  • 最简单的方法是杀死正在运行的进程(使用“kill ”或“kill -9 ”)。或者您正在寻找一些自动化的解决方案?
  • 是的,ps -ef | awk '/HelloWorld/ {print $2}' | xargs kill 可以工作,但我正在寻找 Jetty 命令来停止正在运行的嵌入式 Jetty 服务器。就像mvn jetty:stop(这对我也不起作用)......
  • 链接中提到的命令呢? "java -jar start.jar STOP.PORT= STOP.KEY="
猜你喜欢
  • 1970-01-01
  • 2015-09-26
  • 2012-08-25
  • 1970-01-01
  • 2020-05-18
  • 2013-10-27
  • 2011-01-31
  • 1970-01-01
  • 2017-07-07
相关资源
最近更新 更多