Gradle und testspezifische Classpaths in Eclipse

Heute widmen wir uns einem Problem, das in einer der neuen Versionen von Gradle in Version 5.6 bereits gelöst wurde, sich allerdings für alle, die eine ältere Version verwenden, immer noch stellt.

In neueren Versionen von Eclipse sind Ressourcen, die nur zur Testzeit benötigt werden, speziell markiert. Dies führt dazu, dass diese Test-Only-Ressourcen nur von Quell-Verzeichnissen, die ebenfalls diese Markierung besitzen, benutzt werden können. Erreicht wird diese Unterscheidung durch das Anhängen eines Attributes an die Klassenpfadeinträge. Um von Eclipse erkannt zu werden, muss das Attribut test mit dem Wert true im Eintrag enthalten sein.

Hier ein Beispiel:
Angenommen folgende Dependencies stehen in unserer build.gradle

dependencies {
 implementation 'com.google.guava:guava:23.0'
 testImplementation "org.junit.jupiter:junit-jupiter-api:5.2.0"
 testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.2.0"
}

Um es einfacher zu machen, zwischen Test-Only und denjenigen Ressourcen zu unterscheiden, welche tatsächlich im späteren Build landen, stellt Eclipse auch eine visuelle Repräsentation bereit. Folgende Abbildung zeigt, wie das in Eclipse aussieht. Die gräulichen Abhängigkeiten sind als Test-Only markiert.

Schauen wir uns dazu ein paar Ausschnitte aus der .classpath Datei an:

<classpath>

<!--...-->

	<classpathentry kind="output" path="bin/default"/>
	<classpathentry output="bin/main" kind="src" path="src/main/java">
		<attributes>
			<attribute name="gradle_scope" value="main"/>
			<attribute name="gradle_used_by_scope" value="main,test"/>
		</attributes>
	</classpathentry>

	<classpathentry output="bin/test" kind="src" 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 sourcepath="C:/.../guava-23.0.jar">
		<attributes>
			<attribute name="gradle_used_by_scope" value="main,test"/>
		</attributes>
	</classpathentry>

<!--...-->

	<classpathentry sourcepath="C:/.../junit-jupiter-api-5.2.0.jar">
		<attributes>
			<attribute name="gradle_used_by_scope" value="test"/>
			<attribute name="test" value="true"/>
		</attributes>
	</classpathentry>

<!--...-->

</classpath>

So war das vor Gradle 5.6…

Vor Gradle 5.6 war Gradle mit dem neuen Feature von Eclipse noch nicht so ganz kompatibel. Um die Klassenpfadeinträge konsistent mit dem Attribut test zu versehen und eine entsprechende Anzeige in Eclipse zu erzielen, konnte man allerdings innerhalb von build.gradle folgendes Code-Schnipsel einfügen.

eclipse.classpath.file.whenMerged { classpath ->
     def testEntries = classpath.entries.findAll { 
         (it instanceof org.gradle.plugins.ide.eclipse.model.SourceFolder || 
         it instanceof org.gradle.plugins.ide.eclipse.model.Library) &amp;&amp;  
          it.entryAttributes.get('gradle_used_by_scope') == 'test' 
     }
     testEntries.each { entry->
         entry.entryAttributes.put('test','true')
     }
 }

Der Snippet aktualisiert alle Einträge des Klassenpfades, welche mit dem Eintragsattribut gradle_used_by_scope = ‘test’ markiert sind. Bei allen gefundenen Test-Einträgen wird das Attribut test mit value = true angehängt.

Short URL for this post: https://wp.me/p4nxik-3ob
This entry was posted in Eclipse Universe and tagged , . Bookmark the permalink.

Leave a Reply