Refresh Gradle Project override .classpath

I am using Buildship 2.0.0. When I run Gradle -> Refresh Gradle Project on a project, the .classpath file is changed.

The problem is then that entries with libraries and the output directory disappear. The Eclipse plugin I have integrated. The .classpath file should not be overwritten.

before:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
	<classpathentry kind="src" output="classes/main" path="source">
		<attributes>
			<attribute name="FROM_GRADLE_MODEL" value="true"/>
		</attributes>
	</classpathentry>
	<classpathentry kind="src" output="classes/test" path="test/java">
		<attributes>
			<attribute name="FROM_GRADLE_MODEL" value="true"/>
		</attributes>
	</classpathentry>
	<classpathentry kind="src" path="test/resources">
		<attributes>
			<attribute name="FROM_GRADLE_MODEL" value="true"/>
		</attributes>
	</classpathentry>
	<classpathentry kind="lib" path="properties_zentral"/>
	<classpathentry kind="lib" path="properties_projekt"/>
	<classpathentry kind="lib" path="lib/properties"/>
	<classpathentry kind="lib" path="images"/>
	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
	<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
	<classpathentry kind="output" path="classes/main"/>
</classpath>

after:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
	<classpathentry kind="src" path="source"/>
	<classpathentry kind="src" path="test/java"/>
	<classpathentry kind="src" path="test/resources"/>
	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
	<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
	<classpathentry kind="lib" path="properties_zentral"/>
	<classpathentry kind="lib" path="properties_projekt"/>
	<classpathentry kind="lib" path="lib/properties"/>
	<classpathentry kind="lib" path="images"/>
	<classpathentry kind="output" path="classes/main"/>
</classpath>

build.gradle

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'ru.vyarus.quality'
apply plugin: 'at.bxm.svntools'
apply plugin: 'maven'
apply plugin: 'ivy-publish'

//apply plugin: 'net.researchgate.release' //https://github.com/researchgate/gradle-release
//https://github.com/ghale/gradle-jenkins-plugin/wiki - Erzeugung Jenkins Jobs Ăźber Gradle
buildscript {
     repositories {
	    maven {
	      url 'https://plugins.gradle.org/m2/'
	    }
     }

     dependencies {
    	classpath "at.bxm.gradleplugins:gradle-svntools-plugin:latest.release"
 		classpath 'ru.vyarus:gradle-quality-plugin:2.0.0'
    }
 }

 
eclipse {
	project {
		//if you don't like the name Gradle has chosen
		name = 'ekitdev'

		//if you want to specify the Eclipse project's comment
		comment = 'devBranch'

		//if you want to append a build command with parameters:
		//buildCommand 'org.eclipse.jdt.core.javabuilder'
		buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
		buildCommand 'net.sf.eclipsecs.core.CheckstyleBuilder'

		//if you want to assign natures in a groovy fashion:
		natures = ['org.eclipse.buildship.core.gradleprojectnature', 'org.eclipse.jdt.core.javanature', 'net.sf.eclipsecs.core.CheckstyleNature']

		linkedResource name: 'properties_zentral', type: '2', locationUri: 'C:/Entwicklung/properties'
	}

	classpath {
		downloadSources = true
	    downloadJavadoc = false

   		//Änderung Ausgabeverzeichnisse
	    defaultOutputDir = file('classes/main')

	    file {
      		withXml {
		    	n ->n.asNode().classpathentry.findAll {
		    		it.@path.startsWith('test')
		    	}.each {
		    		it.@output = 'classes/test'
		    	}
      		}

			beforeMerged { classpath ->
				classpath.entries.removeAll {
					entry -> entry.kind == 'lib'
				}
			}
		}

		containers 'org.eclipse.jdt.junit.JUNIT_CONTAINER/4', 'org.eclipse.buildship.core.gradleclasspathcontainer'
    }
}


sourceSets {
    main {
        java {
            srcDirs "source"
        }

        resources {
            srcDirs += 'images' + 'source/licences'
        }

        output.classesDir = 'classes/main'
     }
    test    {
        java {
            srcDirs "test/java"
        }
        resources {
            srcDirs 'test/resources'
        }

        runtimeClasspath += files("lib/properties")
        output.classesDir = 'classes/test'
    }
}

Please use the file.whenMerged hook instead of file.withXml. The XML hook is no longer necessary, because the model you get in whenMerged contains all aspects of the classpath. Buildship only takes whenMerged into account, it does not work on XML level.

Thanks for the information. I changed it. How do I get the order in the .classpath file and how can I add the “lib” entries

it does not work: entries += new Library(fileReference(file(‘properties_zentral’)))

