Gradle - compileTestGroovy не может разрешить основной класс приложения - PullRequest
0 голосов
/ 07 января 2019

У меня странная проблема. Наш проект был запущен уже 6 лет, и некоторые обновления пакета были уже давно. Серверная часть приложения написана на Java 8, тесты на Java и Groovy, а внешний интерфейс - на AngularJS 1.5

.

Приложение состоит из 7 модулей и всей структуры проекта, а процесс сборки настраивается через файлы сборки Gradle.

В процессе обновления версий библиотек самой большой из них было mongodb обновление с 4.0 и spring обновление до 5.1.3 и spring_boot версия от 1.2.6 до 2.1.1 .

Я знаю, довольно много серьезных обновлений, и благодаря всем проведенным тестам мне удалось изменить весь наш код, чтобы он соответствовал изменениям в новых версиях библиотек. Все тесты проходят. Сборка практически всех модулей работает как шарм. За исключением для модуля, состоящего из тестовых классов Groovy. Все тесты, когда я запускаю их из IntelliJ, проходят, ошибок компиляции или сборки нет.

Но когда я пытаюсь запустить gradle build, задача testCompileGroovy завершается неудачно, поскольку импорт в одном из классов спецификации абстрактного теста не может быть решен. И это импорт основного класса приложения, необходимый для параметра classes аннотации @SpringBootTest.

Здесь находится файл library.gradle со всеми библиотеками, от которых мы зависим ...

ext {
spring_version = "5.1.3.RELEASE"
spring_boot_version = "2.1.1.RELEASE"
spring_data_mongodb = "2.1.3.RELEASE"
groovy_version = "2.4.5"

ext.lib = [

        spring_core                 : "org.springframework:spring-core:$spring_version",
        spring_context              : "org.springframework:spring-context:$spring_version",
        spring_context_support      : "org.springframework:spring-context-support:$spring_version",
        spring_test                 : "org.springframework:spring-test:$spring_version",
        spring_data_mongodb         : "org.springframework.data:spring-data-mongodb:$spring_data_mongodb",
        spring_shell                : "org.springframework.shell:spring-shell:1.1.0.RELEASE",
        spring_webmvc               : "org.springframework:spring-webmvc:$spring_version",

        spring_web                  : "org.springframework:spring-web$spring_version",

        spring_boot_test            : "org.springframework.boot:spring-boot-test:2.1.1.RELEASE",

        spring_boot_starter         : "org.springframework.boot:spring-boot-starter:$spring_boot_version",
        spring_boot_starter_web     : "org.springframework.boot:spring-boot-starter-web:$spring_boot_version",
        spring_boot_starter_tomcat  : "org.springframework.boot:spring-boot-starter-tomcat:$spring_boot_version",
        spring_boot_starter_security: "org.springframework.boot:spring-boot-starter-security:$spring_boot_version",
        spring_boot_starter_test    : "org.springframework.boot:spring-boot-starter-test:$spring_boot_version",
        spring_boot_gradle_plugin   : "org.springframework.boot:spring-boot-gradle-plugin:$spring_boot_version",
        spring_boot_autoconfigure   : "org.springframework.boot:spring-boot-autoconfigure:$spring_boot_version",
        spring_boot_logging         : "org.springframework.boot:spring-boot-logging:$spring_boot_version",

        swager                      : "io.springfox:springfox-swagger2:2.6.1",
        swager_ui                   : "io.springfox:springfox-swagger-ui:2.6.1",

        groovy_all                  : "org.codehaus.groovy:groovy-all:$groovy_version",
        groovy_sql                  : dependencies.create("org.codehaus.groovy:groovy-sql:$groovy_version") {
            exclude group: "org.codehaus.groovy"
        },

        http_builder                : "org.codehaus.groovy.modules.http-builder:http-builder:0.7.1",
        httpmime                    : "org.apache.httpcomponents:httpmime:4.3.6",
        gmongo                      : dependencies.create("com.gmongo:gmongo:1.5") {
            exclude group: "org.codehaus.groovy"
        },
        postgresql                  : "org.postgresql:postgresql:9.4-1201-jdbc41",
        bonecp                      : "com.jolbox:bonecp:0.8.0.RELEASE",
        joda_time                   : "joda-time:joda-time:2.8.2",
        guava                       : "com.google.guava:guava:18.0",
        gson                        : "com.google.code.gson:gson:2.8.5",
        stripe                      : "com.stripe:stripe-java:1.37.0",
        jackson_annotations         : "com.fasterxml.jackson.core:jackson-annotations:2.4.4",
        logentries                  : "com.logentries:logentries-appender:1.1.30",
        hibernate_validator         : "org.hibernate:hibernate-validator:5.4.2.Final",
        logback_classic             : "ch.qos.logback:logback-classic:1.1.3",
        commons_lang                : "org.apache.commons:commons-lang3:3.1",
        commons_io                  : "commons-io:commons-io:2.4",
        commons_validator           : "commons-validator:commons-validator:1.4.0",
        httpclient                  : "org.apache.httpcomponents:httpclient:4.5.1",
        jasypt                      : "org.jasypt:jasypt:1.9.2",
        jsoup                       : "org.jsoup:jsoup:1.8.3",
        trimou_core                 : "org.trimou:trimou-core:1.8.2.Final",
        jackson_core                : "com.fasterxml.jackson.core:jackson-core:2.9.8",
        jackson_databind            : "com.fasterxml.jackson.core:jackson-databind:2.9.8",
        jackson_annotations         : "com.fasterxml.jackson.core:jackson-annotations:2.9.8",
        jackson_datatype_joda       : "com.fasterxml.jackson.datatype:jackson-datatype-joda:2.9.8",
        google_api_services_gmail   : dependencies.create("com.google.apis:google-api-services-gmail:v1-rev23-1.19.1") {
            exclude group: "com.google.guava"
        },
        google_http_client_jackson  : dependencies.create("com.google.http-client:google-http-client-jackson:1.19.0") {
            exclude group: "com.fasterxml.jackson.core"
        },
        javax_mail                  : "com.sun.mail:javax.mail:1.5.4",
        dnsjava                     : "dnsjava:dnsjava:2.1.7",
        email_reply_parser          : "./lib/EmailReplyParser-1.1.jar",
        salesforce                  : ["com.force.api:force-wsc:31.0.0", "com.force.api:force-partner-api:29.0.0", "com.force.api:force-metadata-api:29.0.0"],
        authy                       : 'com.authy:authy-java:1.1.0',
        libphonenumber              : 'com.googlecode.libphonenumber:libphonenumber:7.2.4',
        hellosign                   : 'com.hellosign:hellosign-java-sdk:4.0.5',
        awaitility                  : 'com.jayway.awaitility:awaitility:1.7.0',


        junit                       : "junit:junit:4.12",
        hamcrest_all                : "org.hamcrest:hamcrest-all:1.3",
        hamcrest_core               : "org.hamcrest:hamcrest-core:1.3",
        mockito_core                : "org.mockito:mockito-core:1.10.19",
        httpmime                    : "org.apache.httpcomponents:httpmime:4.3.6",
        rest_assured                : dependencies.create("com.jayway.restassured:rest-assured:2.4.1") {
            exclude group: "org.codehaus.groovy"
        },
        spock_core                  : "org.spockframework:spock-core:1.2-groovy-2.4",
        spock_spring                : "org.spockframework:spock-spring:1.2-groovy-2.4",

        apache_pdf                  : "org.apache.pdfbox:pdfbox:2.0.4",
        google_cloud                : "com.google.cloud:google-cloud-storage:1.35.0"
]}

