简体   繁体   中英

Eclipse: Gradle source folder migration breaks JUnit test resources

I refactored an Eclipse project with using Java 11.0.10 to match Gradle's default source and resource folders instead of eclipse's source and resource folders, like this:

eclipse          Gradle
src           -> src/main/java
resources     -> src/main/resources
test          -> src/test/java
testResources -> src/test/resources

I moved the sources and resources to the folders accordingly.

When I access a test resource within a JUnit test, like TestClass.class.getResource("/my/package/mytestresource.xml") it returns [ProjectFolder]/src/main/resources/my/package/mytestresource.xml and not [ProjectFolder]/src/test/resources/my/package/mytestresource.xml . The test runs over Eclipse's JUnit launcher.

TestClass.java is located in [ProjectFolder]/src/test/my/package and the test resource in [ProjectFolder]/src/test/resources/my/package/mytestresource.xml .

This worked perfectly before the refactoring.

How can I tell Eclipse and JUnit to merge the output paths together? Or can I tell Eclipse to work with 2 output paths?

Previously the build.gradle contained this (which was removed completely):

sourceSets {
    main {
        java {
            srcDirs  = ['src']
        }
        resources {
            srcDirs  = ['resources']
        }
    }
    test {
        java {
            srcDirs  = ['src', 'test']
        }
        resources {
            srcDirs  = ['resources', 'testResources']
        }
    }
}

.classpath before changes:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" output="bin/test" path="test">
        <attributes>
            <attribute name="gradle_scope" value="test"/>
            <attribute name="gradle_used_by_scope" value="test"/>
            <attribute name="test" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="src" output="bin/test" path="src">
        <attributes>
            <attribute name="gradle_scope" value="test"/>
            <attribute name="gradle_used_by_scope" value="test"/>
            <attribute name="test" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="src" output="bin/test" path="resources">
        <attributes>
            <attribute name="gradle_scope" value="test"/>
            <attribute name="gradle_used_by_scope" value="test"/>
            <attribute name="test" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="src" output="bin/test" path="testResources">
        <attributes>
            <attribute name="gradle_scope" value="test"/>
            <attribute name="gradle_used_by_scope" value="test"/>
            <attribute name="test" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/">
        <attributes>
            <attribute name="module" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
    <classpathentry kind="output" path="bin/default"/>
</classpath>

.classpath after changes:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" output="bin/main" path="src/main/java">
        <attributes>
            <attribute name="gradle_scope" value="main"/>
            <attribute name="gradle_used_by_scope" value="main,test"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="src" output="bin/main" path="src/main/resources">
        <attributes>
            <attribute name="gradle_scope" value="main"/>
            <attribute name="gradle_used_by_scope" value="main,test"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="src" output="bin/test" path="src/test/java">
        <attributes>
            <attribute name="gradle_scope" value="test"/>
            <attribute name="gradle_used_by_scope" value="test"/>
            <attribute name="test" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="src" output="bin/test" path="src/test/resources">
        <attributes>
            <attribute name="gradle_scope" value="test"/>
            <attribute name="gradle_used_by_scope" value="test"/>
            <attribute name="test" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/">
        <attributes>
            <attribute name="module" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
    <classpathentry kind="output" path="bin/default"/>
</classpath>

I use the following software:

Windows 10 Version 2004
eclipse JDT 2021-03
Buildship 3.1.5
Gradle 6.4.1
JUnit Jupiter 5.7.0

I found two workarounds for this issue:

  1. Adding the gradle eclipse plugin to the project and manipulating the classpathentry in the .classpath file of the project:

     apply plugin: 'eclipse' eclipse { classpath { file { whenMerged { entries.each { source -> if (source.kind == 'src' && source.path.contains('src/main')) { source.entryAttributes.put("test", "true") source.output="bin/test" } } } } } }

or alternatively

  1. Re-introducing of the sourceSets in the gradle build with Gradle's default source and resource folders.

     sourceSets { main { java { srcDirs = ['src/main/java'] } resources { srcDirs = ['src/main/resources'] } } test { java { srcDirs = ['src/main/java', 'src/test/java'] } resources { srcDirs = ['src/main/resources', 'src/test/resources'] } } }

I'm not sure why this happens with eclipse, but at least it works again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM