【问题标题】:ClassNotFoundException when running fat JAR configured by spring-boot-maven-plugin运行 spring-boot-maven-plugin 配置的胖 JAR 时出现 ClassNotFoundException
【发布时间】:2018-07-15 20:58:42
【问题描述】:

我正在尝试为我的 Spring Boot 应用程序创建可执行的 JAR 文件。 为了实现这个 spring-boot-maven-plugin 已经使用了指定的主类并打包到 jar 中。 不幸的是,在运行输出 JAR 文件后,我收到指向我的主类的 java.lang.ClassNotFoundException。

下面是我的 pom.xml 和主类。提前感谢您的帮助。

pom.xml:

    <?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>com.test</groupId>
    <artifactId>interflight</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>interflight</name>

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

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <feign-gson.version>7.2.1</feign-gson.version>
        <spring-cloud.version>Edgware.SR1</spring-cloud.version>
        <gson.version>2.8.0</gson.version>
        <assertj-core.version>3.8.0</assertj-core.version>
   <startClass>com.test.interflight.configuration.InterflightApplication</startClass>
  </properties>

    <dependencies>
    <!--External dependencies-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
        <dependency>
            <groupId>com.netflix.feign</groupId>
            <artifactId>feign-gson</artifactId>
            <version>${feign-gson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>${gson.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

    <!--Test dependencies-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    <dependency>
      <groupId>org.assertj</groupId>
      <artifactId>assertj-core</artifactId>
      <version>${assertj-core.version}</version>
      <scope>test</scope>
    </dependency>
    </dependencies>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <finalName>${project.artifactId}</finalName>
          <layout>ZIP</layout>
          <mainClass>com.test.interflight.configuration.InterflightApplication</mainClass>
        </configuration>
            </plugin>
        </plugins>
    </build>
</project>

输出错误:

    $ java -jar interflight.jar
Exception in thread "main" java.lang.ClassNotFoundException: com.test.interfl
ight.configuration.InterflightApplication
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(Laun
chedURLClassLoader.java:94)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner
.java:46)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
        at org.springframework.boot.loader.PropertiesLauncher.main(PropertiesLau
ncher.java:587)

主类:

@SpringBootApplication
@ComponentScan(basePackages = {"com.test.interflight.controller", "com.test.interflight.implementation.*"})
@EnableFeignClients(basePackages = {"com.test.interflight.api.restclient"},
                    defaultConfiguration = FeignConfiguration.class)
public class InterflightApplication {

    public static void main(String[] args) {
        SpringApplication.run(InterflightApplication.class, args);
    }
}

【问题讨论】:

  • 主类在哪个包中? InterflightApplication 类文件顶部的 package 语句是什么?
  • 您可以删除 pom.xml 中的 &lt;mainClass&gt;...&lt;/mainClass&gt; 块,因为 spring boot maven 插件将自行搜索主类。
  • @Scigs 主类位于package com.test.interflight.configuration;
  • @FlorianCramer 你是对的,但在这种情况下,这样的操作会导致Execution default of goal org.springframework.boot:spring-boot-maven-plugin:1.5.9.RELEASE:repackage failed: Unable to find main class
  • @Macieyo 看来您的 Fat Executable 是 ZIP 而不是 JAR。请查看 spring 文档以使用 ZIP docs.spring.io/spring-boot/docs/current/reference/html/… 运行 Spring Boot 应用程序

标签: java spring spring-boot classnotfoundexception spring-boot-maven-plugin


【解决方案1】:

简答:

看起来您正在使用 ZIP 布局,而您应该使用 JAR 布局。在 Spring Boot maven 插件声明中将 &lt;layout&gt;ZIP&lt;/layout&gt; 更改为 &lt;layout&gt;JAR&lt;/layout&gt;

更长的答案:

看看the docs,它将ZIP布局描述为:

  • ZIPDIR 的别名):类似于 JAR 布局使用 PropertiesLauncher

其中PropertiesLauncherdescribed in the docs 为:

  • 具有用户配置的类路径和主类的存档启动器 通过属性文件...
  • 在各个位置查找属性文件以提取加载程序设置,默认为 application.properties... 无默认值,但会回退到在 MANIFEST.MF 中查找 Start-Class

如果您希望它是您的 Jar 文件中的用户指定,请在您的 Jar 的 meta-inf 文件夹中指定(或检查您是否已经有),或自己指定属性。

【讨论】:

  • 感谢您的回答,确实ZIP 不是最佳选择,因为我的意图是接收纯JAR 文件。在尝试解决问题的过程中,我不必要地离开了它。无论如何,在将布局更改为JAR 后,我遇到了同样的错误,MANIFEST.MF 路径似乎相当不错。 MANIFEST.MF Manifest-Version: 1.0 Implementation-Vendor-Id: com.test Main-Class: org.springframework.boot.loader.JarLauncher Start-Class: com.test.interflight.configuration.InterflightApplication Spring-Boot-Classes: BOOT-INF/classes/ Spring-Boot-Lib: BOOT-INF/lib/ Created-By: Apache Maven 3.3.9 Build-Jdk: 1.8.0_92
  • 明白了。您可以将文件路径发布到您的 JAR 中的 web-inf/classes 目录中吗?
  • 这很有趣,我的 JAR 中没有这样的文件夹。它包含如下结构:BOOT-INF/libMETA-INF/maven/com.test/interflight/pom.properties&amp;pom.xmlMETA-INF/manifest.mf, org/springframework/boot/loader/archive&amp;data&amp;jar&amp;util&amp;some_class_files
  • 也许这很重要——我的项目结构包括对由目录表示的逻辑部分的分离,里面有实现、控制器、api和具有标准布局的配置:src/main/java/com.test.interflight.(API/CONTROLLER/CONFIGURATION/IMPLEMENTATION)(取决于文件夹)。只有一个 maven 模块,其父 pom.xml 包括上述文件夹结构。
  • 如果您在其中看到 /src/main/java 文件夹,我认为这是一个危险信号...它应该在 meta-inf/classes 文件夹中找到您的可运行文件。您的 pom.xml 是否与您在原始帖子中的内容有所不同?
猜你喜欢
  • 2018-09-10
  • 2018-11-12
  • 2015-01-19
  • 2014-07-21
  • 1970-01-01
  • 1970-01-01
  • 2017-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多