И это build.gradle файл для модуля tests-api , который не работает.

apply plugin: 'groovy'
apply plugin: 'java'

apply plugin: 'org.springframework.boot'

repositories {
    mavenCentral()
    maven {
        url "http://repo.springsource.org/libs-release"
    }
}

dependencies {
    compile project(':api')
    compile project(':cli')

    compile lib.groovy_all
    compile lib.http_builder
    compile lib.httpmime
    compile lib.gmongo
    compile lib.hamcrest_core

    testCompile lib.groovy_all
    testCompile lib.junit
    testCompile lib.spock_core
    testCompile lib.spock_spring
    testCompile lib.spring_boot_starter_test
}

build.gradle для API модуль выглядит следующим образом:

    apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'org.springframework.boot'


buildscript {
    repositories {
        maven {
            url "http://repo.springsource.org/libs-release"
        }
        mavenLocal()
    }
    dependencies {
        classpath lib.spring_boot_gradle_plugin
    }
}

repositories {
    mavenCentral()
    maven {
        url "http://repo.springsource.org/libs-release"
    }
}

war {
    baseName = 'buyerdeck-api'
    version = '2.0'
}

dependencies {
    compile project(':backend')
    compile project(':analytics')

    compile lib.spring_webmvc
    compile lib.spring_boot_starter
    compile lib.spring_boot_starter_web
    compile lib.spring_boot_starter_tomcat
    compile lib.spring_boot_starter_security
    compile lib.jackson_core
    compile lib.jackson_annotations
    compile lib.jackson_datatype_joda

    compile lib.swager
    compile lib.swager_ui
    testCompile lib.junit
    testCompile lib.hamcrest_all
    testCompile lib.mockito_core
}

springBoot {
    mainClassName = "com.buyerdeck.Application"
}

Aaaa и build.gradle модуля backend :

apply plugin: 'java'

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    mavenCentral()
    maven {
        url "http://repo.springsource.org/libs-release"
    }
}

configurations {
    all*.exclude module: "groovy"
}

