eclipse / buildship

The Eclipse Plug-ins for Gradle project.
533 stars 171 forks source link

Annotation Processor configuration from Gradle Eclipse Plugin #329

Open donat opened 7 years ago

donat commented 7 years ago

Original post: https://bugs.eclipse.org/bugs/show_bug.cgi?id=480066

eximius313 commented 6 years ago

It seems that there will be (some) support for annotation processors if Gradle 4.6 (https://github.com/gradle/gradle/pull/4217)

oehme commented 6 years ago

gradle/gradle#4217 has nothing to do with the eclipse plugin. Please follow https://github.com/gradle/gradle/issues/2300 for progress on modelling annotation processor configuration better

donat commented 5 years ago

I'm started looking into the possibilities of how to implement this feature. The first thing I'd like to check if we can advise people to apply the net.ltgt.apt-eclipse plugin and let them execute the eclipse task before every project synchronization/auto-build. @tbroyer what do you think?

oehme commented 5 years ago

Not the eclipse task, since that would contradict Buildship's project/classpath model. We should only invoke the task that generates the factoryPath.

tbroyer commented 5 years ago

Well, I wouldn't advise people to use an unmaintained plugin… (and by unmaintained, I mean that I archived the project on Github and have absolutely no willingness to maintain it any further; I have zero incentive to begin with: I've been using IntelliJ IDEA exclusively for the past 5 years or so, as do my teammates, and it now imports Gradle projects without any specific configuration)

Feel free to copy code from the plugin into Buildship and/or Gradle though (it's Apache licensed after all).

blackfoxoh commented 4 years ago

I just stumbled upon this issue while now having to use a annotationprocessor. Seems I have to give the net.ltgt.apt-eclipse plugin a try even it is unsupported now (thanks @tbroyer for publishing your plugin). Is there any chance to get this fixed for one of the next buildship releases?

blackfoxoh commented 4 years ago

For now I ended up with a different solution:

eclipse {
    classpath {
        ... maybe doing something else here like dealing with containers....

        // factorypath (for Annotation-Processors)
        def fpfile = file('.factorypath')
        if (fpfile.exists()) {
            def xml = new XmlParser().parse(fpfile)
            xml.factorypathentry.findAll{it.@kind == 'EXTJAR'}.each{xml.remove(it)}
            project.configurations.codeGeneration.each { dep->
                def curDep = xml.factorypathentry.find{it.@id.endsWith dep.name}
                def newDep = new NodeBuilder().factorypathentry(kind:'EXTJAR', id:dep.absolutePath, enabled:true, runInBatchMode:false)
                if (curDep){
                    curDep.replaceNode(newDep)
                } else {
                    xml.append(newDep)
                }
            }
            new XmlNodePrinter(new java.io.PrintWriter(fpfile), "    ").print(xml)
        } else {
            fpfile.withWriter {
                new groovy.xml.MarkupBuilder(it).'factorypath' {
                    project.configurations.codeGeneration.each { dep->
                        factorypathentry(
                            kind:'EXTJAR',
                            id:dep.absolutePath,
                            enabled:true,
                            runInBatchMode:false)
                    }
                }
            }
        }
    }
}

In short this groovy-code covers the usecase of not having a .factorypath file as well as having one with entrys of kind other than 'EXTJAR'. Existing EXTJAR entrys are considered from an earlier refresh-gradle so they are getting cleaned and recreated if still configured in gradle. Entrys other thaen EXTJAR are kept. As source for the new entrys I use a gradle configuration codeGeneration to which a declare the dependency:

configurations {
    codeGeneration
}
dependencies {
   ...
   codeGeneration 'xxx:yyy:4.+'
}

Now a "refresh-gradle" on a project (re-)generates the .factorypath withdependency linked from the local gradle-cache. All the other settings like code-gen directory and other settings necessary are in configurationfiles we have under source control anyway. In fact the .factorypath is under versioncontrol as well but had the problem of referencing the jar in an abolut path with the username inside (gradle cache). Having the groovy-code in eclipse classpath assures it is executed by refresh-gradle. Looking at gradles eclipse task the eclipse-jdt would be a better match but it doesn't get executed by buildship there... This solution is still a workaround and might not suite to everyones needs but maybe it helps some of you or maybe it can inspire a solution for this issue... Cheers

nedtwigg commented 4 years ago

With @tbroyer's blessing, we have fixed the Gradle 6 deprecation warnings in net.ltgt.apt-eclipse, and republished as com.diffplug.eclipse.apt as part of the goomph plugin. We will continue to maintain and fix any deprecations in the future.

pedrolamarao commented 3 years ago

I've just been bitten by this in a project which uses Lombok.

kdvolder commented 3 years ago

@pedrolamarao Even if BuildShip supported APT config, that wouldn't help you in this case. Lombok Eclipse integration doesn't use APT. Instead Lombok support uses a Java Agent which you have to install and attach to your Eclipse. The agent modifies Eclipse JDT compiler and tooling. The point is, this is something you install separately yourself and has nothing to do with Eclipse APT.

So, while I do think having BuildShip support APT configs, in general, would be good. In this particular case, its not going to help you and you don't need it. Just install Lombok support for Eclipse. See: https://projectlombok.org/setup/eclipse

eximius313 commented 3 years ago

As far as I know, Lombok jar is both: Annotation processor and JavaAgent for Eclipse.

kdvolder commented 3 years ago

It is an annotation processor sure, if you run it from command line using javac (or indirectly using javac via gradle or maven or whatnot). But to get Eclipse tooling to properly understand your lombok code and so not pester you with lots of invalid compilation errors etc... you need the JavaAgent installed. This modifies Eclipse compiler and tooling to understand lombok. So... even if BuildShip would somehow configure the APT to run the annotation processor it still wouldn't really help with Eclipse integration for lombok. That is my understanding anyway. But I could be wrong.

Edit: Also on the flip side. If you install the javagent support for lombok today, even without any support from BuildShip to configure APT, lombok works fine in Eclipse Gradle projects.

eximius313 commented 3 years ago

As far as I know, Eclipse can use generated classes when configured properly (and this is what I believe this issue is about). And Lombok isn't the only AnnotationProcessor. Some examples might be: hibernate-jpamodelgen or Mapstruct

kdvolder commented 3 years ago

As far as I know, Eclipse can use generated classes when configured properly

Well, I would challenge you to try and do that. Configure Eclipse APT so that it runs the lombok annotation processors. Yes, this is totally possible. But I think you'll find that you cannot actually make Eclipse JDT tooling work properly with the compiled classes and lombok annotated sources at the same time. The problem is that you cannot have Eclipse be aware of both the source code of your 'lombokked' java code and your compiled code at the same time. This would mean that you have two different versions of the same classes on your classpath at the same time. I could be wrong of course but I don't think you can just make lombok integrate nicely with Eclipse simply by telling it to run the annotation processors and configuring build paths.

I am however 100% sure that you can already have decent lombok support without any of this if you just install the lombok Java agent.

Anyway there's no need to discuss this further. This issue, as has been said is about adding APT integration to BuildShip. That is something I fully support. All I am trying to say here is that Lombok integration won't benefit from this and isn't a 'use case' for this. I only spoke up about that because it seems people have a misunderstanding about it here.