web-dev-qa-db-fra.com

Le projet multi-modules Spring Boot avec Gradle ne se construit pas

Je travaille sur une application Spring Boot avec plusieurs modules et nous utilisons Gradle pour la construire. Malheureusement, je ne peux pas obtenir la bonne configuration Gradle.

La structure du projet est la suivante:

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

Lorsque j'essaie de créer le projet, j'obtiens des erreurs de compilation comme error: cannot find symbol disant que les classes des données utilisées dans les services ne sont pas importées. Et je suppose que cela est vrai entre tous les modules.

Mon parent build.gradle ressemble à ceci:

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:

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

l'un des enfants (core) a ceci dans son 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 ressemble à ceci:

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')
}

Les autres ne déclarent également que les dépendances.

La structure de dépendance ressemble à ceci:

core - apis, services, data

apis - services, data

services - data

data -

Exemple d'erreurs de compilation:

/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
17
bajermi2

Dans vos projets utilitaires (données), mettez:

bootJar {
    enabled = false
}

jar {
    enabled = true
}
34
Prime

La réponse est similaire à celle-ci .

Gradle documentation sur les versions multi-projets:

Une dépendance "lib" est une forme spéciale de dépendance d'exécution. Il provoque la construction de l'autre projet en premier et ajoute le bocal avec les classes de l'autre projet au chemin de classe.

Un pot reconditionné pose donc un problème.

Si, par exemple, le projet B dépend du projet A et si le projet A a un plugin org.springframework.boot Qui lui est appliqué, un simple compile project(':A') la dépendance ne fonctionnera pas car le fichier jar du projet est reconditionné pendant la tâche bootRepackage ou bootJar. Le pot de graisse résultant a une structure différente, empêchant Gradle de charger ses classes.

Dans ce cas, les dépendances doivent être écrites de la manière suivante:

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

Utiliser directement la sortie d'un ensemble source équivaut à utiliser le pot résultant "normal" du projet A avant qu'il ne soit reconditionné.

10
jihor

Vous devez exclure org.springframework.boot de tous les sous-modules (racine build.gradle file, allProjects block), qui sont des dépendances pour votre module de base, qui sera construit en fat-jar.

Incluez la configuration dependencyManagement dans tous vos sous-modules gérés par Spring-Boot:

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

La raison de votre problème est l'absence de fichiers jar sous-modules compilés dans votre fat-jar de module de base.

1
Alexandr Solo
bootJar {
    enabled = false
}

jar {
    enabled = true
}

Cela fonctionne pour moi. Dans mon cas, utilisez une botte de printemps avec un nuage de printemps avec plusieurs projets et Gradle ne parvient pas à construire. Avec cette solution fonctionne!

1
dariovmartine