I use kotlin and java with spring boot to develop my project.
My build tool is gradle, a task is defined as follows:
configurations {
providedRuntime
jpametamodel
}
dependencies {
jpametamodel ('org.hibernate:hibernate-jpamodelgen:4.3.11.Final')
}
task generateMetaModel(type: JavaCompile, group: 'build', description: 'metamodel generate') {
source = sourceSets.main.java
classpath = configurations.compile + configurations.jpametamodel
options.compilerArgs = ["-proc:only"]
destinationDir = sourceSets.generated.java.srcDirs.iterator().next()
doFirst {
delete(sourceSets.generated.java.srcDirs)
}
}
This task works with out kotlin class, but if I add kotlin class, the task cannot work by throw the following errors:
Hibernate JPA 2 Static-Metamodel Generator 4.3.11.Final
/.../src/main/java/com/app/web/rest/UserResource.java:18:
Cannot find .....
import com.app.web.rest.dto.SimpleUser;
^
Symbol: Class SimpleUser
Position: Package com.app.web.rest.dto
The SimpleUser is defined in kotlin file:
SimpleUser.kt
data class SimpleUser(val str:String)
The Hibernate meta-model generator is implemented as a JSR 269 annotation processor. When using Kotlin, you'll need to enable annotation processing explicitly by applying the kapt compiler plugin. When you do that, you'll find that the meta-model gets generated for Kotlin entities.
Related
I am trying to build a simple maven library and I can't get it to build. I am using Gradle Groovy and Kotlin Multiplatform Library in IntelliJ IDEA.
I haven't even been able to begin coding since my dependencies wont load. I am very new to all this so bare with me.
This is my build.gradle
plugins {
id 'org.jetbrains.kotlin.multiplatform' version '1.7.10'
}
group = 'me.me'
version = '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies{
implementation platform("io.cucumber:cucumber-bom:7.1.0")
implementation 'io.cucumber:cucumber-java'
implementation 'io.cucumber:cucumber-junit-platform-engine'
implementation 'io.cucumber:cucumber-junit'
implementation 'io.cucumber:cucumber-spring'
implementation 'com.googlecode.json-simple:json-simple:1.1.1'
}
kotlin {
jvm {
compilations.all {
kotlinOptions.jvmTarget = '1.8'
}
withJava()
testRuns["test"].executionTask.configure {
useTestNG()
}
}
sourceSets {
commonMain {
}
commonTest {
dependencies {
implementation kotlin('test')
}
}
}
}
and this is the error I am getting
Build file '/Users/Me/Documents/GitHub/Project-Tools/build.gradle' line: 13
A problem occurred evaluating root project 'Project-Tools'.
> Could not find method implementation() for arguments
[DefaultExternalModuleDependency{group='io.cucumber', name='cucumber-bom', version='7.1.0', configuration='default'}]
on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
I even tried commenting out each dependency one at a time so see if any work and none did
EDIT: Also I am on a Mac
I want to run QueryDsl Q-type generation in a separate task. I want that Q-type classes not to be created in a regular compileJava task, but the compiler sees the AnnotationProcessor in the classpath and creates them itself. I tried nulling the annotationProcessorPath, but then I couldn't restore its configuration in a separate task.
May be is it possible to exclude somehow dependencies of subtasks from the classpath?
compileJava {
options.annotationProcessorPath = null
}
tasks.register('generateQTypes'){
group 'build'
description 'Generate Q-Type classes with QueryDsl library'
dependencies {
annotationProcessor(
'com.querydsl:querydsl-apt:4.1.4:jpa',
'javax.persistence:javax.persistence-api:2.2',
'javax.annotation:javax.annotation-api:1.3.1')
}
compileJava {
options.annotationProcessorPath = classpath
}
}
What is the best way to solve this problem?Thanks in advance!
I made the following solution
class QTypeGenerator extends DefaultTask {
#TaskAction
addDependencies() {
project.dependencies {
annotationProcessor(
'com.querydsl:querydsl-apt:4.1.4:jpa',
'javax.persistence:javax.persistence-api:2.2',
'javax.annotation:javax.annotation-api:1.3.1')
}
}
}
tasks.register("generateQTypeClasses", QTypeGenerator) {
group('build')
description('Generate Q-type classes by queryDsl in build directory with default path')
finalizedBy('compileJava')
doLast {
println("Q-types classes will gererated and stored in ${compileJava.options.annotationProcessorGeneratedSourcesDirectory}")
}
}
We are trying to upgrade from Gradle 4.5 to 5.0. After upgrade, compileJava is failing because Mapstruct is not able to resolve values (getters not available obviously) used in #Mapping annotation. This was working fine in Gradle 4.5 .
The code is like this
#Mapper(componentModel = "spring")
public interface CAndACodeGenConverter extends BaseConverter<CGen, AGen> {
#Mapping(target = "owner", source = "owner.name")
#Mapping(target = "useCA", source = "defaultCA")
AGen convertToDto(CGen entity);
}
Our build.gradle is like this
mapstructVersion = "1.4.1.Final"
lombokVersion = "1.18.12"
lombokMapstructBindingVersion = "0.2.0"
compileOnly('org.projectlombok:lombok:1.18.12')
compile("org.mapstruct:mapstruct:${mapstructVersion}")
implementation "org.mapstruct:mapstruct:${mapstructVersion}", "org.projectlombok:lombok:${lombokVersion}"
annotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}", "org.projectlombok:lombok-mapstruct-binding:${lombokMapstructBindingVersion}"
The error we are getting is
error: No property named "owner.name" exists in source parameter(s). Did you mean "null"?
This was working fine in Gradle 4.5 .
Try to change dependencies order like below:
compileOnly "org.projectlombok:lombok:$lombokVersion"
compileOnly "org.mapstruct:mapstruct:${mapstructVersion}"
annotationProcessor "org.projectlombok:lombok-mapstruct-binding:0.2.0"
annotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}"
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
I've tested it just now and it works.
P.S. IDK why this order is required, got it from lombok-mapstruct-binding related article long time ago
I'm not sure if this is feasible, but wanted to get some comments/solution for the problem.
I'm creating a new dependency com.example:app-dep:1.0.1 will be used in com.example:app as compile dependency.
app-dep having a dependency io.undertow:undertow-core:2.0.1.Final which I don't want in com.example:app project, because I'm excluding the class file from com.example:app-dep related to undertow because the class requires on development time but not required in production.
When I add com.example:app-dep:1.0.1 in com.example:app I want to exclude io.undertow:undertow-core:2.0.1.Final.
But I want to control that from com.example:app-dep:1.0.1 maybe enable in future.
Some gradle I tried
TRY 1
app-dep - build.gradle
dependencies {
implementation('io.undertow:undertow-core:2.0.1.Final') {
transitive = true
}
implementation('io.undertow:undertow-servlet:2.0.1.Final') {
transitive = false
}
}
jar {
from sourceSets.main.allSource
excludes = ['com/example/ExampleServer**', 'public']
}
production-app build.gradle
using spring-boot-gradle-plugin bootRepackage
buildscript {
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:1.5.12.RELEASE"
}
}
dependencies {
compile 'com.example:app-dep:1.0.1'
}
OUTPUT: Still pulling and adding io.undertow:undertow-core:2.0.1.Final in production spring-boot jar
TRY 2
Using profiles
dependencies {
compile 'org.apache.commons:commons-lang3:3.4'
testCompile 'org.mockito:mockito-core:3.1.0'
testCompile 'org.powermock:powermock-module-junit4:1.6.6'
testCompile 'org.powermock:powermock-api-mockito:1.6.6'
if(isDev) {
implementation 'io.undertow:undertow-core:2.0.1.Final'
}
}
OUTPUT: Class inside app-dep throwing compilation error saying the following when I do ./gradlew build
Undertow server = Undertow.builder().addHttpListener(8081,
"localhost").setHandler(routingHandler).build();
^
symbol: variable Undertow
location: class ExampleServer
26 errors
What I can do but I don't want
In production-app build.gradle
dependencies {
compile('com.example:app-dep:1.0.1') {
exclude(module: 'com.example.app-dep')
}
}
Because I want to control that from app-dep
So I'm trying to get the Hibernate Validator Annotation Processor working in a Kotlin project, to check my JSR 380 annotations, with not much luck.
Unfortunately the documentation does not mention how to set it up with Gradle, and obviously with Kotlin we have to use "Kapt" to enable java annotation processors.
Hibernate Validator Annotation Processor Documentation: http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#validator-annotation-processor
Kapt Documentation: https://kotlinlang.org/docs/reference/kapt.html
I currently have the following config in my build.gradle file relating to the processor:
plugins {
id "org.jetbrains.kotlin.kapt" version "1.3.11"
...
}
apply plugin: 'org.jetbrains.kotlin.kapt'
...
dependencies {
implementation 'org.hibernate:hibernate-validator:6.0.14.Final'
implementation 'org.glassfish:javax.el:3.0.1-b09'
kapt 'org.hibernate:hibernate-validator-annotation-processor:6.0.14.Final'
...
}
kapt {
arguments {
arg('methodConstraintsSupported', 'false')
arg('verbose', 'true')
}
}
However whenever I build, I cannot see any output relating to the validator annotation processor and I do not get any build errors when deliberately applying an incorrect annotation (e.g. applying a #Min() annotation to a String field.
If someone could advise on how to get the processor working I would be eternally grateful! :)
I got this working in my build.gradle.kts like so (I'm using Kotlin Script as opposed to Groovy):
plugins {
...
id("org.jetbrains.kotlin.kapt") version "1.3.72"
...
}
dependencies {
...
kapt(
group = "org.hibernate.validator",
name = "hibernate-validator-annotation-processor",
version = "6.0.2.Final"
)
...
}
This correctly gave me errors when building, but only when I applied the validation annotation to the getter. When I was mistakenly applying it to just the constructor argument the validation did not work, and I saw no errors from the annotation processor. For example:
class Thing(
#get:AssertTrue
var name: String
)