Gradle integration for eclipse keeps on changing .classpath file

My current configuration includes a Java WAR project using gradle with the java and eclipse-wtp plugins, and the latest version of Buildship for Eclipse integration (1.0.3 till this morning and 1.0.4 right now) along with Eclipse Luna.

After following this solution http://stackoverflow.com/a/9820317/1544713 (successfully) to avoid deploying the test classes to my local server, I noticed that every time I refreshed the project or closed and opened Eclipse, the .classpath file and .settings/org.eclipse.wst.common.component were changed to their previous state, which is something I that gives me problems (deploying the test classes to the local server implies that they will fail to be loaded due to the lack of some test time dependencies, and of course an undesired behaviour).

The content of .classpath is changed from (the right one):

<classpathentry kind="src" output="target/test-classes" path="src/test/java">
    <attributes>
        <attribute name="FROM_GRADLE_MODEL" value="true"/>
    </attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/resources">
    <attributes>
        <attribute name="FROM_GRADLE_MODEL" value="true"/>
    </attributes>
</classpathentry>

to this undesired state:

<classpathentry kind="src" path="src/test/java">
    <attributes>
        <attribute name="FROM_GRADLE_MODEL" value="true"/>
    </attributes>
</classpathentry>
<classpathentry kind="src" path="src/test/resources">
    <attributes>
        <attribute name="FROM_GRADLE_MODEL" value="true"/>
    </attributes>
</classpathentry>

And in the case of .settings/org.eclipse.wst.common.component, these two lines are added (which again, I don’t want them to be present):

    <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/java"/>
    <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/resources"/>

I can’t figure out if it is Gradle that is changing the files or Buildship, or even Eclipse. In any case, I guess there is a way to stop this happening. I have tried many alternatives, like the following configs in build.gradle:

eclipse.classpath.file.whenMerged { cp ->
    cp.entries.findAll { it.kind = "src" && it.path.startsWith("src/test/") }*.output = "target/test-classes"
}

eclipse {
    wtp.component {  
        file.withXml { xml ->       
            def node = xml.asNode()                     
            def wbrNodes = node.'**'.findAll { it.name() == 'wb-resource' && it.'@source-path'.startsWith("/src/test/")}
            if (wbrNodes.size() > 0) {
                wbrNodes.each { n -> n.parent().remove(n) }
            }                   
        }
    }
}

But this configuration works erratically (sometimes it seems to work, some other times it doesn’t, and actually the first piece of code that starts with eclipse.classpath.file.whenMerged never works).

Thanks in advance.

I have started to think that Buildship is my real problem, but i’m still unsure about why… Any help?

I’m pretty sure you can’t use the eclipse plugin and buildship together. You’ll need to choose one or the other since they both manipulate the .classpath and .project files.

Do you know if there is a way to prevent Buildship from modifying the .classpath and .settings/org.eclipse.wst.common.component when they have been manually changed?

I don’t think that’s currently possible. I think buildship assumes it owns .classpath and .project and can therefore do what it wants with them.

Sounds like you want

apply plugin: 'buildship' 

buildship.wtp.component.file.withXml { ... } 

This doesn’t exist but sounds like a reasonable feature request.

1 Like

Anyways, I still don’t understand how it is possible that something which (to me) seems a typical problem as preventing the test classes from being deployed in a local server can’t be handled in any way with Buildship…

I doubt that buildship currently supports wtp projects. I’d guess wtp support is part of the future roadmap.

Can you just have a normal (non wtp) project and deploy the war built by gradle? This won’t contain test classes

Unluckily, I’m using JRebel to reload dynamically the classes while developing, so I depend on the stuff auto-compiled by Eclipse located in /bin/, and that’s why I wanted to move the *Test.class from /bin/ to anywhere else…

Right now I’m trying with the other Gradle integration plugin (the one from Nodeclipse in the Eclipse Marketplace) to see if I can get a better result with it.

I think wtp and buildship have conflicting goals. One of buildship’s main goals is that eclipse is NOT the build tool. Everything is built by gradle and nothing is built to /bin/

Perhaps you could achieve the same functionality by running a --continuous task. The task could unzip the war to the server directory any time an input changes (eg a class file)

FYI gretty supports hot deployment

http://akhikhl.github.io/gretty-doc/Hot-deployment.html

Thanks for your help Lance_Java. You are right, you can’t mix Buildship with the gradle plugin eclipse-wtp.

In the end, I had to change from Buildship to Gradle IDE Pack 3.6.x+0.17 which uses build.gradle to build its model… It’s a pity because I wanted to use the official tools as much as possible, but this limitation (and the fact that Buildship doesn’t show custom tasks, though being a smaller limitation) made me leave it.

Keep in mind that buildship is still in it’s infancy and the first release was 3 months ago. I’m sure WTP support is on the todo list.

I suggest you raise a feature request for the “withXml” hook I suggested above. Buildship improvements seem to arrive quickly from what I’ve seen. A new version was just announced 5 hours ago!

It’s likely some (most?) of this feature could be copied from the eclipse plugin

I’m having the same issue. Does anyone know of a workaround or whether there are any plans of fixing it?

Nearly four years later, this problem still exists. Buildship infancy is no longer a viable explanation. Shall we infer that the official position is to just deal with it?