I'm trying to create a multimodule springboot application on gradle, but I get an Unresolved reference error message during build. Gradle config for individual modules is below.
Unresolved reference error on import org.example.finalmultimodule.data.repositories.IPersonRepository during build:
Error:
Directory tree:
BuildTools > Gradle:
Main build.gradle:
plugins {
id("org.springframework.boot") version "2.3.3.RELEASE"
id("io.spring.dependency-management") version "1.0.10.RELEASE"
kotlin("plugin.spring") version "1.4.10"
kotlin("jvm") version "1.4.10"
}
group = "org.example"
version = "1.0-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11
repositories {
mavenCentral()
}
// Projekty
project(":data") {
apply(plugin = "org.springframework.boot")
apply(plugin = "io.spring.dependency-management")
}
project(":business") {
apply(plugin = "org.springframework.boot")
apply(plugin = "io.spring.dependency-management")
}
project(":api") {
apply(plugin = "org.springframework.boot")
apply(plugin = "io.spring.dependency-management")
}
dependencies {
// Moduly
implementation(project(":core"))
implementation(project(":data"))
implementation(project(":business"))
implementation(project(":api"))
implementation(kotlin("stdlib"))
}
allprojects {
tasks.withType<Test> {
useJUnitPlatform()
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "11"
}
}
}
Core build.gradle:
plugins {
kotlin("jvm")
}
group = "org.example"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
// Anotace pro #JsonProperty
implementation("com.fasterxml.jackson.core:jackson-annotations:2.11.2")
implementation(kotlin("stdlib"))
}
Data build.gradle:
plugins {
kotlin("jvm")
}
group = "org.example"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
// Moduly
implementation(project(":core"))
// Anotace #Component etc...
implementation("org.springframework:spring-context")
// Corutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
// Databaze
implementation("org.springframework.boot:spring-boot-starter-data-r2dbc")
implementation("io.r2dbc:r2dbc-mssql")
implementation(kotlin("stdlib"))
}
Business build.gradle:
plugins {
kotlin("jvm")
}
group = "org.example"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
implementation(project(":core"))
implementation(project(":data"))
// Kediatr variace na Mediatr
implementation("com.trendyol:kediatr-spring-starter:1.0.14")
implementation(kotlin("stdlib"))
}
Api (springboot) build.gradle:
plugins {
kotlin("jvm")
kotlin("plugin.spring")
}
group = "org.example"
version = "0.0.1-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
// Moduly
implementation(project(":core"))
implementation(project(":business"))
// Kediatr variace na Mediatr
implementation("com.trendyol:kediatr-spring-starter:1.0.14")
implementation("org.springframework.boot:spring-boot-starter-rsocket")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
}
testImplementation("io.projectreactor:reactor-test")
}
I had a very similar situation where my classes from other modules would not be resolved even though everything looked fine in IntelliJ.
I managed to solve it by explicitly adding
#ComponentScan(basePackages = ["my.package"])
to my spring boot application.
Also, set library projects up like this:
tasks.findByName("bootJar")?.apply {
enabled = false
}
tasks.findByName("jar")?.apply {
enabled = true
}
Related
I need to deploy a aplication in railway, but any time returno this error:
Caused by: java.lang.ClassNotFoundException: br.com.zezinho.helpdesk
Error: Could not find or load main class br.com.zezinho.helpdesk
My path is correct.
github: https://github.com/Luciannodev/helpdesk-back
plugins {
java
id("org.springframework.boot") version "2.7.8"
id("io.spring.dependency-management") version "1.1.0"
}
group = "br.com.zezinho"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11
val mainClassName = "HelpDeskApplication.java"
configurations {
compileOnly {
extendsFrom(configurations.annotationProcessor.get())
}
}
repositories {
mavenCentral()
maven { url = uri("https://repo.spring.io/milestone") }
maven { url = uri("https://repo.spring.io/snapshot") }
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("io.jsonwebtoken:jjwt-api:0.11.5")
implementation("io.jsonwebtoken:jjwt-impl:0.11.5")
implementation("io.jsonwebtoken:jjwt-jackson:0.11.5")
implementation("mysql:mysql-connector-java:8.0.28")
implementation("com.h2database:h2:1.4.200")
testImplementation("org.springframework.boot:spring-boot-starter-test")
annotationProcessor("org.projectlombok:lombok")
}
tasks.withType<Test> {
useJUnitPlatform()
}
tasks.jar {
manifest.attributes["Main-Class"] = "br.com.zezinho.helpdesk"
manifest.attributes["Class-Path"] = configurations
.runtimeClasspath
.get()
.joinToString(separator = " ") { file ->
"libs/${file.name}"
}
}
I have a multi-module Gradle project which is structured like so:
root
|
|_____main
|
|_____other
This is how the build.gradle.ktss files are structured:
Root:
import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.8.0" apply false
kotlin("plugin.spring") version "1.8.0" apply false
kotlin("plugin.lombok") version "1.8.0" apply false
id("org.springframework.boot") version "2.7.2" apply false
id("io.spring.dependency-management") version "1.0.12.RELEASE" apply false
}
subprojects {
apply {
plugin("org.jetbrains.kotlin.jvm")
plugin("org.jetbrains.kotlin.plugin.spring")
plugin("org.jetbrains.kotlin.plugin.lombok")
plugin("org.springframework.boot")
plugin("io.spring.dependency-management")
}
configurations {
configurations["compileOnly"].extendsFrom(configurations["annotationProcessor"])
all {
exclude(group = "org.springframework.boot", module = "spring-boot-starter-logging")
}
}
repositories {
mavenCentral()
}
val implementation by configurations
val testImplementation by configurations
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
implementation("org.springframework.boot:spring-boot-starter")
//other dependencies...
}
configure<DependencyManagementExtension> {
imports {
mavenBom("org.springframework.shell:spring-shell-dependencies:2.1.0")
}
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict", "-Xjvm-default=all")
jvmTarget = "17"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
}
Main:
import org.springframework.boot.gradle.tasks.bundling.BootJar
plugins {
`java-test-fixtures`
application
}
group = "my.group"
version = "0.2.0"
java.sourceCompatibility = JavaVersion.VERSION_17
application {
mainClass.set("my.group.MainKt")
}
tasks.withType<BootJar> {
manifest {
attributes["Main-Class"] = "org.springframework.boot.loader.PropertiesLauncher"
}
}
task<JavaExec>("runBootJar") {
val bootJar: BootJar by tasks
classpath = files(bootJar)
debug = true
}
springBoot {
buildInfo()
}
extra["springShellVersion"] = "2.1.0"
dependencies {
implementation("org.springframework.boot:spring-boot-loader")
api("org.springframework.boot:spring-boot-starter-web")
api("org.springframework.boot:spring-boot-starter-batch")
api("org.springframework.boot:spring-boot-starter-data-mongodb")
api("org.springframework.boot:spring-boot-starter-data-jpa")
api("org.springframework.boot:spring-boot-starter-integration")
api("org.springframework.boot:spring-boot-starter-thymeleaf")
api("org.springframework.boot:spring-boot-starter-log4j2")
api("org.springframework.integration:spring-integration-mongodb")
api("org.springframework.boot:spring-boot-starter-mail")
api("org.springframework.shell:spring-shell-starter")
//other dependencies...
}
Other:
plugins {
`java-library`
}
group = "my.group"
version = "0.2.0"
java.sourceCompatibility = JavaVersion.VERSION_17
dependencies {
compileOnly(project(":main"))
implementation("org.springframework.boot:spring-boot-starter-data-mongodb")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
//other dependencies...
}
As you can see, Main has a dependency towards org.springframework.shell:spring-shell-starter, which in turns makes this piece inside the Root build.gradle.kts mandatory:
configure<DependencyManagementExtension> {
imports {
mavenBom("org.springframework.shell:spring-shell-dependencies:2.1.0")
}
}
If I try to move this part inside the Main script, the following error pops up when I try to compile Other:
Execution failed for task ':other:compileKotlin'.
> Could not resolve all files for configuration ':other:compileClasspath'.
> Could not find org.springframework.shell:spring-shell-starter:.
Required by:
project :other> project :main
Also, if I run Gradle with the stacktrace enabled, there is also this error:
2: Task failed with an exception.
-----------
* What went wrong:
java.lang.StackOverflowError (no error message)
This made me think there could be some kind of cyclic dependency, but I couldn't find any.
I'd like to move the mavenBom part inside Main because Spring Shell is only used there, and not in every submodule, but in the end I cannot get it working.
What am I missing?
I'm trying to implement a simple spring boot web mvc application, but requirements are:
Generate code from api.yaml (openapi 3.0)
Generate swagger's code ( I guess it's just a couple of annotations but nevertheless)
But generated code doesn't compile due to generated:
import springfox.documentation.spring.web.paths.RelativePathProvider;
in org/openapitools/configuration/OpenAPIDocumentationConfig.java
my searching results summarized:
it's due to old springfox version, migrate to 3.0.0. The RelativePathProvider was replaced by DefaultPathProvider
but I'd already have it originally. And it'seems the generator doesn't know it need to generate DefaultPathProvider instead of old RelativePathProvider
My build.gradle.kts is:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "2.5.6"
id("org.openapi.generator").version("5.3.0")
id("io.spring.dependency-management") version "1.0.11.RELEASE"
kotlin("jvm") version "1.5.31"
kotlin("plugin.spring") version "1.5.31"
kotlin("plugin.jpa") version "1.5.31"
}
group = "com.hometask"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11
configurations {
compileOnly {
extendsFrom(configurations.annotationProcessor.get())
}
}
repositories {
mavenCentral()
}
dependencies {
implementation("javax.validation:validation-api:2.0.1.Final")
implementation("org.flywaydb:flyway-core")
api("io.springfox:springfox-swagger2:3.0.0")
api("io.springfox:springfox-swagger-ui:3.0.0")
api("org.openapitools:jackson-databind-nullable:0.2.1")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
compileOnly("org.projectlombok:lombok")
runtimeOnly("com.h2database:h2")
annotationProcessor("org.projectlombok:lombok")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
val spec = "$rootDir/src/main/resources/openapi/api.yml"
val generatedSourcesDir = "$buildDir/generated/openapi"
openApiGenerate {
generatorName.set("spring")
inputSpec.set(spec)
outputDir.set(generatedSourcesDir)
apiPackage.set("org.openapi.example.api")
invokerPackage.set("org.openapi.example.invoker")
modelPackage.set("org.openapi.example.model")
configOptions.set(mapOf(
"dateLibrary" to "java8"
))
}
sourceSets {
getByName("main") {
java {
srcDir("$generatedSourcesDir/src/main/java")
}
}
}
tasks {
val openApiGenerate by getting
val compileJava by getting {
dependsOn(openApiGenerate)
}
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "11"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
I have an example SpringBoot app in Kotlin and WebFlux. I divided whole application into modules (as I'm used to from asp.net).
Modules:
core (models, DTO, helpers, etc...) referenced everywhere
data (repositories, tables...) referenced only in business
business (services, handlers...) referenced in api
api actual SpringBoot application
My problem now is how to properly work with ReactiveCrudRepository<> and repositories in general. I have config class in data module to enable R2dbcRepositories.
#Configuration
#EnableR2dbcRepositories("me.janam.data")
open class RepositoriesConfiguration {
}
Now if I create table and repository
interface IPersonRepository: ReactiveCrudRepository<PersonTable, Long> {
#Query("SELECT * FROM person.person limit 1")
fun getOne(): Mono<PersonTable>
}
and try to use it in business module I'm getting an error
Cannot access 'org.springframework.data.repository.reactive.ReactiveCrudRepository' which is a supertype of 'me.janam.data.features.person.repositories.IPersonRepository'. Check your module classpath for missing or conflicting dependencies
Of course if I add
implementation("org.springframework.data:spring-data-commons:2.4.6")
into my business module everything works fine. But somehow this feels strange to me. Is this the right way how to do this?
Also not part of my main question but here is complete config and I like to hear some opinion on it as i'm mainly asp.net dev. Thx.
root - settings.gradle.kts:
rootProject.name = "springboot-example"
include(":api")
include(":business")
include(":data")
include(":core")
root - gradle.properties:
kotlin.code.style=official
kotlin_version=1.4.31
kotlinx_coroutines_reactor_version=1.4.3
r2dbc_postgresql_version=0.8.7.RELEASE
postgresql_version=42.2.19
spring_context_version=5.3.5
root - build.gradle.kts:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.4.31"
id("io.spring.dependency-management") version "1.0.11.RELEASE"
}
subprojects {
apply(plugin = "io.spring.dependency-management" )
dependencyManagement {
}
}
group = "me.janam"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
//implementation("org.springframework:spring-context:5.3.5")
testImplementation(kotlin("test-junit5"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
}
tasks.test {
useJUnitPlatform()
}
tasks.withType<KotlinCompile>() {
kotlinOptions.jvmTarget = "13"
}
core - build.gradle.kts:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm")
}
group = "me.janam"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
testImplementation(kotlin("test-junit5"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
}
tasks.test {
useJUnitPlatform()
}
tasks.withType<KotlinCompile>() {
kotlinOptions.jvmTarget = "13"
}
data - build.gradle.kts:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
val kotlinx_coroutines_reactor_version: String by project
val r2dbc_postgresql_version: String by project
val postgresql_version: String by project
val spring_context_version: String by project
plugins {
kotlin("jvm")
}
group = "me.janam"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
implementation(project(":core"))
implementation("org.springframework:spring-context:$spring_context_version")
implementation("org.springframework.boot:spring-boot-starter-data-r2dbc:2.4.4")
runtimeOnly("io.r2dbc:r2dbc-postgresql:$r2dbc_postgresql_version")
runtimeOnly("org.postgresql:postgresql:$postgresql_version")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$kotlinx_coroutines_reactor_version")
testImplementation(kotlin("test-junit5"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
}
tasks.test {
useJUnitPlatform()
}
tasks.withType<KotlinCompile>() {
kotlinOptions.jvmTarget = "13"
}
business - build.gradle.kts:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
val kotlinx_coroutines_reactor_version: String by project
val spring_context_version: String by project
plugins {
kotlin("jvm")
}
group = "me.janam"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
implementation(project(":core"))
implementation(project(":data"))
implementation("org.springframework:spring-context:$spring_context_version")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$kotlinx_coroutines_reactor_version")
implementation("org.springframework.data:spring-data-commons:2.4.6") //TODO
testImplementation(kotlin("test-junit5"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
}
tasks.test {
useJUnitPlatform()
}
tasks.withType<KotlinCompile>() {
kotlinOptions.jvmTarget = "13"
}
api - build.gradle.kts:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "2.4.4"
// Přesunuto do rootu
id("io.spring.dependency-management")
kotlin("jvm")
kotlin("plugin.spring") version "1.4.31"
}
group = "me.janam"
version = "1.0-SNAPSHOT"
//java.sourceCompatibility = JavaVersion.VERSION_13
repositories {
mavenCentral()
}
dependencies {
implementation(project(":core"))
implementation(project(":business"))
//implementation("org.springframework.boot:spring-boot-starter-data-r2dbc")
implementation("org.springframework.boot:spring-boot-starter-rsocket")
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
//runtimeOnly("io.r2dbc:r2dbc-postgresql")
//runtimeOnly("org.postgresql:postgresql")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("io.projectreactor:reactor-test")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "13"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
Adding the same set of dependencies to each subproject may feel odd, but it's totally fine to do. In order to use a given dependency in a given subproject, you'll have to specify it as a dependency for that subproject.
There are, however, neater ways to accomplish this than actually copy-pasting the import statement to each build file. I would suggest specifying a subprojects section in your root build.gradle.kts and putting shared & common dependencies there:
subprojects {
dependencies {
// Put items here that are used in all/most subprojects:
implementation("org.springframework:spring-context:$spring_context_version")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$kotlinx_coroutines_reactor_version")
// You can put this import here or just keep it in the build files
// for subprojects where it will actually get used
implementation("org.springframework.data:spring-data-commons:2.4.6")
testImplementation(kotlin("test-junit5"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
}
}
You'll still need to specify in each sub-build file what other subprojects each depends on with implementation(project(":core")) type statements, but the above dependencies block takes care of making the specified libraries accessible in all subprojects.
I'm creating gradle multi project for kotlin programming.
When I create dependencies under subprojects in main project build.gradle.kts I'm getting error Configuration with name 'implementation' not found.
Below is my configuration -
plugins {
kotlin("jvm") version "1.3.61" apply false
}
subprojects {
dependencies {
val implementation by configurations
implementation(kotlin("stdlib-jdk8"))
}
}
Once I move the plugins and dependencies into subproject build.gradle.kts then it is working fine.
How can I make dependencies under subprojects work fine?
Code is on github.
With Kotlin dsl, you can add your dependencies as long as you use either apply(plugin = "org.jetbrains.kotlin.jvm") or apply(plugin = "java").
Those needs to be where you put your dependencies { .. }, usually inside a subprojects { .. }.
So here would be a simple build.gradle.kts that would propagate the kotlin dependency in all its subprojects.
plugins {
kotlin("jvm") version "1.3.50"
}
repositories {
mavenCentral()
}
subprojects {
apply(plugin = "org.jetbrains.kotlin.jvm")
dependencies {
implementation(kotlin("stdlib-jdk8"))
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "11"
}
}
}
(You would still need to have the kotlin plugin, however no need to specify the version in the other subproject once defined at the root)
Adding the below configuration worked for me
buildscript {
repositories {
maven {
url = uri("https://plugins.gradle.org/m2/")
}
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61")
}
}
subprojects {
apply(plugin = "java")
apply(plugin = "org.jetbrains.kotlin.jvm")
dependencies {
val implementation by configurations
implementation(kotlin("stdlib-jdk8"))
}
}
In your root build.gradle.kts you can also exclude projects if you want:
subprojects {
if (!project.name.contains("ios")) {
apply("${rootDir}/ktlint.gradle.kts")
apply(plugin = "org.jetbrains.kotlinx.kover")
apply(plugin = "com.diffplug.spotless")
}
}