Как запустить тестовое задание gradle JUnit без исходных файлов, но с fat jar?

#java #gradle #junit #fatjar

#java #gradle #junit #fatjar

Вопрос:

Я очень новичок в мире JVM и не могу понять, как решить следующую проблему:

У меня есть проект gradle, который создает тестовый uber jar (созданный с помощью плагина shadowJar) с выводом тестов JUnit. Я могу запустить этот uber jar в том же проекте, используя что-то вроде этого:

 task runFatJar(type: Test) {
    dependsOn shadowJar
    classpath = project.files( "$buildDir/libs/fatjar.jar", configurations.runtime )
    outputs.upToDateWhen { false }
}
  

Однако я хочу создать очень маленький gradle.build файл для запуска этого же задания с уже предварительно созданным jar.
Чтобы уточнить это: у меня есть мой проект A, который создает этот fat jar, и я хочу иметь проект B, в котором есть только runFatJar задача и нет исходных текстов.

Я попытался сделать что-то подобное с моим проектом B:

 apply plugin: 'java'

buildscript {
    repositories {
        jcenter()
    }
}

repositories {
    jcenter()
}

dependencies {
   testRuntime("org.junit.vintage:junit-vintage-engine:5.4.1")
}

tasks.withType(Test) {
    systemProperties = System.getProperties()
    systemProperties.remove("java.endorsed.dirs")
}

configurations {
  itestCompile.extendsFrom testCompile
  itestRuntime.extendsFrom testRuntime
}

task runFatJar(type: Test) {
    classpath = project.files( "$buildDir/fatjar.jar", configurations.runtime )
    outputs.upToDateWhen { false }
}
  

Моя структура папок выглядит следующим образом:

 ├───build
└───src
    └───test
        └───resources
            └───features
  

и после того, как я запустил gradle runFatJar , оно становится таким:

 ├───.gradle
│   ├───5.2.1
│   │   ├───executionHistory
│   │   ├───fileChanges
│   │   ├───fileContent
│   │   ├───fileHashes
│   │   └───vcsMetadata-1
│   ├───buildOutputCleanup
│   └───vcs-1
├───build
│   └───resources
│       └───test
│           └───features
└───src
    └───test
        └───resources
            └───features
  

Но вывод gradle на самом деле ничего не делает:

 > gradle runFatJar --info
Initialized native services in: C:Usersderwasp.gradlenative
The client will now receive all logging from the daemon (pid: 6960). The daemon log file: C:Usersderwasp.gradledaemon5.2.1daemon-6960.out.log
Starting 3rd build in daemon [uptime: 49.78 secs, performance: 97%, no major garbage collections]
Using 8 worker leases.
Starting Build
Settings evaluated using settings file 'D:Temp!deletemesettings.gradle'.
Projects loaded. Root project using build file 'D:Temp!deletemebuild.gradle'.
Included projects: [root project '!deleteme']

> Configure project :
Evaluating root project '!deleteme' using build file 'D:Temp!deletemebuild.gradle'.
All projects evaluated.
Selected primary task 'runFatJar' from project :
Tasks to be executed: [task ':compileJava', task ':processResources', task ':classes', task ':compileTestJava', task ':processTestResources', task ':testClasses', task ':runFatJar']
:compileJava (Thread[Execution worker for ':',5,main]) started.

> Task :compileJava NO-SOURCE
file or directory 'D:Temp!deletemesrcmainjava', not found
Skipping task ':compileJava' as it has no source files and no previous output files.
:compileJava (Thread[Execution worker for ':',5,main]) completed. Took 0.007 secs.
:processResources (Thread[Execution worker for ':',5,main]) started.

> Task :processResources NO-SOURCE
file or directory 'D:Temp!deletemesrcmainresources', not found
Skipping task ':processResources' as it has no source files and no previous output files.
:processResources (Thread[Execution worker for ':',5,main]) completed. Took 0.001 secs.
:classes (Thread[Execution worker for ':',5,main]) started.

> Task :classes UP-TO-DATE
Skipping task ':classes' as it has no actions.
:classes (Thread[Execution worker for ':',5,main]) completed. Took 0.0 secs.
:compileTestJava (Thread[Execution worker for ':',5,main]) started.

> Task :compileTestJava NO-SOURCE
file or directory 'D:Temp!deletemesrctestjava', not found
Skipping task ':compileTestJava' as it has no source files and no previous output files.
:compileTestJava (Thread[Execution worker for ':',5,main]) completed. Took 0.001 secs.
:processTestResources (Thread[Execution worker for ':',5,main]) started.

> Task :processTestResources UP-TO-DATE
Skipping task ':processTestResources' as it is up-to-date.
:processTestResources (Thread[Execution worker for ':',5,main]) completed. Took 0.011 secs.
:testClasses (Thread[Execution worker for ':',5,main]) started.

> Task :testClasses UP-TO-DATE
Skipping task ':testClasses' as it has no actions.
:testClasses (Thread[Execution worker for ':',5,main]) completed. Took 0.0 secs.
:runFatJar (Thread[Execution worker for ':',5,main]) started.

> Task :runFatJar NO-SOURCE
Skipping task ':runFatJar' as it has no source files and no previous output files.
:runFatJar (Thread[Execution worker for ':',5,main]) completed. Took 0.001 secs.
  

Я даже не знаю, зачем сейчас с этим работать. Есть ли способ заставить это задание запускаться без наличия файлов фактического исходного кода?

Ответ №1:

Мне потребовалось некоторое время, чтобы понять это, но вот последний файл gradle, который делает трюк:

 apply plugin: 'java'

compileJava.options.encoding = 'UTF-8'

tasks.withType(Test) {
    systemProperties = System.getProperties()
    systemProperties.remove("java.endorsed.dirs")
}

task runBinaryTests(type: Test) {
    testClassesDirs = project.files( "$projectDir/unzipped", configurations.runtime )
    classpath = project.files( "$projectDir/fatjar.jar", configurations.runtime )
    outputs.upToDateWhen { false }
}
  

Единственное обязательное условие — выполнить unzip -qq fatjar.jar -d unzipped правильное действие перед вызовом runBinaryTests . Хотя gradle может работать с zip-деревьями, он довольно плохо справляется с UTF-8, который есть в именах файлов cucumber. Если кто-нибудь знает, как это исправить, вот файл gradle, который вы можете использовать, не разархивируя jar вручную:

 apply plugin: 'java'

compileJava.options.encoding = 'UTF-8'

tasks.withType(Test) {
    systemProperties = System.getProperties()
    systemProperties.remove("java.endorsed.dirs")
}

task runBinaryTests(type: Test) {
    testClassesDirs  = zipTree($projectDir/fatjar.jar)
    classpath = project.files( "$projectDir/fatjar.jar", configurations.runtime )
    outputs.upToDateWhen { false }
}