无法启动嵌入式 Jetty 服务器

Posted

技术标签:

【中文标题】无法启动嵌入式 Jetty 服务器【英文标题】:Unable to start embedded Jetty server 【发布时间】:2020-05-18 16:26:23 【问题描述】:

我做了一个spring boot项目。

当我使用 windows 10 制作一个 jar 并在我的 windows 机器上运行时,它可以正常工作。

当我尝试在安装了 Java 8 的 Debian 10 或 CentOS 8 上运行它时,我得到了

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-02-02 20:22:13.050 ERROR 14537 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.boot.web.server.WebServerException: Unable to start embedded Jetty server
        at org.springframework.boot.web.embedded.jetty.JettyWebServer.start(JettyWebServer.java:165) ~[spring-boot-2.1.9.RELEASE.jar!/:2.1.9.RELEASE]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.startWebServer(ServletWebServerApplicationContext.java:297) ~[spring-boot-2.1.9.RELEASE.jar!/:2.1.9.RELEASE]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:163) ~[spring-boot-2.1.9.RELEASE.jar!/:2.1.9.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:552) ~[spring-context-5.1.10.RELEASE.jar!/:5.1.10.RELEASE]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.1.9.RELEASE.jar!/:2.1.9.RELEASE]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744) [spring-boot-2.1.9.RELEASE.jar!/:2.1.9.RELEASE]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391) [spring-boot-2.1.9.RELEASE.jar!/:2.1.9.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) [spring-boot-2.1.9.RELEASE.jar!/:2.1.9.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.1.9.RELEASE.jar!/:2.1.9.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204) [spring-boot-2.1.9.RELEASE.jar!/:2.1.9.RELEASE]
        at ptoject.web.Application.main(Application.java:14) [classes!/:na]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_232]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_232]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_232]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_232]
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) [web-4.jar:na]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) [web-4.jar:na]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:51) [web-4.jar:na]
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:52) [web-4.jar:na]
Caused by: java.net.SocketException: Permission denied
        at sun.nio.ch.Net.bind0(Native Method) ~[na:1.8.0_232]
        at sun.nio.ch.Net.bind(Net.java:433) ~[na:1.8.0_232]
        at sun.nio.ch.Net.bind(Net.java:425) ~[na:1.8.0_232]
        at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223) ~[na:1.8.0_232]
        at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74) ~[na:1.8.0_232]
        at org.eclipse.jetty.server.ServerConnector.openAcceptChannel(ServerConnector.java:342) ~[jetty-server-9.4.19.v20190610.jar!/:9.4.19.v20190610]
        at org.eclipse.jetty.server.ServerConnector.open(ServerConnector.java:308) ~[jetty-server-9.4.19.v20190610.jar!/:9.4.19.v20190610]
        at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:80) ~[jetty-server-9.4.19.v20190610.jar!/:9.4.19.v20190610]
        at org.eclipse.jetty.server.ServerConnector.doStart(ServerConnector.java:236) ~[jetty-server-9.4.19.v20190610.jar!/:9.4.19.v20190610]
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) ~[jetty-util-9.4.19.v20190610.jar!/:9.4.19.v20190610]
        at org.springframework.boot.web.embedded.jetty.JettyWebServer.start(JettyWebServer.java:146) ~[spring-boot-2.1.9.RELEASE.jar!/:2.1.9.RELEASE]

如果有任何帮助,这是我的 build.gradle 文件

buildscript 
    repositories 
        mavenCentral()
    
    dependencies 
        classpath("org.springframework.boot:spring-boot-gradle-plugin:2.1.9.RELEASE")
    


plugins 
    id 'org.springframework.boot' version '2.1.9.RELEASE'
    id 'io.spring.dependency-management' version '1.0.8.RELEASE'
    id 'java'
    id 'application'


group = 'project'
version = '4'
mainClassName = "project.web.Application"

repositories 
    mavenCentral()


