为依赖于其他项目的 spring 引导应用程序创建胖 jar 时出现异常

Exception while creating a fat jar for spring boot application which depends on other project

这是我之前问题的后续 Convert gradle multi project to springboot fat jar application

我有一个 http servlet 应用程序,它是一个多项目 gradle 构建,我的项目是一个包含 gradle HttpServlet 项目,它依赖于其他两个 gradle java 个项目。我在 tomcat webapps/Web-INF/lib 目录和 运行 目录中部署了所有 3 个 jar。

现在有一个要求,我必须将我的应用程序转换为 spring 启动应用程序,而不是 3 个单独的 jar,我必须创建一个我应该 运行 的 fat jar。

我运行我的代码如下

    Rootrepository
      - settings.gradle 
     - build.gradle
      - Springboot project
         - build.gradle
         -src….
    - OtherGardleProject1
        - Src…
    - OtherGardleProject2
        - Src…

Please see `root project’s build.gradle`

version = '1.0.0'
group = ‘myproj’
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'groovy'
apply plugin: 'eclipse'

subprojects {
    repositories {
        mavenCentral()
            }
    }

    apply plugin: 'java'

    sourceCompatibility = 1.8

    compileJava

    jar {
     from sourceSets.main.allSource
    }
}

subprojects.each { subproject ->
  evaluationDependsOn(subproject.path)
}


task mmJar(type: Jar, dependsOn: subprojects.jar) {
      manifest {
        attributes 'Main-Class': 'org.springframework.boot.loader.JarLauncher'
        attributes 'Start-Class': ‘mypackage.springboot.Application'
    }
  subprojects.each { subproject ->
    from subproject.configurations.archives.artifacts.files.collect {
      zipTree(it)
    }
  }
}


dependencies {
        compile 'junit:junit:4.12'
        compile 'org.slf4j:slf4j-api:1.7.7'
}

请看springboot projects’ build.gradle

buildscript {
    ext {
        spring_plugin_version = '2.1.1.RELEASE'
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:$spring_plugin_version")
        classpath "io.spring.gradle:dependency-management-plugin:1.0.3.RELEASE"

    }
}

apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'



dependencies {
    implementation('org.springframework.boot:spring-boot-starter-quartz')
    implementation('org.springframework.boot:spring-boot-starter-web')

    compile project(‘:otherproject1’)


    compile group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1'

    compile group: 'commons-io', name: 'commons-io', version: '2.4'
    compile('org.springframework:spring-webmvc')

    runtimeOnly('org.springframework.boot:spring-boot-devtools')
    compileOnly('org.projectlombok:lombok:1.18.8')
    annotationProcessor('org.projectlombok:lombok:1.18.8')

    testCompile('org.springframework.boot:spring-boot-starter-test')
}

然后我 运行 gradle clean assemble mmJar 并且它按预期创建了一个 fat jar。

但是当我尝试 运行 java -jar build/libs/myproj-1.0.0.jar

Exception in thread "main" java.lang.IllegalStateException: Failed to get nested archive for entry BOOT-INF/lib/JavaEWAH-1.1.6.jar
    at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchive(JarFileArchive.java:108)
    at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchives(JarFileArchive.java:86)
    at org.springframework.boot.loader.ExecutableArchiveLauncher.getClassPathArchives(ExecutableArchiveLauncher.java:70)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:49)
    at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
Caused by: java.io.IOException: Unable to open nested jar file 'BOOT-INF/lib/JavaEWAH-1.1.6.jar'
    at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:256)
    at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:241)
    at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchive(JarFileArchive.java:103)
    ... 4 more
Caused by: java.lang.IllegalStateException: Unable to open nested entry 'BOOT-INF/lib/JavaEWAH-1.1.6.jar'. It has been compressed and nested jar files must be stored without compression. Please check the mechanism used to create your executable jar file
    at org.springframework.boot.loader.jar.JarFile.createJarFileFromFileEntry(JarFile.java:284)
    at org.springframework.boot.loader.jar.JarFile.createJarFileFromEntry(JarFile.java:264)
    at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:252)
    ... 6 more

有人可以告诉我我做错了什么吗?

正如@M.Deinum 和我在链接 post 中所建议的,只需让 spring 引导 gradle 插件完成这项工作。在您的根文件夹中保留 settings.gradle 文件并删除 build.gradle。 运行

gradle clean build

Rootrepository 文件夹中。 Gradle 将构建包含在 settings.gradle 中的项目并在 Springboot project/build/libs 文件夹中创建 fat jar