dependencies {
    compile project(':email')

    compile lib.spring_core
    compile lib.spring_context
    compile lib.spring_context_support
    compile lib.spring_data_mongodb

    compile lib.joda_time
    compile lib.guava
    compile lib.gson
    compile lib.stripe
    compile lib.jackson_core
    compile lib.jackson_databind
    compile lib.jackson_annotations
    compile lib.logentries
    compile lib.hibernate_validator
    compile lib.logback_classic
    compile lib.commons_lang
    compile lib.commons_io
    compile lib.commons_validator
    compile lib.httpclient
    compile lib.salesforce
    compile lib.jasypt
    compile lib.jsoup
    compile lib.trimou_core
    compile lib.hellosign
    compile lib.awaitility
    compile lib.authy
    compile lib.libphonenumber
    compile lib.httpmime
    compile lib.apache_pdf
    compile lib.google_cloud

    testCompile lib.spring_test
    testCompile lib.spring_boot_test
    testCompile lib.spring_boot_starter
    testCompile lib.junit
    testCompile lib.hamcrest_all
    testCompile lib.mockito_core
    testCompile lib.httpmime
    testCompile lib.rest_assured
}

task wrapper(type: Wrapper) {
    gradleVersion = '1.11'
}

sourceSets {
    test {
        java {
            srcDir 'src/test/java'
            srcDir 'src/test-integration/java'
        }
    }
}

Наконец, класс, выдающий ошибку компиляции, - это ApiSpecification.groovy из tests-api module:

    package tests.api

import com.companyxyz.Application
import com.companyxyz.backend.core.tenant.Tenant
import com.companyxyz.backend.infrastructure.mongo.MongoSetup
import org.bson.types.ObjectId
import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.test.context.ConfigFileApplicationContextInitializer
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.web.server.LocalServerPort
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.PropertySource
import org.springframework.data.mongodb.core.MongoTemplate
import org.springframework.data.mongodb.core.query.Criteria
import org.springframework.data.mongodb.core.query.Query
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.junit4.SpringRunner
import org.springframework.test.context.web.WebAppConfiguration
import spock.lang.Specification

@PropertySource("classpath:companyxyz.properties")
@SpringBootTest(classes = Application, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, properties = ["server.port:0", "mongo.database:companyxyz-test-api", "email.templates.root.path:../email-templates", "email.enabled:false", "timegate.enabled:true"])
abstract class ApiSpecification extends Specification {

    @LocalServerPort
    private int serverPort

    @Value('${mongo.database}')
    private String dbName

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    MongoSetup mongoSetup;

    private static boolean dbCleaned;

    def setup() {
        ApiSettings.apiUrl = "http://localhost:$serverPort/api/"
        ApiSettings.dbName = dbName

        println "apiurl $ApiSettings.apiUrl"
        if (!dbCleaned) {
            println "Dropping Mongo DB $dbName"
            mongoTemplate.getDb().drop();
            mongoSetup.ensureIndexes()
            dbCleaned = true;
        }
        DbExecutor.createMockThingies()
    }

    def removeUser(email) {
        mongoTemplate.remove(Query.query(Criteria.where("email").is(email)), com.companyxyz.backend.core.user.User.class)
    }


}

Ошибка в строке 3:

import com.companyxyz.Application

Не удалось разрешить импорт. Задача testGroovyCompile просто не выполняется из-за неразрешенной зависимости. Запуск тестов непосредственно из классов, расширяющих этот класс, работает без проблем.

Ничего в файле build.gradle для модуля не изменилось, за исключением того, что была добавлена ​​одна зависимость, необходимая для весенних тестов, но все остальное такое же, как и раньше. Модуль зависит от других модулей, но их файлы сборки не сильно изменились, за исключением необходимых тестовых зависимостей.

Я часами пытался заняться этим, но я просто не могу понять, почему это не работает. Я пробовал с разными версиями Gradle, но безуспешно. Кто-нибудь знает, что может быть причиной этих проблем?

Извините за длинный пост, дайте мне знать, если я могу предоставить больше информации.

Luka

1 Ответ

0 голосов
/ 07 января 2019

Проблема в том, что ваш api модуль представляет собой проект Spring Boot: по умолчанию он не будет генерировать стандартный jar, а только исполняемый файл / fat jar (или war, если у вас установлен плагин war). Даже если вы добавите зависимость 'project' compile project(':api') в модуль tests-api, Gradle не сможет предоставить классы из модуля api в путь к классам tests-api, поскольку нет стандартного встроенного jar из модуля api (подробнее о типе зависимости проекта здесь ):

[lib] зависимость [Project] - это особая форма зависимости выполнения. Это заставляет другой проект быть сначала собранным и добавляет jar с классами другого проекта в путь к классам. Он также добавляет зависимости другого проекта в путь к классам.

Итак, я вижу два варианта решения вашей проблемы:

1) ( PREFERRED ) Настройте плагин SpringBoot в модуле api для получения стандартного jar

build.gradle из модуля API :

jar {
    enabled = true
}

См .: https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/gradle-plugin/reference/html/#packaging-executable-and-normal

2) Создание зависимости от tests-api до api модулей. SourceSet:

build.gradle из модуля тест-API :

dependencies {
    compile project(':api').sourceSets.main.output
    // others
}

(решение 2 должно работать, но не тестироваться. Может вызвать ошибку с api зависимостями проекта, недоступными в tests-api модуле)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...