java 带有 Gradle 的 Spring Boot 多模块项目无法构建

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47598848/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 09:41:54  来源:igfitidea点击:

Spring Boot multi module project with Gradle doesn't build

javaspringspring-bootgradlebuild.gradle

提问by bajermi2

I'm working on a Spring Boot app with multiple modules and we're using Gradle to build it. Unfortunately I can't get the Gradle configuration right.

我正在开发一个带有多个模块的 Spring Boot 应用程序,我们正在使用 Gradle 来构建它。不幸的是,我无法正确配置 Gradle。

The project structure is this:

项目结构是这样的:

parent
  |
  + build.gradle
  |
  + settings.gradle
  |
  + core
  |   |
  |   + build.gradle
  | 
  + apis
  |   |
  |   + build.gradle
  |
  + services
  |   |
  |   + build.gradle
  | 
  + data
  |   |
  |   + build.gradle

When I try to build the project, I get compilation errors like error: cannot find symbolsaying, that the classes from data used in services aren't imported. And I assume this is true between all the modules.

当我尝试构建项目时,我收到编译错误,比如error: cannot find symbol没有导入服务中使用的数据中的类。我假设所有模块之间都是如此。

My parent build.gradle looks like this:

我的父 build.gradle 看起来像这样:

buildscript {
    ext {
        springBootVersion = '2.0.0.BUILD-SNAPSHOT'
    }
    repositories {
        mavenCentral()
        maven { url "https://repo.spring.io/snapshot" }
        maven { url "https://repo.spring.io/milestone" }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'eclipse'
apply plugin: 'idea'

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

    group = 'com.example'
    version = '0.0.1-SNAPSHOT'
    sourceCompatibility = 1.8
    targetCompatibility = 1.8

    repositories {
        mavenCentral()
        maven { url "https://repo.spring.io/snapshot" }
        maven { url "https://repo.spring.io/milestone" }
    }

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

dependencies {
    compile project(':data')
    compile project(':services')
    compile project(':apis')
    compile project(':core')
}

jar {
    baseName = 'my-jar'
    version = '0.0.1-SNAPSHOT'
}

settings.gradle:

设置.gradle:

rootProject.name = 'my-app'
include ':apis'
include ':core'
include ':data'
include ':services'

one of children (core) has this in it's build.gradle:

其中一个孩子(核心)在它的 build.gradle 中有这个:

dependencies {
    compile('org.springframework.boot:spring-boot-starter-actuator')
    compile('org.springframework.boot:spring-boot-starter-quartz')
    compile('org.springframework.boot:spring-boot-starter-tomcat')
    runtime('com.h2database:h2')

    compile project(':data')
    compile project(':services')
    compile project(':apis')
}

services build.gradle looks like this:

服务 build.gradle 看起来像这样:

dependencies {
    compile('org.springframework.boot:spring-boot-starter-quartz')
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    runtime('com.h2database:h2')

    compile project(':data')
}

The other ones also declare only dependencies.

其他的也只声明依赖项。

The dependency structure looks like this:

依赖结构如下所示:

core - apis, services, data

apis - services, data

services - data

data -

Example of the compilation errors:

编译错误示例:

/my-app/services/src/main/java/com/example/my-app/business/IssuedTokenService.java:3: error: package com.examples.data.dao does not exist import com.examples.data.dao.IssuedToken;

/my-app/services/src/main/java/com/example/my-app/business/IssuedTokenService.java:4: error: package com.examples.data.repository does not exist import com.examples.data.repository.IssuedTokenRepository;

/my-app/services/src/main/java/com/example/my-app/business/IssuedTokenService.java:12: error: cannot find symbol 
    private IssuedTokenRepository issuedTokenRepository;

    symbol:   class IssuedTokenRepository
   location: class IssuedTokenService

/my-app/services/src/main/java/com/example/my-app/business/IssuedTokenService.java:15: error: cannot find symbol
   public void saveToken(IssuedToken issuedToken) {
                                  ^
   symbol:   class IssuedToken
   location: class IssuedTokenService

回答by Prime

In your utility (data) projects put:

在您的实用程序(数据)项目中放置:

bootJar {
    enabled = false
}

jar {
    enabled = true
}

回答by jihor

The answer is similar to this one.

答案与类似。

Gradle documentationon multi-project builds states:

关于多项目构建的Gradle文档指出:

A “lib” dependency is a special form of an execution dependency. It causes the other project to be built first and adds the jar with the classes of the other project to the classpath.

“lib”依赖是一种特殊形式的执行依赖。它会导致首先构建另一个项目,并将带有另一个项目的类的 jar 添加到类路径中。

A repackaged jar, thus, poses a problem.

因此,重新包装的罐子会带来问题。

If, say, project Bdepends on project A, and the project Ahas a org.springframework.bootplugin applied to it, a simple compile project(':A')dependency will not work because the project jar is repackaged during the bootRepackageor bootJartask. The resulting fat jar has different structure, preventing Gradle from loading its classes.

例如,如果 projectB依赖于 project A,并且该项目应用了A一个org.springframework.boot插件,那么简单的compile project(':A')依赖将不起作用,因为在bootRepackageorbootJar任务期间重新打包了项目 jar 。生成的胖 jar 具有不同的结构,从而阻止 Gradle 加载其类。

In this case, the dependencies should be written the following way:

在这种情况下,应按以下方式编写依赖项:

dependencies {
  compile project(':A').sourceSets.main.output
}

Using output of a source set directly is equivalent to using the "normal" resulting jar of project Abefore it is repackaged.

直接使用源集的输出相当于A在重新打包之前使用项目的“正常”结果jar 。

回答by Alexandr Solo

You should exclude org.springframework.bootfrom all submodules (root build.gradlefile, allProjectsblock), that are stands as dependencies for your core module, which will be build to fat-jar.

您应该org.springframework.boot从所有子模块(根build.gradle文件、allProjects块)中排除,这些子模块作为核心模块的依赖项,将构建到 fat-jar。

Include dependencyManagementconfiguration into all of your spring-boot managed submodules:

dependencyManagement配置包含在所有 spring-boot 管理的子模块中:

dependencyManagement {
    imports {
        mavenBom "org.springframework.boot:spring-boot-starter-parent:${springBootVersion}"
    }
}

The reason of your problem is the absence of submodules compiled jar files inside your core module fat-jar.

您的问题的原因是您的核心模块 fat-jar 中缺少子模块编译的 jar 文件。

回答by dariovmartine

bootJar {
    enabled = false
}

jar {
    enabled = true
}

This works for my. In my case use spring boot with spring cloud with multi project and gradle fail to build. With this solution works!

这适用于我的。在我的情况下,使用带有多项目的 spring 云的 spring boot 和 gradle 无法构建。使用此解决方案有效!