dependencies 
    compile("org.springframework.boot:spring-boot-starter-web") 
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
    
    compile('org.springframework.boot:spring-boot-starter-data-jpa') 
        exclude group: 'org.apache.tomcat', module: 'tomcat-jdbc'
    
    implementation 'org.springframework.boot:spring-boot-starter-jetty'
    implementation 'org.springframework.boot:spring-boot-starter-freemarker'
    implementation 'org.springframework.boot:spring-boot-starter-jdbc'
    implementation 'org.springframework.boot:spring-boot-starter-mail';
    implementation 'com.h2database:h2'
    implementation 'org.webjars:jquery:3.1.0'
    implementation 'commons-validator:commons-validator:1.6'


jar 
    // include all the jars
    from 
        configurations.compile.collect  it.isDirectory() ? it : zipTree(it) 
        (configurations.runtime).collect 
            it.isDirectory() ? it : zipTree(it)
        
    
    manifest 
        attributes 'Main-Class': 'web.Application'
    

我完全不知道为什么会发生这种情况

Debian 10 和 CentOS 8 有

openjdk version "1.8.0_232"
OpenJDK Runtime Environment (build 1.8.0_232-b09)
OpenJDK 64-Bit Server VM (build 25.232-b09, mixed mode)

windows机器有

java version "1.8.0_241"
Java(TM) SE Runtime Environment (build 1.8.0_241-b07)
Java HotSpot(TM) 64-Bit Server VM (build 25.241-b07, mixed mode)

【问题讨论】:

java.net.SocketException: Permission denied 表示不允许绑定端口。我猜你正在尝试需要提升权限的端口 80 或 443 之类的东西 1024以下的所有端口只允许以root身份运行。而且您不应该以 root 身份运行 java 应用程序,这是一个安全风险。你可以在这里阅读更多关于它的信息serverfault.com/questions/112795/… @ThomasAndolf 我愿意承担安全风险。如何在端口 80 上以 root 身份运行 java?或者,如果我无法在端口 80 上运行,那么如何将端口 80 指向在端口 >1024 上运行的 Spring Boot 应用程序? 阅读我发布的链接。 @ThomasAndolf 如果您回答,我可以接受您的回答是正确的。此外,您的链接没有解释为什么它是一个安全风险。此外,如果我以 root 身份运行 java 进程,它也可以工作。 【参考方案1】:

1024以下的所有端口只允许root打开。这就是为什么 Spring Boot 应用程序通常在端口 8080 上运行,而您有某种代理/负载均衡器将流量从 80 重定向到 8080。

为什么您不想以 root 身份运行应用程序,是因为如果您的应用程序中存在允许“远程代码执行”(有人可以通过您的应用程序执行恶意代码)的漏洞/错误,那么代码将以root身份运行,这是linux服务器上最强大的用户。

然后攻击者基本上可以在服务器/机器上为所欲为。

这个帖子有几个建议如何解决你的问题https://serverfault.com/questions/112795/how-to-run-a-server-on-port-80-as-a-normal-user-on-linux

但我绝不会推荐任何人以 root 身份运行应用程序,这是一个重大的安全风险。我宁愿在不同的端口(比如 8080)上运行它。

【讨论】:

可能也不建议这样做,但对我来说,在 .NET 中解决这个问题的快速方法是以管理员身份运行 IDE。 以管理员身份运行 ide,会使您面临上述内容的风险。然后应用程序以管理员身份运行女巫同样危险。

以上是关于无法启动嵌入式 Jetty 服务器的主要内容,如果未能解决你的问题,请参考以下文章

启动嵌入式 Jetty 服务器的最短代码

Spring Boot + Tomcat + Jetty - 应用程序无法启动

docker jetty10 启动 war

无法启动 bean 'webServerStartStop';无法启动嵌入式 Tomcat 服务器 - spring-boot-starter-web

嵌入式jetty9启动标准webapp目录

Jetty嵌入式Web容器攻略