Spring Tools Suite и Gradle - Настройка за използване на правилни ресурси от STS

Имам настройка на проект Spring Boot Gradle в Spring Tools Suite (3.7.2 RELEASE) със следните изходни папки:

- src/integration-test/java
- src/integration-test/resources 
- src/main/java
- src/main/resources
- src/test/java
- src/test/resources`

Всеки път, когато стартирам приложението или модулните тестове от STS, виждам, че STS използва ресурсите, намерени под src/integration-test/resources.

Виждам предупреждение за дублиран ресурс в STS за файлове, които съществуват във всичките 3 папки с източник на ресурс. Например, имам application.properties във всичките 3 папки източник и виждам следното:

The resource is a duplicate of src/integration-test/resources/application.properties and was not copied to the output folder

Ако стартирам приложението като JAR или модулни тестове/интеграционни тестове от командния ред (чрез gradle build), всичко изглежда използва правилните ресурси. Това ме кара да вярвам, че това е проблем с това как STS/Eclipse обработва gradle.

Някой знае ли как мога да конфигурирам STS да използва правилните папки с източници на ресурси, когато използвам gradle?

Мисля, че проблемът ми може да е свързан с (или същия?) Spring Boot неправилно зарежда тестова конфигурация, когато работи от eclipse+gradle, https://issuetracker.springsource.com/browse/STS-3882, https://issues.gradle.org/browse/GRADLE-1777

Опитах и ​​решението, намерено тук, но изглежда, че коригира само компилациите на Maven: Spring Tool Suite намира конфигурация за тест за интегриране на пролетно зареждане и не стартира основното приложение


person Adam    schedule 17.12.2015    source източник


Отговори (2)


Мисля, че проблемът ми може да е свързан с...

Да, свързано е, но според мен не е същото. Този проблем е причинен от неправилния класов път на изпълнение. Този проблем е грешка, идваща от конструктора на проекти на eclipse, така че е проблем по време на компилиране.

Проблемите обаче са тясно свързани. В зависимост от вашата гледна точка, можете да кажете, че те са еднакви (неправилно смесване на пътеки на класове за тест и по време на компилация).

Тук по-конкретно проблемът е, че конструкторът на eclipse се опитва да копира всички ресурси, които намира в изходните папки, в единствената изходна папка на проекта. Всяка папка източник има 'application.properties'. Конструкторът предупреждава, че не може да копира някои от тях, защото едното ще замени другото.

Мисля, че може да има решение за този проблем. Но това е решение, което наистина трябва да идва от Gradle + (BuildShip | STS Gradle Tooling), отколкото от вас.

Възможно е в Eclipse да конфигурирате всяка изходна папка поотделно за насочване към конкретна изходна папка. Maven + M2E правят това правилно, но комбинациите Gradle + (BuildsShip | STS Gradle Tooling) не го правят.

Например това е, което maven поставя във файла .classpath на eclipse, когато конфигурира папка с тестови ресурси:

    <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
         <attributes>
            <attribute name="maven.pomderived" value="true"/>
         </attributes>
     </classpathentry>

Забележете как изрично задава изходната папка за този запис (на нещо различно от изходната папка по подразбиране на проекта).

Може да успеете сами да се справите с проблема, като модифицирате .classpath за gradle проект по подобен начин. Или като го направите ръчно, или от вашия build.gradle.

Не съм сигурен обаче, че това си заслужава, тъй като тогава най-вероятно все още ще бъдете засегнати от проблема с класовия път на изпълнение (тъй като тези папки все още ще бъдат добавени към вашия класов път на изпълнение, вашият класов път на изпълнение ще завърши с два ресурса appication.properties, единият, който ще „засенчи" другия. Вижте: https://bugs.eclipse.org/bugs/show_bug.cgi?id=482315)

Бих казал, че правилното нещо е да добавите коментар към проблема, който свързах, и се надявам да го поправят скоро, тъй като можете да направите толкова много, като хакнете файла build.gradle, за да модифицирате .classpath (това не може да реши проблема с класовия път по време на изпълнение, но за да реши проблем с класния път по време на изпълнение, те ще трябва да конфигурират изходните папки, за да насочват към отделна изходна папка, подобно на това, което прави m2e).

person Kris    schedule 21.12.2015
comment
Добавих коментар към билета за Eclipse bugzilla, позоваващ се на този въпрос: bugs.eclipse .org/bugs/show_bug.cgi?id=482315#c8 - person Kris; 21.12.2015
comment
Виждам, че се борите с този проблем с пътя на класа по време на изпълнение от доста време. Благодаря за проверката на проблема. Мислех, че определено има нещо нередно с настройката ми, тъй като намирането на свързани проблеми не беше лесно и щях да видя този проблем веднага, когато създавам нови проекти. Засега просто стартирам извън STS. - person Adam; 22.12.2015

Бих добавил това като коментар към отговора на @Kris, но е твърде дълго.

Реших проблема с пътя на класа по време на изпълнение, като добавих кода по-долу към моя build.gradle файл. Кодът генерира конфигурация за стартиране на Eclipse за класа на приложението Spring Boot и включва само runtime classpath (т.е. без тестови JAR).

Моят проект използва приставката Gradle 'eclipse' за генериране на проектните файлове на Eclipse (които след това импортирам в Eclipse). Изпълнението на целта eclipseClasspath Gradle ще генерира стартиращия файл в основната директория на проекта.

def mainClassName = "com.example.MyApplication"
task eclipseApplicationLaunch {
    group "IDE"
    description "Generate an Eclipse launch configuration file for the Spring Boot application class"
}
eclipseApplicationLaunch << {
    def writer = new FileWriter("${mainClassName.substring(mainClassName.lastIndexOf(".")+1)}.launch")
    def xml = new groovy.xml.MarkupBuilder(writer)
    xml.doubleQuotes = true 

    xml.launchConfiguration(type: "org.eclipse.jdt.launching.localJavaApplication") { 
        listAttribute(key:"org.eclipse.debug.core.MAPPED_RESOURCE_PATHS") {
            listEntry(value:"/${project.name}/src/main/java/${mainClassName.replace(".","/")}.java")
        }
        listAttribute(key:"org.eclipse.debug.core.MAPPED_RESOURCE_TYPES") {
            listEntry(value:"1")
        }
        listAttribute(key:"org.eclipse.jdt.launching.CLASSPATH") {
            listEntry(value:"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<runtimeClasspathEntry containerPath=\"org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/\" javaProject=\"${project.name}\" path=\"1\" type=\"4\"/>\r\n")
            listEntry(value:"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<runtimeClasspathEntry path=\"3\" projectName=\"${project.name}\" type=\"1\"/>\r\n")
            configurations.runtime.resolvedConfiguration.resolvedArtifacts.each { artifact ->
                def filePath = artifact.file.canonicalPath.replace("\\","/")
                listEntry(value:"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<runtimeClasspathEntry externalArchive=\"${filePath}\" path=\"3\" type=\"2\"/>\r\n")
            }
        }
        booleanAttribute(key:"org.eclipse.jdt.launching.DEFAULT_CLASSPATH", value:"false")
        stringAttribute(key:"org.eclipse.jdt.launching.MAIN_TYPE", value:"${mainClassName}")
        stringAttribute(key:"org.eclipse.jdt.launching.PROGRAM_ARGUMENTS", value:"--spring.profiles.active=local --spring.config.location=conf/")
        stringAttribute(key:"org.eclipse.jdt.launching.PROJECT_ATTR", value:"${project.name}")
        stringAttribute(key:"org.eclipse.jdt.launching.VM_ARGUMENTS", value:"-Djava.net.preferIPv4Stack=true")
    }
    writer.close()
}
eclipseClasspath.dependsOn eclipseApplicationLaunch

Не съм модифицирал файла Eclipse .classpath според предложението на Крис. Вместо това добавих @Profile("test") към моя тестов клас на приложение и @ActiveProfiles("test") към моите тестови класове.

person Nathan    schedule 17.11.2016