whenMerged {
	//change DefaultOutputfolder
	def src = entries.find { it.path == 'source' }
	src.output = "classes/main"

	def testsrc = entries.find { it.path == 'test/java' }
	testsrc.output = "classes/test"

	def testres = entries.find { it.path == 'test/resources' }
	testres.output = "classes/test"

	//Delete all lib entries
	entries.removeAll { it.kind == 'lib' }

	//Add properties entries
	entries += new Library(fileReference(file('properties_zentral')))
	entries += new Library(fileReference(file('properties_projekt')))
}

Afaik JDT only allows JARs and class folders as libraries, not arbitrary files.

The directories contain properties that I need when starting the programs. Because it is Eclipse container, I can add you only via the eclipse plugin. Do you have an idea how I managed this.

If it is a directory it should just work. Sorry I thought it was a single properties file. If it doesn’t work can you please provide an example on github?

1 Like

I’ve got it right now.

file {
	whenMerged {
		//change DefaultOutputfolder
		def src = entries.find { it.path == 'source' }
		src.output = "classes/main"

		def testsrc = entries.find { it.path == 'test/java' }
		testsrc.output = "classes/test"

		def testres = entries.find { it.path == 'test/resources' }
		testres.output = "classes/test"

		//Delete all lib entries
		entries.removeAll { it.kind == 'lib' }

		//Add properties entries
		entries += new Library(fileReference('properties_zentral'))
		entries += new Library(fileReference('properties_projekt'))
	}
}

Thank you for your support.

1 Like

I have another question about buildship and classpath updating. When will the “Project and Exetrnal Dependencies” (org.eclipse.buildship.core.gradleclasspathcontainer) rebuild in the Eclipse project. I have a new version of a library. However, the library is not updated

It is refreshed when you call “Refresh Gradle project” from the context menu

Hello,

I found the problem…

//Delete all lib entries
entries.removeAll { it.kind == ‘lib’ }

This deletes all lib entries, including those from the container.

Hello,

Can I influence the order of the elements in the .classpath?

So I need them.The properties elements must be before the GradleContainer

<classpath>
	<classpathentry kind="src" output="classes/main" path="source"/>
	<classpathentry kind="src" output="classes/test" path="test/java"/>
	<classpathentry kind="src" output="classes/test" path="test/resources"/>
	<classpathentry kind="lib" path="properties_zentral"/>
	<classpathentry kind="lib" path="properties_projekt"/>
	<classpathentry kind="lib" path="lib/properties"/>
	<classpathentry kind="lib" path="images"/>
	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
	<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
	<classpathentry kind="output" path="classes/main"/>
</classpath>

generated by eclipse plugin

<classpath>
	<classpathentry kind="src" output="classes/main" path="source"/>
	<classpathentry kind="src" output="classes/test" path="test/java"/>
	<classpathentry kind="src" output="classes/test" path="test/resources"/>
	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
	<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
	<classpathentry kind="lib" path="properties_zentral"/>
	<classpathentry kind="lib" path="properties_projekt"/>
	<classpathentry kind="lib" path="lib/properties"/>
	<classpathentry kind="lib" path="images"/>
	<classpathentry kind="output" path="classes/main"/>
</classpath>

I don’t understand what you mean. Buildship will put library entries into the container. You should never be calling ´gradle eclipse´ when using Buildship. They are mutually exclusive.

I do not run gradle eclipse manually. If I call refresh gradle on the project, the .classpath file is re-created. “Refresh gradle” I have to call that the updated libraries are loaded by the Nexus server

Buildship does not create lib entries. They might be left over from a time when you generated the classpath file manually. Please delete them from your classpath, the buildship container should already contain them.

Use the buildship plugin the eclipse tasks from build.gradle? Why does buildship change the refresh gradle .classpath file. My guess is that he re-sorted the .classpath.

Again, the libraries are already in the container (just open it in Eclipse and you’ll see them), please remove the extra entries from your classpath.

Hello,

The lib entries are not contained in my container. “properties-zentral” is in Eclipse a link to a local directory, that exists only on the workstations, but not on the buildserver. For this reason they are not stored under dependencies in the build script.

You added them to the eclipse.classpath as lib entries. Buildship puts all those lib entries into the container. If you found a case where this doesn’t hold, please create a reproducible example.

I have created an example project. With refresh gradle, the order in the .classpath file is changed.

Maybe I also have a wrong configuration of the Eclipse project. So it has always worked :slight_smile:

Thank you for the example. The problem is that you are trying to include a linked resource as a dependency, but we check for physical files. We should probably replace that with an Eclipse resource check instead.

We should also actively remove any user-defined lib entries like you checked into your .classpath file, since those would conflict with our classpath container. I’ll see if we can get both of these changes into 2.0.1.

1 Like