Add classpathentry to aspectj-classpath via Eclipse Plugin


(Daniel Platz) #1

Hi,
I am using the eclipse plugin:
apply plugin: 'eclipse'

I would like from the build.gradle modify extend the classpath to add a specific jar on the Aspects-Path for AspectJ.

So, in essence i need to do eother of those two modifications below (found it out by doing config in Eclipse and looking at .classpath):

	<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer">
		<attributes>
			<attribute name="org.eclipse.ajdt.aspectpath.restriction" value="myaspects.jar"/>
			<attribute name="org.eclipse.ajdt.aspectpath" value="org.eclipse.ajdt.aspectpath"/>
		</attributes>
	</classpathentry>

or this

<classpathentry kind="lib" path="/path/to/myaspects.jar">
	<attributes>
		<attribute name="org.eclipse.ajdt.aspectpath" value="org.eclipse.ajdt.aspectpath"/>
	</attributes>
</classpathentry>

The thing is, if i understand it correctly, i am not really interested in modifying the .classpath file in disk but just modify the model in eclipse/gradle.
I.e. what i understand/assume is that there are three callbacks where i can do stuff:

eclipse {
  
    project {
        natures = ['org.eclipse.ajdt.ui.ajnature','org.eclipse.jdt.core.javanature']
        buildCommand 'org.eclipse.ajdt.core.ajbuilder'
    }
  
    classpath {
        file {
            beforeMerged  { classpath ->
                // a
            }
            whenMerged  { classpath ->
                // b
            }

            withXml {
                // c
                def node = it.asNode();

                node.appendNode("classpathentry",  [kind:"lib", path:"/path/to/myaspects.jar"])
                        .appendNode("attributes", [:])
                        .appendNode("attribute", [name:"org.eclipse.ajdt.aspectpath", value:"org.eclipse.ajdt.aspectpath"]);
            }
        }
    }
}

a and b would be the place to modify the model in Eclipse when within Eclipse I run “Gradle -> Refresh Gradle Project”.
c is only excuted when i run the task “eclipse” explicitly.

So, i can achive modifying the .classpath with the code in option c). The problem here is, to get those changes, i have to run the “eclipse” task manually and then run a regular “Refresh” of the Project (not “Gradle -> Refresh Gradle Project”!).
What i want to achive instead i think i have to do in a) or b) to get the in-memory model in Eclipse updated.
Unfortunately, i have a problem to figure out how or if it is possible. Whatever i do does not seem to work because here I cannot simply work on the XML-model/nodes but i have to work with the Groovy/Java types like AbstractClasspathEntry, Library, Container, etc. and they seem to be immutable (e.gf when i try to modify the gradle container and attributes) or it is not possible via the API to set attributes on the Library-class.

E.g. i tried it in the following ways that all did not work out:

whenMerged  { classpath ->
    classpath.entries.each {
        if (!it.getPath().equals("org.eclipse.buildship.core.gradleclasspathcontainer")) return;
        it.writeEntryAttributes(node)
        // Not set when i read it out again:
        System.out.println("**" + it.getEntryAttributes())
    }
}

whenMerged  { classpath ->
    classpath.entries.each {
        def node = new Node(null, "classpathentry",  [kind:"lib", path:"/path/to/myaspects.jar"])
        node.appendNode("attributes", [:])
            .appendNode("attribute", [name:"org.eclipse.ajdt.aspectpath", value:"org.eclipse.ajdt.aspectpath"]);
                        
        def lib=new org.gradle.plugins.ide.eclipse.model.Library(node, new org.gradle.plugins.ide.eclipse.model.internal.FileReferenceFactory())
        lib.exported = true
        classpath.entries << lib
    }
}

Can someone point me in the right direction? Maybe it is not possible at all?

Thanks,
Daniel