I have a Micronaut-based project written in Java with several sub-projects. My project-setup is as follows:
|-> gradle
| |-> plugins
| |-> micronaut-plugins
| | |-> src/main/kotlin
| | | |-> my-app.gradle.kts
| | | |-> my-base.gradle.kts
| | |-> build.gradle.kts
| |-> settings.gradle.kts
|-> core
| |-> build.gradle.kts
|-> app1
| |-> build.gradle.kts
| |-> gradle.properties
|-> gradle.properties
|-> settings.gradle.kts
I simplified the structure to keep things as easy as possible, the main point here is, that I have two other sub-projects like app1. These three sub-projects are meant to be built as docker images. Each of them applies the plugin my-app. Also, they depend on the core sub-project, which is a library not meant to be shipped alone. This core-project again applies the plugin my-base. Furthermore, my-base is also applied by my-app.gradle. To sum it up:
Good news is, that I was successful in setting up Spotbugs, Checkstyle, PMD and Jacoco as well as the Micronaut dependency shared by all the sub-projects as planned. However, the sub-projects meant to be built as docker images also need to generate Java-code from jsonschema files. There is some common configuration, so I'd like to centralize that part as well, but I fail, because once apply the necessary plugin (jsonschema2pojo) in my-app.gradle.kts, Gradle fails to find the classes used by that plugin resulting in messages like:
Task :plugins:micronaut-plugins:compileKotlin FAILED e: Supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath: class org.jsonschema2pojo.gradle.JsonSchemaExtension, unresolved supertypes: org.jsonschema2pojo.GenerationConfig Adding -Xextended-compiler-checks argument might provide additional information.
I suppose that the dependency to the plugin is added too late within the build-process, so classes are not available in time.
gradle/plugins/micronaut-plugins/src/main/kotlin/my-app.gradle.kts (note the line I have commented out as it would cause trouble):
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.project
plugins {
id("my-base")
id("io.micronaut.application")
//id("org.jsonschema2pojo")
}
repositories {
mavenCentral()
}
dependencies {
implementation(project(":core"))
implementation("io.micronaut:micronaut-jackson-databind")
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.2")
testImplementation("org.testcontainers:junit-jupiter:1.17.6")
testImplementation("org.testcontainers:testcontainers:1.17.6")
testImplementation("org.testcontainers:kafka:1.17.6")
testImplementation("org.awaitility:awaitility:4.1.1")
testImplementation("io.micronaut:micronaut-http-client")
}
tasks.dockerfile {
baseImage.set("ghcr.io/graalvm/jdk:ol9-java17-22.3.0")
}
tasks.dockerBuild {
images.add("${project.name}:${project.version}")
}
gradle/plugins/micronaut-plugins/src/main/kotlin/my-base.gradle.kts:
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.repositories
plugins {
id("java")
id("com.github.spotbugs")
jacoco
checkstyle
pmd
}
repositories {
mavenCentral()
}
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
}
tasks.withType<JavaCompile>().configureEach {
options.encoding = "UTF-8"
}
dependencies {
annotationProcessor("io.micronaut:micronaut-http-validation")
implementation("io.micronaut:micronaut-jackson-databind")
implementation("io.micronaut.kafka:micronaut-kafka")
implementation("io.micronaut.kafka:micronaut-kafka-streams")
implementation("jakarta.annotation:jakarta.annotation-api")
implementation("io.micronaut:micronaut-validation")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.2")
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.9.2")
testImplementation("io.micronaut.test:micronaut-test-junit5")
testImplementation("org.mockito:mockito-core:5.1.1")
testImplementation("org.apache.kafka:kafka-streams-test-utils:3.4.0")
}
tasks.jacocoTestReport {
dependsOn(tasks.test) // tests are required to run before generating the report
reports {
xml.required.set(true)
html.required.set(true)
csv.required.set(false)
}
}
spotbugs {
ignoreFailures.set(true)
excludeFilter.set(file(layout.projectDirectory.toString() + "/../etc/codeanalyse/spotbugs-excludes.xml"))
layout.projectDirectory.toString()
}
checkstyle {
isIgnoreFailures = true
configFile = file(layout.projectDirectory.toString() + "/../etc/codeanalyse/checkstyle-config.xml")
setConfigProperties(
"checkstyle.suppressionfilter.config" to layout.projectDirectory.toString() + "/../etc/codeanalyse/checkstyle-supressions.xml"
)
}
pmd {
isIgnoreFailures = true
ruleSetFiles = files(layout.projectDirectory.toString() + "/../etc/codeanalyse/pmd-excludes.xml")
}
gradle/plugins/micronaut-plugins/build.gradle.kts:
plugins {
`kotlin-dsl`
}
repositories {
gradlePluginPortal()
}
dependencies {
implementation("io.micronaut.gradle:micronaut-gradle-plugin:3.7.0")
implementation("org.jsonschema2pojo:jsonschema2pojo-gradle-plugin:1.1.3")
implementation("com.github.spotbugs.snom:spotbugs-gradle-plugin:5.0.13")
}
gradle/plugins/settings.gradle.kts:
pluginManagement {
repositories.gradlePluginPortal()
}
dependencyResolutionManagement {
repositories.gradlePluginPortal()
}
include("micronaut-plugins")
core/build.gradle.kts:
plugins {
id("my-base")
id("io.micronaut.minimal.library") version "3.7.0"
}
app1/build.gradle.kts:
plugins {
id("my-app")
id("org.jsonschema2pojo") version "1.1.3"
id("io.micronaut.test-resources") version "3.7.0"
}
application {
mainClass.set("app1.Application")
}
// that's were I'd like to save a few lines:
jsonSchema2Pojo {
setSource(files("src/main/resources/jsonschema"))
targetPackage = "app1.outgoing"
targetDirectory = file(layout.buildDirectory.dir("generated-sources/jsonschema2pojo"))
setAnnotationStyle("jackson2")
formatTypeMapping = hashMapOf(
"uuid" to "java.lang.String"
)
}
app1/gradle.properties:
version=1.0.0
gradle.properties (Micronaut version not up-to-date as we have troubles migrating):
org.gradle.caching = true
micronautVersion=3.4.4
settings.gradle.kts:
pluginManagement {
repositories.gradlePluginPortal()
includeBuild("gradle/plugins")
}
dependencyResolutionManagement {
repositories.mavenCentral()
}
rootProject.name = "the-project"
include("core")
include("app1")
So, can someone please tell me where my mistake is? My best bet is the scope when giving the dependency, but no other scope I tried did the job. Please note that I am relatively new to Gradle, so please provide Kotlin-code if possible. I am on Gradle 7.6.0. Gradle 8.0 failed, probably because Micronaut dependencies are too old.
The error
Task :plugins:micronaut-plugins:compileKotlin FAILED
e: Supertypes of the following classes cannot be resolved.
Please make sure you have the required dependencies in the classpath:
class org.jsonschema2pojo.gradle.JsonSchemaExtension,
unresolved supertypes: org.jsonschema2pojo.GenerationConfig
Indicates that there's a problem in :plugins:micronaut-plugins
, so that's where to focus.
It also says that a 'supertype' is missing, org.jsonschema2pojo.GenerationConfig
.
Looking in the source code, we can see that the GenerationConfig
class is defined in the subproject named jsonschema2pojo-core
.
Looking at the build script for the org.jsonschema2pojo
Gradle plugin shows that it has a dependency on org.jsonschema2pojo:jsonschema2pojo-core
// jsonschema2pojo/jsonschema2pojo-gradle-plugin/build.gradle
dependencies {
implementation "org.jsonschema2pojo:jsonschema2pojo-core:${project.version}"
}
However, this dependency is defined using implementation
, not api
(see: Gradle Implementation vs API configuration), so any Gradle projects that depend on the jsonschema2pojo-gradle-plugin
project will not automatically depend on jsonschema2pojo-core
.
Aside: changing from
implementation
toapi
would be a good improvement in the jsonschema2pojo project
Therefore, when adding a dependency on the jsonschema2pojo plugin, you should also depend on jsonschema2pojo-core
.
dependencies {
implementation("org.jsonschema2pojo:jsonschema2pojo-gradle-plugin:1.1.3")
implementation("org.jsonschema2pojo:jsonschema2pojo-core:1.1.3")
}