Java 部署在 tomcat 上的 Spring Boot 无法启动

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37919593/
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-08-11 19:47:45  来源:igfitidea点击:

Spring boot deployed on tomcat won't start

javaspringspring-mvctomcat

提问by Herr Derb

I have a working Spring application that contains a embedded Tomcat. As a executable war, it works fine. As I'm going to use AngularJ for the front end, it isn't very practical to have the Spring project in an executable jar, as I will do debugging in the browser and want to be able to quickly edit the js source files. If they are saved in an archive, this is annoying.

我有一个包含嵌入式 Tomcat 的工作 Spring 应用程序。作为一个可执行的战争,它工作正常。由于我将在前端使用 AngularJ,因此将 Spring 项目放在可执行 jar 中并不是很实用,因为我将在浏览器中进行调试,并希望能够快速编辑 js 源文件。如果它们保存在档案中,这很烦人。

That's why I want to make it deployable, so it would get unpacked on a tomcat. It seems to be that easy, but I can't get it to work.

这就是为什么我想让它可部署,所以它会在 tomcat 上解压缩。这似乎很容易,但我无法让它发挥作用。

The context always gets loaded twice apparently. Because of that first I get an exception of the repository (@Repository) I use (already blocked) and another exception from spring "Cannot initialize context because there is already a root application context present".

上下文显然总是被加载两次。因此,首先我得到了@Repository我使用的存储库 ( )的异常(已被阻止)和 spring 的另一个异常“无法初始化上下文,因为已经存在根应用程序上下文”。

I confused as I already read, that is quite normal that Spring creates 2 contexts, especially with MVC. But why the exceptions then?

正如我已经读过的那样,我很困惑,Spring 创建 2 个上下文是很正常的,尤其是使用 MVC。但是为什么会有例外呢?

My SpringApp class looks like this

我的 SpringApp 类看起来像这样

@EnableWebMvc
@ComponentScan
@EnableAutoConfiguration
public class LAuthServerApplication extends WebMvcConfigurerAdapter {

    @Autowired
    Environment env;

    public static void main(String[] args) {
    System.out.println("#################### Startup parameters ##############");
    for (String s : args) {
        System.out.println("Parameter: " + s);
    }
    System.out.println("######################################################");
    SpringApplication.run(LAuthServerApplication.class, args);
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    configurer.enable();
    }

    @Bean
    public InternalResourceViewResolver viewResolver() {
    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
    viewResolver.setPrefix("/WEB-INF/pages/");
    viewResolver.setSuffix(".jsp");
    return viewResolver;
    }

To make it deployable I added this class to my project:

为了使其可部署,我将这个类添加到我的项目中:

@Configuration
public class AppServletInitializer extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }
}

POM:

聚甲醛:

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>ch.comlab.comweb</groupId>
    <artifactId>LAuth</artifactId>
    <version>1.0.0</version>
    <packaging>war</packaging>
    <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>

    </properties>
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.5.RELEASE</version>
    </parent>

    <dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
    </dependency>
    <dependency>
        <groupId>ch.comlab.comweb</groupId>
        <artifactId>Infrastructure</artifactId>
        <version>1.2.6</version>
    </dependency>

    </dependencies>
    <build>
    <plugins>
        <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.6</version>
        <configuration>
            <webResources>
            <resource>
                <directory>src/main/webapp</directory>
                <filtering>true</filtering>
            </resource> 
            </webResources>
        </configuration>
        </plugin>
        <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
            <resources>
            <resource>
                <filtering>true</filtering>
                <directory>src/main/resources/</directory>
            </resource>
            </resources>
        </configuration>
        </plugin>
    </plugins>
    </build>
    <repositories>
    <repository>
        <id>spring-releases</id>
        <url>https://repo.spring.io/libs-release</url>
    </repository>
    </repositories>
    <pluginRepositories>
    <pluginRepository>
        <id>spring-releases</id>
        <url>https://repo.spring.io/libs-release</url>
    </pluginRepository>
    </pluginRepositories>
    <name>LAuth</name>
</project>

采纳答案by Herr Derb

I finally got it to run, with the following POM and the suggested Code change from M.Denium and Dhanabalan:

我终于让它运行了,使用以下 POM 和来自 M.Denium 和 Dhanabalan 的建议代码更改:

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ch.comlab.comweb</groupId>
<artifactId>LAuth</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>

</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
</parent>

<dependencies>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
    <exclusion>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
    </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-el</artifactId>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
    <groupId>ch.comlab.comweb</groupId>
    <artifactId>Infrastructure</artifactId>
    <version>1.2.6</version>
</dependency>

</dependencies>
<build>
<plugins>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <resources>
        <resource>
            <filtering>true</filtering>
            <directory>src/main/resources/</directory>
        </resource>
        </resources>
    </configuration>
    </plugin>
</plugins>
</build>
<repositories>
<repository>
    <id>spring-releases</id>
    <url>https://repo.spring.io/libs-release</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
    <id>spring-releases</id>
    <url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
<name>LAuth</name>

回答by Dhanabalan

I believe its due to the embedded server which comes from spring-boot-tomcat.

我相信这是由于来自 spring-boot-tomcat 的嵌入式服务器。

Can you exclude embedded tomcat and try? Eg:

您可以排除嵌入式tomcat并尝试吗?例如:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

also remove your tomcat dependency which you gave next to spring-boot-starter-web.

还要删除您在 spring-boot-starter-web 旁边提供的 tomcat 依赖项。

回答by M. Deinum

Your configuration is a bit confusing and verbose if you use Spring Boot.

如果您使用 Spring Boot,您的配置会有点混乱和冗长。

You should remove the maven-war-pluginfrom your list of plugins. As the spring-boot-maven-plugintakes care of those things already (and the parent is also).

您应该maven-war-plugin从插件列表中删除。由于spring-boot-maven-plugin已经处理了这些事情(父母也是)。

Next your configuration remove some of the code and merge the LAuthServerApplicationand your starter into one. And use @SpringBootApplicationinstead of single annotations (saves you code).

接下来你的配置删除一些代码LAuthServerApplication并将你的启动器合并为一个。并使用@SpringBootApplication而不是单个注释(节省您的代码)。

@SpringBootApplication
public class LAuthServerApplication extends SpringBootServletInitializer {

    @Autowired
    Environment env;

    public static void main(String[] args) {
        System.out.println("#################### Startup parameters ##############");
        for (String s : args) {
            System.out.println("Parameter: " + s);
        }
        System.out.println("######################################################");
        SpringApplication.run(LAuthServerApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(LAuthServerApplication.class);
    }

}

In your application.propertiesadd

在您application.properties添加

spring.mvc.view.prefix=/WEB-INF/pages/
spring.mvc.view.suffix=.jsp

Spring Boot already configures Spring MVC for you and yours interferes with that. Don't override the defaults unless you have very specific needs.

Spring Boot 已经为您配置了 Spring MVC,而您的配置会干扰它。除非您有非常特殊的需求,否则不要覆盖默认值。

Now rebuild and restart your application.

现在重建并重新启动您的应用程序。

Note:IMHO it is a very bad idea to edit the unpacked files directly into tomcat, as you really want to edit the source files. Instead of hacking your way around you might want to take a look at the JHipsterproject, which unifies JS and Spring Boot development.

注意:恕我直言,将解压后的文件直接编辑到 tomcat 中是一个非常糟糕的主意,因为您确实想编辑源文件。您可能想看一看JHipster项目,它统一了 JS 和 Spring Boot 开发,而不是绕过你的方式。