最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

deployment - Deploying spring-boot-application (3.4) on external jetty-server (12): HowHow to debug? - Stack Overflow

programmeradmin3浏览0评论

Problem:

I'm trying to deploy a simple spring-boot (3.4) application on a pre-installed jetty-server (12.0.18). (The main reason is to keep the package small for both transfer and memory).

The war-file seems to be deployed (addressing the context results in something) but I can't address the endpoint (404).

The only description I found was with ChatGpt, Gemini and DeepSeek and all were quite similar. But I couldn't address the endpoint.

What I did and expectations

All three AIs recommended

  • change packaging to WAR
  • mark the embedded Jetty-dependency as provided
  • extend SpringBootServletInitializer
  • deploy the war to jetty 12

For the experiments I tried to deploy a minimal application with one endpoint as shown below:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=".0.0" xmlns:xsi=";
    xsi:schemaLocation=".0.0 .0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>springboot.jetty.deploy</groupId>
    <artifactId>myDepTst</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>myDepTst</name>
    <description>Deploy a spring-boot application on jetty</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- proposed by deepseek -->
        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.0.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Main-class:

package springboot.jetty.deploy;

import .springframework.boot.SpringApplication;
import .springframework.boot.builder.SpringApplicationBuilder;
import .springframework.boot.web.servlet.support.SpringBootServletInitializer;

@.springframework.boot.autoconfigure.SpringBootApplication
public class SpringBootApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        System.out.println("### DeployOnJettyApplication.main: Deploy On Jetty");
        SpringApplication.run(SpringBootApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        System.err.println("### DeployOnJettyApplication.configure");
        return application.sources(SpringBootApplication.class);
    }
}

A WebEndpoint for testing:

package springboot.jetty.deploy;

import jakarta.annotation.PostConstruct;
import .springframework.web.bind.annotation.GetMapping;
import .springframework.web.bind.annotation.RequestMapping;
import .springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/endpt")
public class WebEndpoint {

    private int counter = 0;

    @PostConstruct
    public void init() {
        System.out.println("### WebEndpoint.init()");
    }

    @GetMapping("tst")
    public String tst() {
        return "### WebEndpoint.tst() called %s-times".formatted(counter++);
    }

}

Deploying to Jetty:

  • Downloading jetty 12.0.8 and unpacking to .../jetty-home
  • copy the built war-file to .../jetty-base/webapps/myDepTst.war
  • as the needed modules aren't clear (yet) -- cd jetty-base -- java -jar .../jetty-home/start.jar --add-modules=ee10-demos
  • fire up jetty: java -jar .../jetty-home/start.jar

In the logs I find:

