Eclipse 2018-09 не находит тестовые классы, если присутствует module-info.java - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть простой проект на Java 11 в Eclipse со следующими зависимостями:

dependencies {   
    testImplementation("org.junit.jupiter:junit-jupiter-api:${junit}")  
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junit}")
}

Структура проекта следующая:

project structure

module-info.java экспортирует только пакет simple.tests в модуль simple.tests .

У меня естьопределили следующие задачи Gradle для правильной настройки проекта Eclipse и его зависимостей.Зависимости теста находятся в пути к классам, и они видны только источникам теста.

eclipse {
    classpath {
        file {
            whenMerged {
                entries.findAll { 
                    it.kind == 'src' || it.kind == 'lib' 
                }.each { it.entryAttributes['module'] = 'true' }
            }
        }
    }
}

eclipse.classpath.file.whenMerged {

    // Setting output folder for main files
    def mainSrc = entries.find { it.path == 'src/main/java' }
    if(mainSrc != null) {
        mainSrc.output = 'bin/main'
    }

    def mainResources = entries.find { it.path == 'src/main/resources' }
    if(mainResources != null) {
        mainResources.output = 'bin/main'
    }

    // Setting output folder for test files
    def testSrc = entries.find { it.path == 'src/test/java' }
    if(testSrc != null) {
        testSrc.output = 'bin/test'
        testSrc.entryAttributes['test'] = 'true'
        testSrc.entryAttributes['module'] = 'false'
    }

    def testResources = entries.find { it.path == 'src/test/resources' }
    if (testResources != null) {   
        testResources.output = 'bin/test'
        testResources.entryAttributes['test'] = 'true'
        testResources.entryAttributes['module'] = 'false'
    }

    // Updating test dependencies' visibility and adding them to module path
    // instead of the classpath
    entries.forEach { entry ->
        def entryIn = { it.find { file(entry.path).equals(it) } }
        if (entry.kind == 'lib') {
            entry.entryAttributes['test'] =
               entryIn(configurations.testRuntimeClasspath) &&
                !entryIn(configurations.runtimeClasspath)
            if(entry.entryAttributes['test']) {
                entry.entryAttributes['module'] = 'false'
           }
        }
    }
}

Я могу скомпилировать и запустить тестовые случаи в Gradle (5.0) со следующими настройками:

test {
     useJUnitPlatform()
}

ext.moduleName = 'simple.tests' 

compileJava {
    inputs.property("moduleName", moduleName)
    doFirst {
        options.compilerArgs = [
            '--module-path', classpath.asPath,
        ]
        classpath = files()  
    }
}

Тем не менее, я не могу выполнить тест JUnit в Eclipse, потому что я получаю сообщение об ошибке (не найдено тестов с помощью Runner 5 'Junit 5) и следующую трассировку стека:

Class not found simple.tests.DummyTest
java.lang.ClassNotFoundException: simple.tests.DummyTest
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadClass(RemoteTestRunner.java:773)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadClasses(RemoteTestRunner.java:502)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:525)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)

Перемещение тестовых зависимостей в путь модуля не решает проблему.В этом случае я получаю следующую трассировку стека даже после добавления Junit Launcher в путь к модулю:

java.lang.NoClassDefFoundError: org/junit/platform/engine/EngineExecutionListener
    at org.junit.platform.launcher.core.LauncherFactory.create(LauncherFactory.java:59)
    at org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader.<init>(JUnit5TestLoader.java:34)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
    at java.base/java.lang.Class.newInstance(Class.java:584)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.createRawTestLoader(RemoteTestRunner.java:370)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.createLoader(RemoteTestRunner.java:365)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.defaultInit(RemoteTestRunner.java:309)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.init(RemoteTestRunner.java:224)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:208)
Caused by: java.lang.ClassNotFoundException: org.junit.platform.engine.EngineExecutionListener
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    ... 12 more

Единственное решение, которое я нашел, - это удаление файла module-info.java.После удаления дескриптора модуля тестовые наборы могут выполняться как в Eclipse, так и в Gradle.

Есть ли неправильные настройки в моей конфигурации?Или я что-то не так делаю?

Заранее спасибо!

...