为spring boot应用程序生成war包时maven构建失败?

Posted

技术标签:

【中文标题】为spring boot应用程序生成war包时maven构建失败?【英文标题】:maven build failing when generating war package for spring boot application? 【发布时间】:2015-07-02 03:22:48 【问题描述】:

这是我在 SO 上的上一个问题 here 的扩展。根据这篇文章,生成deployable war

不需要 main 方法

我正在尝试为这个简单的uploading files 应用程序生成一个deployable war。此示例应用的源代码可以在here找到。

按照 spring boot 中关于 jar 到 war 转换的说明,我更改了我的 pom.xml 以反映以下内容。 (刚刚添加了 tomcat 依赖,范围为 provided)。

参考:http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#build-tool-plugins-maven-packaging

      <?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>org.springframework</groupId>
    <artifactId>gs-uploading-files</artifactId>
    <version>0.1.0</version>
    <packaging>war</packaging>

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


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

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

    </dependencies>

    <properties>
        <java.version>1.7</java.version>
    </properties>

    <repositories>
        <repository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>https://repo.spring.io/libs-release</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>https://repo.spring.io/libs-release</url>
        </pluginRepository>
    </pluginRepositories>
</project>

然后我把Application.java改成如下

参考:http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-create-a-deployable-war-file

@SpringBootApplication
public class Application extends SpringBootServletInitializer

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) 
        return application.sources(Application.class);
    

    /*public static void main(String[] args) 
        SpringApplication.run(Application.class, args);
     */
 

我尝试了两种情况。两者都失败并出现以下错误 (Unable to find main class)。

    没有 main 方法(注意我上面已经注释掉了 main 方法) 没有 application.Java 文件(注释掉该文件中的所有内容 - 此处未显示)

错误:

[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9.218s
[INFO] Finished at: Thu Apr 23 11:46:24 PDT 2015
[INFO] Final Memory: 22M/222M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.2.3.RELEASE:repackage (default) on project gs-uploading-files: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:1.2.3.RELEASE:repackage failed: Unable to find main class -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionException

PS:当我有完整的main方法时,构建成功

【问题讨论】:

有没有机会在 pom.xml 中仍然引用您的主类? @ci_:我不确定你的确切意思。我已经更新了我的整个 pom.xml 除了您的链接问题的答案之外,我找不到任何证据表明您可以省略主类,即具有 main 方法的类。 spring-boot-maven-plugin 似乎正在寻找它。也许如果您没有使用该插件,但不确定是否值得。 如果您只想将应用程序作为标准war文件运行,您可以完全删除Boot插件或重新配置它,以便重新打包目标不绑定到Maven的生命周期 对于本地测试,我更喜欢嵌入式Tomcat。但为了部署,我需要战争。我不知道我怎样才能在这里获得这两种好处 【参考方案1】:

请注意,您可能会收到类似的消息


未能在项目 Xyz 上执行目标 org.springframework.boot:spring-boot-maven-plugin:1.3.2.RELEASE:repackage (default):目标 org.springframework.boot:spring-boot-maven 的执行默认值-plugin:1.3.2.RELEASE:repackage failed: 无法从以下候选中找到单个主类 [com.a.Application, com.a.fake.Application, com.a.main .Main1, com.a.runner.DataImportRunner, com.a.temp.dependencyinjection.MainApp, com.a.finalapp.facade.impl.V3DataImports, com.a.finalapp.service.impl.App2]


(我在尝试运行 Maven 安装时在我的应用程序中看到)

就我而言,我有多个主要方法,而 Spring 无法自动选择我想要的那个。

解决方案与 Naymesh Mistry 之前概述的相同(在 pom.xml 中明确指定 your.main.class.with.package.prefix)

【讨论】:

【参考方案2】:

如果您想获得两者的好处 - 即与嵌入式 Tomcat 的独立可执行战争可部署在外部 Tomcat 中的正常战争 - 你需要有一个带有 main 的类方法。所以,

在 Application.java 中启用 main() 方法。 配置spring-boot-maven-plugin 以指定具有主类的类(如果你有一个,Spring 无论如何都会找到它,但我想最好明确一点): <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>$spring-boot-version</version> <configuration> <mainClass>the.package.of.Application</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> 使用provided 范围删除您的pom 中的spring-boot-starter-tomcat 依赖项。 Spring boot 神奇地知道如何启用/禁用嵌入式 Tomcat。

有了这个,您应该能够从 IDE 启动您的 Spring 应用程序,只需将 Application.java 类作为普通 Java 应用程序运行,构建一个既是独立可执行文件,也可以像往常一样在外部 Tomcat 中部署的 war 文件。

我目前正在使用这种设置使用 Spring Boot 1.0.1.RELEASE 构建 REST API,它在所有三种模式下都运行良好。

【讨论】:

即使没有配置 spring-boot-maven-plugin (如你所建议的那样),如果我有 main 方法,它适用于嵌入式和部署战争。如果我只想启用部署战争模式,似乎我还需要main。否则我无法让它工作。 没错,as the document says 如果您不指定主类,插件将搜索具有公共静态 void main(String[] args) 方法的类。不过,为了可读性,我个人更喜欢明确指定类。但是,是的,它不需要明确指定。如果你只想在普通战争模式下启用部署,你根本不需要在你的 pom 中使用spring-boot-maven-plugin 谢谢,在生产中,我怀疑任何机构都使用嵌入式 Tomcat 服务器。所以,我更愿意部署war。正在删除spring-boot-maven-plugin,我是只删除main method 搜索还是丢失了一些重要的东西? 是的。嵌入式 Tomcat 更易于分发(例如,您的测试人员不需要先安装任何 Tomcat)和在开发和测试期间部署。在生产中应该使用通常的战争。删除 spring-boot-maven-plugin 和 main 方法应该只从战争中删除独立的可执行/嵌入的 Tomcat 功能,没有别的(只是在我的应用程序上测试了这个并且工作正常:)) 如果您可以选择,建议部署可执行的 war 或 jar。

以上是关于为spring boot应用程序生成war包时maven构建失败?的主要内容,如果未能解决你的问题,请参考以下文章

为 Spring Boot 应用程序生成战争

Spring boot demo: spring boot生成war包

Spring Boot REST API war 文件生成 404 错误

没有父pom.xml的spring-boot无法生成war打包

spring boot 生成 war 包有一个war.original是什么?

更新 Spring Boot 以生成 WAR 文件而不是 JAR 文件