简体   繁体   English

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

[英]Spring Boot multi module project with Gradle doesn't build

I'm working on a Spring Boot app with multiple modules and we're using Gradle to build it.我正在开发一个带有多个模块的 Spring Boot 应用程序,我们正在使用 Gradle 来构建它。 Unfortunately I can't get the Gradle configuration right.不幸的是,我无法正确配置 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 symbol saying, that the classes from data used in services aren't imported.当我尝试构建项目时,我收到编译错误,例如error: cannot find symbol表示未导入服务中使用的数据中的类。 And I assume this is true between all the modules.我认为这在所有模块之间都是正确的。

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

In your utility (data) projects put:在您的实用程序(数据)项目中放置:

bootJar {
    enabled = false
}

jar {
    enabled = true
}

If kotlin dsl如果 kotlin dsl

tasks.getByName<BootJar>("bootJar") {
    enabled = false
}

tasks.getByName<Jar>("jar") {
    enabled = true
}

The answer is similar to this one .答案与类似。

Gradle documentation on multi-project builds states:关于多项目构建的 Gradle 文档指出:

A “lib” dependency is a special form of an execution dependency. “lib”依赖是一种特殊形式的执行依赖。 It causes the other project to be built first and adds the jar with the classes of the other project to the classpath.它会导致首先构建另一个项目,并将带有另一个项目的类的 jar 添加到类路径中。

A repackaged jar, thus, poses a problem.因此,重新包装的罐子会带来问题。

If, say, project B depends on project A , and the project A has a org.springframework.boot plugin applied to it, a simple compile project(':A') dependency will not work because the project jar is repackaged during the bootRepackage or bootJar task.例如,如果项目B依赖于项目A ,并且项目A应用了org.springframework.boot插件,那么简单的compile project(':A')依赖项将不起作用,因为项目 jar 在bootRepackage期间被重新打包或bootJar任务。 The resulting fat jar has different structure, preventing Gradle from loading its classes.生成的胖 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 A before it is repackaged.直接使用源集的输出相当于在重新打包之前使用项目A的“正常”结果 jar。

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.在我的情况下,使用带有多项目和 gradle 的 spring 云的 spring boot 无法构建。 With this solution works!有了这个解决方案!

You should exclude org.springframework.boot from all submodules (root build.gradle file, allProjects block), that are stands as dependencies for your core module, which will be build to fat-jar.您应该从所有子模块(根build.gradle文件, allProjects块)中排除org.springframework.boot ,这些子模块是核心模块的依赖项,将构建到 fat-jar。

Include dependencyManagement configuration 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 文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM