【问题标题】:Why is the Java -cp option not working when -jar does while using the spring-boot-maven-plugin?为什么 Java -cp 选项在使用 spring-boot-maven-plugin 时 -jar 不起作用?
【发布时间】:2021-08-02 20:40:02
【问题描述】:

我有一个简单的 maven 项目,它在 target 目录中创建一个名为 test.jar 的可执行 jar 文件。

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <main.class>com.me.Main</main.class>
    </properties>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <fork>true</fork>
                <mainClass>${main.class}</mainClass>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>

当我使用java -jar target\test.jar 运行时,一切运行正常,但是当我尝试使用-cp 运行没有-jar 的jar 时,我可以将内容添加到类路径中,例如(Windows)java -cp target\test.jar com.me.Main 我明白了。 ..

Error: Could not find or load main class com.me.Main
Caused by: java.lang.ClassNotFoundException: com.me.Main

我也尝试了其他版本,例如java -cp "target\test.jar" com.me.Main,但无论如何它似乎都不起作用。我错过了什么?

更新

MANIFEST.mf 看起来像这样

Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.me.Main
Spring-Boot-Version: 2.2.12.RELEASE
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/

这似乎表明 spring-boot 正在覆盖 Main-Class KV。

【问题讨论】:

  • 我无法重现该问题,只是创建了一个可执行 jar,我可以以两种方式运行它(Java 11)。
  • 我认为 Spring Boot 插件使用了启动器,即它没有构建传统的可执行 jar,而是进行了奇怪的 jar-files-inside-other-jar-files 捆绑。这意味着将在那里注册的主类将有一个特定于 Spring 的类,它只调用您的真正主类(检查生成的 jar 的清单以了解详细信息)。
  • 慷慨的獾在这里是正确的,你必须使用的主要类是org.springframework.boot.loader.Launcher。查看文档以获取更多信息:docs.spring.io/spring-boot/docs/current/reference/html/…
  • @GenerousBadger 看起来是这样。将 spring boot maven 插件换成程序集插件似乎有助于解决这种情况。让我确认一些事情。
  • @GenerousBadger 我会提出一个答案,你可以改进它,我会接受你的,好吗?这样你就可以获得信用

标签: java spring-boot jar executable-jar spring-boot-maven-plugin


【解决方案1】:

检查 JAR 文件的内容:

jar tvf test.jar

应该包含com/me/Main.class

及其 MANIFEST.MF 文件的内容:

jar xf test.jar META-INF/MANIFEST.MF

并使用文本编辑器打开META-INF/MANIFEST.MF - 应包含以Main-Class: 开头的行和主类的完全限定名称,带有main 方法的名称,在启动JAR 时使用(带有@987654327 @)

(或直接使用 WinZIP、7-zip 或类似软件打开并检查 JAR 文件)

【讨论】:

  • 这如何回答这个问题?
  • @user15793316 感谢您解释此回复。我想说这可能不是一个答案,而是对我是否确认这些项目的评论。还考虑到当我更新问题时问题似乎与 Maven Spring 插件更相关,这个答案可能不适合。再一次,我仍然非常感谢你的帮助,我很快就会发布 MANIFEST.MF,因为我相信春季会有一些奇怪的事情。
  • Spring boot 构建一个特殊的jar。那里的类​​不像其他罐子那样结构化。据我记得,那个罐子可以包含其他罐子。因此,查看罐子内部的建议实际上是有帮助的,甚至认为,严格来说,不是答案
  • 好吧,java 把那个 jar 当作一个普通的 jar 来处理,但是这个 jar 本身并不普通。 Maven 构建 jar,而不是将 mainClass 放入 Main-Class,而是将其放入 Start-Class。主类还是 Spring Boot 类,可以启动这个特殊的 jar。 maven 中指定的类,位于 jar 内的 BOOT-INF 目录中。由于那个java找不到它,如果你把jar放在classpath中。
【解决方案2】:

如果我改成maven-assembly-plugin

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <configuration>
                        <finalName>${project.name}-${project.version}</finalName>
                        <archive>
                            <manifest>
                                <mainClass>
                                    ${main.class}
                                </mainClass>
                            </manifest>
                        </archive>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                </execution>
            </executions>
        </plugin>

那么我仍然可以使用java -jar 运行,也可以使用java -cp 运行

【讨论】:

    猜你喜欢
    • 2021-01-22
    • 2016-12-22
    • 2019-04-11
    • 2021-01-30
    • 2021-11-04
    • 2018-09-10
    • 2017-05-28
    • 2020-01-01
    • 2017-03-16
    相关资源
    最近更新 更多