spring-io / initializr

A quickstart generator for Spring projects

Home Page:https://start.spring.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Configure KAPT gradle plugin when an annotation processor is selected

leonard84 opened this issue · comments

The initializr should generate the appropriate entries for KAPT if the language is Kotlin and the ConfigurationProcessor is selected as dependency.

In gradle you just need to add the processor as an dependency to the kapt configuration:
dependencies { kapt "org.springframework.boot:spring-boot-configuration-processor" }
https://stackoverflow.com/questions/37858833/spring-configuration-metadata-json-file-is-not-generated-in-intellij-idea-for-ko

Maven is a bit more verbose https://kotlinlang.org/docs/reference/kapt.html and requires declaration of the kapt goal. However, there is an open issue that prevents kapt from working if a compiler plugin (e.g. kotlin-maven-allopen) is added as dependency https://youtrack.jetbrains.com/issue/KT-18022

@leonard84 start.spring.io doesn't know that entry is an annotation processor and I am not keen to bring that complexity at this point. I'd like to find another way to make it interoperable. Perhaps @sdeleuze knows?

@snicoll I just tested it, you actually don't need to define the spring-boot-configuration-processor inside the maven goal again. Just executing kapt is enough for it to be picked up, if it is already on the classpath. So the question is, whether to just always include the kapt goal, which would mimic normal javac behavior of executing the annotation processors, or add logic to only add the goal if an annotation processor is present.

I haven't found a simple way for gradle to omit the kapt configuration and have it run anyways. You can use configurations.kapt.extendsFrom(configurations.compileOnly) however I don't think that this is better than just declaring the kapt dependency.

I don't think that's the question. Annotation processors are automatically invoked with Java (it's part of the spec) so I'd rather have that with Koltin if we can. Implementing what you're asking means that initializr has to be aware that the dependency is in fact an annotation processor and I am not sure I like that idea.

@snicoll if you want it to behave similar to Java then you just need to declare the kapt execution for maven and extend the kapt configuration for gradle configurations.kapt.extendsFrom(configurations.compileOnly).

You already put annotation processors into a special scope compileOnly, that goes for spring-boot-configuration-processor as well as lombok. As far as I can see those are the only two depdendencies that are in that scope. So in a way you already know which dependency is an annotation processor.

I disagree that compileOnly means annotation processor actually. So no, I don't know those dependencies are annotation processors which brings me back to my first comment.

Kotlin requires an explicit plugin declaration for annotation processors support and it is unlikely to change, so I don't see a better solution than adding an optional boolean metadata like requireAnnotationProcessors on dependencies that requires it + add a language specifics support to add the relevant Maven/Gradle configuration.

@sdeleuze you are describing the current situation and I think it can be improved (especially when one claims 100% interoperability with Java). I've created https://youtrack.jetbrains.com/issue/KT-18289

My request has been declined so we'll need to make this work here.

Was anyone able to successfully use kapt to generate spring boot configuration metadata? I've created the simplest possible project with Gradle, but when I run build nothing happens. https://github.com/dima767/bootiful-kt-with-config-metadata-processing If someone could point me to a right direction that would be appreciated!

@dima767 To generate Spring Boot configuration metadata, you should use var instead of val here. I will update Spring Boot reference documentation to mention that kapt should be used.

So it seems with #653, this issue will be straightforward to fix as suggested by @snicoll.

I have commented on KT-18022 to ask it to be reopened.

I am not sure if the issue in kotlin is still present.. I was able to make it working using following configuration:

            <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <configuration>
                    <args>
                        <arg>-Xjsr305=strict</arg>
                    </args>
                    <compilerPlugins>
                        <plugin>spring</plugin>
                    </compilerPlugins>
                </configuration>
                <executions>
                    <execution>
                        <id>kapt</id>
                        <goals>
                            <goal>kapt</goal>
                        </goals>
                        <configuration>
                            <annotationProcessorPaths>
                                <annotationProcessorPath>
                                    <groupId>org.springframework.boot</groupId>
                                    <artifactId>spring-boot-configuration-processor</artifactId>
                                    <version>${spring-boot.version}</version>
                                </annotationProcessorPath>
                            </annotationProcessorPaths>
                        </configuration>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-allopen</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                </dependencies>
            </plugin>

Perhaps this info from kapt docs is also relevant:

Please note that kapt is still not supported for IntelliJ IDEA’s own build system. Launch the build from the “Maven Projects” toolbar whenever you want to re-run the annotation processing.
https://kotlinlang.org/docs/kapt.html#using-in-maven

commented

Any update regarding this? In addition to my lack of knowledge about the internal of this project, the discussion is also old, so not sure what comment is still relevant. But I'm a bit confused as to why this is proper to do here. There's already some logic to customize the build file if any annotation processor exists (e.g. GradleAnnotationProcessorScopeBuildCustomizer). The challenge is that in the customizer I don't know the language, so can't decide between kapt and annotationProcessor. To solve that I have to override the configurationForDependency method in KotlinDslGradleBuildWriter. The only thing is to make a sub-type of GradleBuild to expose the language. Does that make sense? (Happy to help if the solution makes sense.)

Well, now, Kotlin says:

kapt is in maintenance mode.
Please use the Kotlin Symbol Processing API (KSP) for annotation processing.

So, what is the right approach for spring configuration processor now? :-)

We've decided to restrict this fix to Gradle only. Unfortunately, supporting Maven is too challenging at this time as it requires us to hardcode the version of the annotation processor in one way or another and we're not keen to do that. I've created https://youtrack.jetbrains.com/issue/KT-59521/ to ask the Kotlin team to provide a feature of the plugin where it'd resolve the annotation processor version.