mvn spring-boot:run vs java -jar

Posted

技术标签:

【中文标题】mvn spring-boot:run vs java -jar【英文标题】: 【发布时间】:2018-04-25 19:15:52 【问题描述】:

我知道这听起来可能很愚蠢,但我无法理解 mvn spring-boot:runjava -jar 之间的区别(使用 mvn install 生成的 .jar 文件)

我在/src/main/resources/META-INF/resources/WEB-INF/ 中有一个带有 jsp 页面的 Spring Boot 应用程序。如果我使用mvn spring-boot:run,则会提供这些页面。但是如果我使用java -jar,应用程序找不到这些页面。

我正在处理的应用程序位于https://github.com/ArslanAnjum/angularSpringApi

更新: 它适用于 spring boot 1.4.2.RELEASE,而我打算使用最新版本,即 1.5.8.RELEASE。

更新: 好吧,我通过将 jsps 放入 src/main/webapp/WEB-INF/views/ 并将打包类型更改为 war 然后使用 java -jar target/myapp.war 运行此 war 并且现在可以正常工作来解决了这个问题。

【问题讨论】:

你能发布你的spring应用配置文件吗? 我已经分享了 github 链接。你可以克隆仓库。 您的配置是从一些样本中提取的吗?我不认为 JAR(嵌入式容器)中的 JSP 可以与 Tomcat 一起使用 freemarker 而不是 jsp 也有同样的问题,你的解决方案(打包为战争)也对我们有用,谢谢 【参考方案1】:

简短回答:spring-boot:run 是一个java -jar 命令在 steroïd 上作为 Maven 构建的一部分运行,确保将所有必需的参数传递给您的应用程序(例如资源)。 spring-boot:run 还将确保通过在运行您的应用程序之前执行 test-compile 生命周期目标来编译您的项目。

长答案:

当您运行 java -jar 时,您将启动一个新的 JVM 实例,其中包含您传递给此 JVM 的所有参数。例如,使用 Spring doc 示例

java -Xdebug -Xrunjdwp:server=y, \
    transport=dt_socket, address=8000, suspend=
    -jar target/myproject-0.0.1-SNAPSHOT.jar

您将使用给定的参数启动一个全新的 JVM。您需要确保在命令行中包含所有需要的内容,例如类路径元素、应用程序参数、JVM 选项等。

当您运行 mvn spring-boot:run 时,您会启动一个 Maven 构建,它将:

运行test-compile生命周期目标,默认为resources:resourcescompiler:compileresources:testResourcescompiler:testCompile Maven Resources and Compiler插件的目标。 使用一组参数启动您的应用程序,这些参数取决于 您在项目中定义的 Spring Boot Maven 插件配置(您的 pom.xml、父项和设置、命令行等)。其中包括: 很多类路径元素:target/classes 文件夹,其中可能包含应用所需的资源和库、Maven 依赖项等。 是否 fork JVM(是否创建一个全新的 JVM 来运行您的应用程序或重用 Maven 构建的 JVM),请参阅插件的 forkagent 参数

根据:

我有一个带有 jsp 页面的 Spring Boot 应用程序 /src/main/resources/META-INF/resources/WEB-INF/。如果我使用 mvn spring-boot:run 提供这些页面。但是如果我使用 java -jar 这些 应用程序找不到页面。

这是因为mvn spring:boot 命令将确保您的target/classes 文件夹在您的应用程序运行时存在于类路径中。编译后,此文件夹将包含target/classes/META-INF/resources/WEB-INF 等内容。然后,您的应用程序将能够找到 META-INF/resources/WEB-INF 并在被询问时加载它们。当您运行java -jar 命令时,此文件夹可能不在类路径中,您的应用程序将无法找到您的资源。 (这些资源是在resources:resources 目标期间从src/main/resources 文件夹中复制的)

要使用您的 java -jar 命令获得类似的结果,您必须在类路径中包含您的资源,例如 javar -jar myapp.jar -cp $CLASSPATH;/path/to/my/project/target/classes/

【讨论】:

我明白了。但我无法让它发挥作用。可以在 $CLASSPATH 之后指定要包含的内容吗?我试过 /classes/resources/META-INF 和 META-INF/resources。 如果您从项目的根目录运行命令以包含目标文件夹,则通常为 ./target/classes。但这只是一个例子:重要的是确保所有必需的依赖项和资源都在类路径上。如果所有内容都打包在您的 JAR 中,那么您就可以了。 jsps 存在于 jar 中。我尝试使用 spring boot 1.4.2 并且它正在工作。可能是当前版本的弹簧靴的错误。 (1.5.8) 我通过将打包类型更改为war并将所有jsps放在src/main/webapp/WEB-INF/views中解决了这个问题。现在它可以通过命令 java -jar target/myapp.war 运行 感谢@ArslanAnjum - 将包装从 jar 更改为 war 也适用于我们。否则只能在开发机本地运行【参考方案2】:

当您使用java -jar 运行jar 文件时,您是否尝试过使用mvn package 而不是mvn install 创建一个jar 文件? package 将根据您的 POM 文件创建一个 jar/war,而 install 会将生成的 jar 文件安装到本地存储库以获取其他依赖项(如果存在)。

【讨论】:

这不是答案。 这一切都取决于创建jar的方式。 This 页面提供了如何使用 Spring Boot 创建可执行 jar 或 war 档案的完整信息。

以上是关于mvn spring-boot:run vs java -jar的主要内容,如果未能解决你的问题,请参考以下文章

spring boot 实战 / mvn spring-boot:run 参数详解

mvn spring-boot:run运行不了的解决办法

使用 'mvn spring-boot:run' 时出错;但不适用于 java -jar 或 intelliJ

mvn spring-boot:run 导致用户'root'@'localhost'的访问被拒绝(使用密码:YES)

Eclipse 中的“mvn spring-boot:run”和“添加到 Tomcat 服务器”有啥区别?

Spring Boot 应用程序 - 启动时间与“mvn spring-boot:run”和“java -jar”的差异