2025-03-20 21:27:51.797:WARN :oejdp.ScanningAppProvider:main: class .eclipse.jetty.deploy.providers.ContextProvider@569bf9eb[file:///C:/temp/jetty/jetty-base/webapps/] no environment for App@42b64ab8[ee10,null,C:\temp\jetty\jetty-base\webapps\myDepTst.war], ignoring
2025-03-20 21:27:51.907:INFO :oejd.DeploymentManager:main: addApp: App@c074c0c[ee10,null,C:\temp\jetty\jetty-base\webapps\myDepTst.war]
2025-03-20 21:27:54.765:INFO :oejsh.ContextHandler:main: Started oeje10w.WebAppContext@315f09ef{myDepTst,/myDepTst,b=file:///C:/temp/jetty/jetty-base/work/jetty-0_0_0_0-8443-myDepTst_war-_myDepTst-any-/webapp/,a=AVAILABLE,h=oeje10s.SessionHandler@b9a77c8{STARTED}}{C:\temp\jetty\jetty-base\webapps\myDepTst.war}
2025-03-20 21:27:54.766:INFO :oejes.ServletContextHandler:main: Started oeje10w.WebAppContext@315f09ef{myDepTst,/myDepTst,b=file:///C:/temp/jetty/jetty-base/work/jetty-0_0_0_0-8443-myDepTst_war-_myDepTst-any-/webapp/,a=AVAILABLE,h=oeje10s.SessionHandler@b9a77c8{STARTED}}{C:\temp\jetty\jetty-base\webapps\myDepTst.war}

Also the logs for the working example ee10-demo-jetty look similar. Setting .eclipse.jetty.LEVEL=TRACE in jetty-logging.properties shows:

2025-03-20 21:55:55.157:DEBUG:oejea.AnnotationParser:qtp192881625-36: Parse class from file:///C:/temp/jetty/jetty-base/work/jetty-0_0_0_0-8443-myDepTst_war-_myDepTst-any-/webapp/WEB-INF/classes/springboot/jetty/deploy/SpringBootApplication.class
2025-03-20 21:55:55.157:DEBUG:oejea.AnnotationParser:qtp192881625-36: Parse class from file:///C:/temp/jetty/jetty-base/work/jetty-0_0_0_0-8443-myDepTst_war-_myDepTst-any-/webapp/WEB-INF/classes/springboot/jetty/deploy/WebEndpoint.class

which I interpret as jetty analyzing my important classes.

When adressing the context http://localhost:8080/myDepTst/ I get a "directory-listing" of "/myDepTst/" so the myDepTst was at least partially recognized.

Screenshot: response to getting context

But when addressing the endpoint http://localhost:8080/myDepTst/endpt/tst I get a 404:

Screenshot: 404 when addressing endpoint

I'm out of options and any help is appreciated! Thanks in advance

Problem:

I'm trying to deploy a simple spring-boot (3.4) application on a pre-installed jetty-server (12.0.18). (The main reason is to keep the package small for both transfer and memory).

The war-file seems to be deployed (addressing the context results in something) but I can't address the endpoint (404).

The only description I found was with ChatGpt, Gemini and DeepSeek and all were quite similar. But I couldn't address the endpoint.

What I did and expectations

All three AIs recommended

  • change packaging to WAR
  • mark the embedded Jetty-dependency as provided
  • extend SpringBootServletInitializer
  • deploy the war to jetty 12

For the experiments I tried to deploy a minimal application with one endpoint as shown below:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache./POM/4.0.0" xmlns:xsi="http://www.w3./2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache./POM/4.0.0 https://maven.apache./xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>springboot.jetty.deploy</groupId>
    <artifactId>myDepTst</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>myDepTst</name>
    <description>Deploy a spring-boot application on jetty</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- proposed by deepseek -->
        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.0.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Main-class:

package springboot.jetty.deploy;

import .springframework.boot.SpringApplication;
import .springframework.boot.builder.SpringApplicationBuilder;
import .springframework.boot.web.servlet.support.SpringBootServletInitializer;

@.springframework.boot.autoconfigure.SpringBootApplication
public class SpringBootApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        System.out.println("### DeployOnJettyApplication.main: Deploy On Jetty");
        SpringApplication.run(SpringBootApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        System.err.println("### DeployOnJettyApplication.configure");
        return application.sources(SpringBootApplication.class);
    }
}

A WebEndpoint for testing:

package springboot.jetty.deploy;

import jakarta.annotation.PostConstruct;
import .springframework.web.bind.annotation.GetMapping;
import .springframework.web.bind.annotation.RequestMapping;
import .springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/endpt")
public class WebEndpoint {

    private int counter = 0;

    @PostConstruct
    public void init() {
        System.out.println("### WebEndpoint.init()");
    }

    @GetMapping("tst")
    public String tst() {
        return "### WebEndpoint.tst() called %s-times".formatted(counter++);
    }

}

Deploying to Jetty:

  • Downloading jetty 12.0.8 and unpacking to .../jetty-home
  • copy the built war-file to .../jetty-base/webapps/myDepTst.war
  • as the needed modules aren't clear (yet) -- cd jetty-base -- java -jar .../jetty-home/start.jar --add-modules=ee10-demos
  • fire up jetty: java -jar .../jetty-home/start.jar

In the logs I find:

2025-03-20 21:27:51.797:WARN :oejdp.ScanningAppProvider:main: class .eclipse.jetty.deploy.providers.ContextProvider@569bf9eb[file:///C:/temp/jetty/jetty-base/webapps/] no environment for App@42b64ab8[ee10,null,C:\temp\jetty\jetty-base\webapps\myDepTst.war], ignoring
2025-03-20 21:27:51.907:INFO :oejd.DeploymentManager:main: addApp: App@c074c0c[ee10,null,C:\temp\jetty\jetty-base\webapps\myDepTst.war]
2025-03-20 21:27:54.765:INFO :oejsh.ContextHandler:main: Started oeje10w.WebAppContext@315f09ef{myDepTst,/myDepTst,b=file:///C:/temp/jetty/jetty-base/work/jetty-0_0_0_0-8443-myDepTst_war-_myDepTst-any-/webapp/,a=AVAILABLE,h=oeje10s.SessionHandler@b9a77c8{STARTED}}{C:\temp\jetty\jetty-base\webapps\myDepTst.war}
2025-03-20 21:27:54.766:INFO :oejes.ServletContextHandler:main: Started oeje10w.WebAppContext@315f09ef{myDepTst,/myDepTst,b=file:///C:/temp/jetty/jetty-base/work/jetty-0_0_0_0-8443-myDepTst_war-_myDepTst-any-/webapp/,a=AVAILABLE,h=oeje10s.SessionHandler@b9a77c8{STARTED}}{C:\temp\jetty\jetty-base\webapps\myDepTst.war}

Also the logs for the working example ee10-demo-jetty look similar. Setting .eclipse.jetty.LEVEL=TRACE in jetty-logging.properties shows:

2025-03-20 21:55:55.157:DEBUG:oejea.AnnotationParser:qtp192881625-36: Parse class from file:///C:/temp/jetty/jetty-base/work/jetty-0_0_0_0-8443-myDepTst_war-_myDepTst-any-/webapp/WEB-INF/classes/springboot/jetty/deploy/SpringBootApplication.class
2025-03-20 21:55:55.157:DEBUG:oejea.AnnotationParser:qtp192881625-36: Parse class from file:///C:/temp/jetty/jetty-base/work/jetty-0_0_0_0-8443-myDepTst_war-_myDepTst-any-/webapp/WEB-INF/classes/springboot/jetty/deploy/WebEndpoint.class

which I interpret as jetty analyzing my important classes.

When adressing the context http://localhost:8080/myDepTst/ I get a "directory-listing" of "/myDepTst/" so the myDepTst was at least partially recognized.

Screenshot: response to getting context

But when addressing the endpoint http://localhost:8080/myDepTst/endpt/tst I get a 404:

Screenshot: 404 when addressing endpoint

I'm out of options and any help is appreciated! Thanks in advance

Share Improve this question edited Mar 21 at 13:04 Franz asked Mar 21 at 12:51 FranzFranz 12 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

Jetty Server

Download Jetty

In C:\temp

  • Brower open https://repo1.maven./maven2//eclipse/jetty/jetty-home/12.0.19/jetty-home-12.0.19.zip
  • get jetty-home-12.0.19.zip

Unzip jetty-home-12.0.19.zip

In C:\temp , unzip jetty-home-12.0.19.zip

create directory jetty-base

In C:\temp, create directory jetty-base

cd C:\temp
mkdir jetty-base

Create Jetty init Config

open CMD.exe

cd C:\temp
set JETTY_BASE=%cd%\jetty-base
set JETTY_HOME=%cd%\jetty-home-12.0.19

cd %JETTY_BASE%
java -jar %JETTY_HOME%\start.jar --add-module=logging-logback,server,http,ee10-deploy,ee10-jsp

Project SpringBoot_WAR_ST

C:\temp\SpringBoot_WAR_ST
├── pom.xml
└── src
    └── main
        ├── java
        │   └── springboot
        │       └── jetty
        │           └── deploy
        │               ├── DemoSpringbootApplication.java
        │               ├── HelloJSPController.java
        │               └── HelloRestController.java
        ├── resources
        │   ├── application.properties
        │   └── logback.xml
        └── webapp
            └── WEB-INF
                └── jsp
                    └── hello.jsp

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3./2001/XMLSchema-instance" xmlns="http://maven.apache./POM/4.0.0"
         xsi:schemaLocation="http://maven.apache./POM/4.0.0 https://maven.apache./xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>springboot.jetty.deploy</groupId>
    <artifactId>myDepTst</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>myDepTst</name>
    <description>Deploy a spring-boot application on jetty</description>
    <properties>
        <mavenpiler.source>17</mavenpiler.source>
        <mavenpiler.target>17</mavenpiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>
    
    <dependencies>
    
        <dependency>
            <groupId>.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>

    </dependencies>

    <build>
        <finalName>myDepTst</finalName>
        <plugins>
            <plugin>
                <groupId>.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

DemoSpringbootApplication.java

  • I changed the name of SpringBootApplication class to DemoSpringbootApplication to avoid misunderstanding. Because there is also a SpringBootApplication in the import (import .springframework.boot.SpringApplication;)
  • Also, when you convert Spring Boot to a war file, the main method is not actually called. You can check the log output.
package springboot.jetty.deploy;

import .springframework.boot.SpringApplication;
import .springframework.boot.autoconfigure.SpringBootApplication;
import .springframework.boot.builder.SpringApplicationBuilder;
import .springframework.boot.web.servlet.support.SpringBootServletInitializer;
import .slf4j.Logger;
import .slf4j.LoggerFactory;

@SpringBootApplication
public class DemoSpringbootApplication extends SpringBootServletInitializer {
    private static final Logger log = LoggerFactory.getLogger(DemoSpringbootApplication.class);

    public static void main(String[] args) {
        log.info(">>>> MAIN START");
        SpringApplication.run(DemoSpringbootApplication.class, args);
        log.info(">>>> MAIN EXIT");
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        log.info(">>>> configure");
        return application.sources(DemoSpringbootApplication.class);
    }

}

HelloJSPController.java

  • Tests for Spring Web MVC.
package springboot.jetty.deploy;

import .springframework.stereotype.Controller;
import .springframework.web.bind.annotation.RequestMapping;
import .springframework.web.bind.annotation.RequestMethod;
import .springframework.web.servlet.ModelAndView;

import .slf4j.Logger;
import .slf4j.LoggerFactory;

import java.util.Map;

@Controller
public class HelloJSPController {
    private static final Logger log = LoggerFactory.getLogger(HelloJSPController.class);

    @RequestMapping(value = "/hellojsp", method = RequestMethod.GET)
    public ModelAndView hello(Map<String, Object> model) {

        //System.out.println("HelloJSP Controller hello");
        log.info(">>>> HelloJSP Controller hello");
        model.put("message", "HelloJSP Controller hello");
        model.put("log", log);
        // /WEB-INF/jsp/hello.jsp
        return new ModelAndView("hello");
    }
}

HelloRestController.java

  • I renamed WebEndpoint.java to HelloRestController.java.
package springboot.jetty.deploy;

import jakarta.annotation.PostConstruct;
import .springframework.web.bind.annotation.GetMapping;
import .springframework.web.bind.annotation.RequestMapping;
import .springframework.web.bind.annotation.RestController;
import .slf4j.Logger;
import .slf4j.LoggerFactory;

@RestController
@RequestMapping("/endpt")
public class HelloRestController {
    private static final Logger log = LoggerFactory.getLogger(HelloRestController.class);
    private int counter = 0;

    @PostConstruct
    public void init() {
        log.info(">>> HelloRestController initialized.");
    }

    @GetMapping("/hello")
    public String hello() {
        log.info(">>>> /hello");
        return "Hello from WAR!";
    }

    @GetMapping("/tst")
    public String tst() {
        log.info(">>>> /tst");
        String s1="HelloRestController.tst() called %s-times".formatted(counter++);
        log.info(s1);
        return s1;
    }
}

application.properties

spring.application.name=spring-boot-demo-war-app
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- TOMCAT SERVER -->
    <!--
    <property name="LOG_HOME" value="${catalina.home}/logs"/>
    -->
    <!-- JETTY SERVER -->

    <property name="LOG_HOME" value="${jetty.base}/logs"/>

    <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d [%thread] %-5level %-50logger{40} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/app.log</file>
        <encoder>
            <pattern>%d [%thread] %-5level %-50logger{40} - %msg%n</pattern>
        </encoder>

        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/app-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxFileSize>1MB</maxFileSize>
            <maxHistory>30</maxHistory>
            <totalSizeCap>10MB</totalSizeCap>
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
        </rollingPolicy>
    </appender>

    <root level="INFO">
        <appender-ref ref="Console"/>
        <appender-ref ref="RollingFile"/>
    </root>
</configuration>

hello.jsp

  • Tests for Spring Web MVC.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import=".slf4j.Logger" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello</title>
    <style>
        .color-red {
            color: red;
        }
    </style>
</head>
<%
// debug
System.out.println("webapp / WEB-INF / jsp / hello.jsp ");
%>
<%
    Logger log = (Logger) request.getAttribute("log");
    if (log != null) {
        log.info(">>>> Logging from JSP page!");
    }
%>
<body>
   <h1 class="color-red">SpringBoot hello.jsp!!  ${message} </h1>
</body>
</html>

Build

cd C:\temp\SpringBoot_WAR_ST
mvn clean package

Put war into jetty webapp

  • copy C:\temp\SpringBoot_WAR_ST\target\myDepTst.war
  • into C:\temp\jetty-base\webapps

Run Jetty Server

OPEN CMD.exe

cd C:\temp
set JETTY_BASE=%cd%\jetty-base
set JETTY_HOME=%cd%\jetty-home-12.0.19

cd %JETTY_BASE%
java -jar %JETTY_HOME%\start.jar

Test

  • http://localhost:8080/myDepTst/hellojsp
  • http://localhost:8080/myDepTst/endpt/hello
  • http://localhost:8080/myDepTst/endpt/tst

check log

Logback writes the log to: C:\temp\jetty-base\logs\app.log

发布评论

评论列表(0)

  1. 暂无评论