Test function in Kotlin cannot find function in main module - gradle

I have a standard (multi-)project set-up in Kotlin using gradle, where I have a /src/main/kotlin/ and a /src/test/kotlin/.
I have a function in my main module that I would like to test, but when i create a test function in the same named directory in the test module, the function I wish to test isn't found and is not callable.
For reference, the root build.gradle
ext.kotlin_version='1.3.61'
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
apply plugin: 'idea'
apply plugin: 'java'
apply plugin: 'kotlin'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
jcenter()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compileOnly 'org.projectlombok:lombok:1.18.8'
annotationProcessor 'org.projectlombok:lombok:1.18.8'
implementation "org.nd4j:nd4j-native-platform:1.0.0-beta5"
implementation "org.apache.commons:commons-lang3:3.9"
implementation "org.apache.commons:commons-math4"
implementation "io.ktor:ktor-server-core:1.2.6"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testImplementation "org.jetbrains.kotlin:kotlin-test-junit5:$kotlin_version"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
sourceSets {
main.java.srcDirs += 'src/main/kotlin/'
test.java.srcDirs += 'src/test/kotlin/'
}
compileKotlin {
kotlinOptions {
jvmTarget = '1.8'
apiVersion = '1.3'
languageVersion = '1.3'
}
}
}
and the sub-project build.gradle:
plugins {
id 'java'
id 'org.jetbrains.kotlin.jvm'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin/'
test.java.srcDirs += 'src/test/kotlin/'
}
repositories {
mavenCentral()
}
sourceCompatibility = 1.8
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation "org.nd4j:nd4j-native-platform"
implementation "org.apache.commons:commons-lang3"
implementation "org.apache.commons:commons-math4"
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
Any help would be greatly appreciated

Related

Kotlin Spring Boot. Controller class #Validated cause #Autowired of service fails

I use #Validated on HomeController,then #Autowired of UserService fails. I get Exception below
kotlin.UninitializedPropertyAccessException: lateinit property service has not been initialized
at com.example.demo.web.HomeController.getService(HomeController.kt:16) ~[main/:na]
at com.example.demo.web.HomeController.index(HomeController.kt:20) ~[main/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke...
Spring Boot 2.4.5
Kotlin 1.5.0
Gradle 6.8.3-bin
This is my code
HoneController.kt
#Validated
#RestController
open class HomeController {
#Autowired
lateinit var service: UserSercie
#RequestMapping("/")
fun index(#NotNull(message = "name can not be null") name: String): String {
return "hello " + name + service.getData()
}
}
UserService.kt
#Service
class UserSercie {
fun getData(): String {
return " message from service"
}
}
build.gralde
plugins {
id 'org.springframework.boot' version '2.4.5'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
id 'org.jetbrains.kotlin.jvm' version '1.5.0'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
}
test {
useJUnitPlatform()
}
compileKotlin {
kotlinOptions {
jvmTarget = "11"
}
}
compileTestKotlin {
kotlinOptions {
jvmTarget = "11"
}
}
I find kotlin-spring plugin:https://kotlinlang.org/docs/all-open-plugin.html#spring-support
I use the plugin and remove open in HomeController.
then it works.
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:$springbootVersion")
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version"
}
}
subprojects {
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'kotlin'
apply plugin: "kotlin-spring"
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
//other settings
}

How to configure 'mainClassName' for Spring Boot Application in a Kotlin Gradle multi-module project?

I have a Gradle multi-module project in Kotlin using Spring Boot in some of the modules.
I use the 'org.springframework.boot' and 'io.spring.dependency-management' plugin in the project's root build.gradle which besides other things provide the bootRun task.
AFAIK I need to configure the mainClassName (or entry point) like this:
springBoot {
mainClassName = 'de.shinythings.hexagon.HexagonApplicationKt'
}
While this works in the subproject that contains the actual Spring Boot application it does not work in the root project.
I want to be able to configure it in the root project because I want to be able to run my project with ./gradlew bootRun instead of ./gradlew configuration:bootRun.
Other tasks like ./gradlew build or ./gradlew test work fine.
Here is the root project's build.gradle (link):
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.4.10'
id 'org.springframework.boot' version '2.3.4.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
implementation project(':configuration')
}
springBoot {
mainClassName = 'de.shinythings.hexagon.HexagonApplicationKt'
}
subprojects {
group = 'de.shinythings.hexagon'
version = '0.0.1-SNAPSHOT'
repositories {
mavenCentral()
}
ext {
mockKVersion = '1.10.2'
}
apply plugin: 'org.jetbrains.kotlin.jvm'
apply plugin: 'io.spring.dependency-management'
dependencies {
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
}
dependencyManagement {
imports {
mavenBom('org.springframework.boot:spring-boot-dependencies:2.3.4.RELEASE')
}
}
compileKotlin {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
freeCompilerArgs = ["-Xjsr305=strict"]
allWarningsAsErrors = true
}
}
compileTestKotlin {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
freeCompilerArgs = ["-Xjsr305=strict"]
allWarningsAsErrors = true
}
}
}
In the subproject/module this setting works (link) :
plugins {
id 'org.springframework.boot'
id 'org.jetbrains.kotlin.plugin.spring' version '1.4.10'
}
dependencies {
implementation project(':common')
implementation project(':application')
implementation project(':adapters:persistence')
implementation project(':adapters:web')
implementation 'org.springframework.boot:spring-boot-starter'
implementation('com.h2database:h2')
}
springBoot {
mainClassName = 'de.shinythings.hexagon.HexagonApplicationKt'
}
What do I have to do to configure the mainClassName is the root's project build.gradle?

Importing coroutines-common causes error "Cannot inline bytecode build with JVM target 1.8 into...". Even with explicitly specified jvmTarget

I'm trying to import kotlin coroutines in my spring project.
I have the following lines in my build.gradle file:
compileKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'
}
}
compileTestKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'
}
}
But anyways when I import coroutines-common using implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-common:1.1.1' I get the error: Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option
If I remove implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-common:1.1.1' the project builds fine.
How can I import kotlin coroutines?
P.S. I tried
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
apiVersion = "1.3"
languageVersion = "1.3"
jvmTarget = "1.8"
}
}
Full build.gradle file:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.5.RELEASE")
classpath("org.jetbrains.kotlin:kotlin-noarg:1.3.20")
classpath("org.jetbrains.kotlin:kotlin-allopen:1.3.20")
}
}
plugins {
id 'org.springframework.boot' version '2.1.3.RELEASE'
id 'org.jetbrains.kotlin.jvm' version '1.3.20'
id 'org.jetbrains.kotlin.plugin.spring' version '1.3.20'
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'kotlin-jpa'
allOpen {
annotation("javax.persistence.Entity")
annotation("javax.persistence.MappedSuperclass")
annotation("javax.persistence.Embeddable")
}
group = 'com.liberaid'
version = '0.0.1'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
maven { url "https://dl.bintray.com/rookies/maven" }
}
dependencies {
def withoutX = {
exclude group: 'org.slf4j', module: 'slf4j-log4j12'
exclude group: 'org.slf4j', module: 'slf4j-jdk14'
exclude group: 'ch.qos.logback', module: 'logback-classic'
}
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
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'
implementation 'commons-net:commons-net:3.6'
implementation 'net.lingala.zip4j:zip4j:1.3.2'
implementation 'org.apache.pdfbox:pdfbox:2.0.1'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'mysql:mysql-connector-java:+'
/* Json parsers */
implementation 'org.json:json:+'
implementation 'com.google.code.gson:gson:+'
/* HTML parser */
implementation 'org.jsoup:jsoup:1.11.3'
/* GROBID - citation parser */
implementation 'org.grobid:grobid-core:0.5.4', withoutX
implementation 'org.grobid:grobid-trainer:0.5.4', withoutX
/* Kotlin coroutines */
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-common:1.1.1'
runtimeOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
compileKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'
}
}
compileTestKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'
}
}
The dependency org.jetbrains.kotlinx:kotlinx-coroutines-common:1.1.1 is wrong.
Use org.jetbrains.kotlinx:kotlinx-coroutines-core-common:1.1.1 instead.

spring integration RedisLockRegistry with spring-context

We have decided to use RedisLockRegistry by adding spring-integration to my project developed with Spring boot 1.5.7.
But when we add spring-integration-starter and spring-integration-redis to the project, quartz gives an error.
If I change the spring-context with spring-context-support or if I add spring-context-support, it is not an error.
Why should I add spring-context-support instead of spring-context or change it either?
gradle
buildscript {
ext {
springBootVersion = '1.5.7.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
allprojects {
repositories {
mavenCentral()
mavenLocal()
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: "io.spring.dependency-management"
apply plugin: 'maven'
apply plugin: 'idea'
sourceCompatibility = 1.8
idea {
module {
sourceDirs += file('build/classes/main/generated')
generatedSourceDirs += file('build/classes/main/generated')
}
}
dependencies {
compileOnly 'org.projectlombok:lombok'
testCompile 'org.springframework.boot:spring-boot-starter-test'
testCompile 'com.h2database:h2'
testCompile 'org.springframework.security:spring-security-test'
}
}
group = 'com.example.redislock'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
compileJava.dependsOn(processResources)
dependencies {
compile 'org.springframework.boot:spring-boot-starter-aop'
compile 'org.springframework.boot:spring-boot-starter-web'
compile 'org.springframework.boot:spring-boot-starter-integration'
compile 'org.quartz-scheduler:quartz:2.3.0'
compile 'org.springframework:spring-core'
//compile 'org.springframework:spring-context'
compile 'org.springframework:spring-context-support'
compile 'org.springframework.integration:spring-integration-redis'
compile 'org.hibernate:hibernate-java8'
compile 'io.springfox:springfox-swagger2:2.6.1'
compile 'io.springfox:springfox-swagger-ui:2.6.1'
compile 'org.springframework.boot:spring-boot-starter-actuator'
compile 'org.flywaydb:flyway-core:4.2.0'
compileOnly 'org.springframework.boot:spring-boot-configuration-processor'
runtime 'org.postgresql:postgresql:42.2.1'
}
This is error giving class:
package com.example.redislock.DemoRedisLockGradle.scheduler;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
#Configuration
public class ExampleScheduler {
#Bean(name = "asdTrigger")
public CronTriggerFactoryBean triggerFactoryBean(#Qualifier("asdJobFactory") JobDetailFactoryBean jobFactory) {
return createTriggerFactoryBean(jobFactory.getObject());
}
#Bean(name = "asdJobFactory")
public JobDetailFactoryBean asd() {
return createJobDetailFactoryBean(ExampleJob.class);
}
CronTriggerFactoryBean createTriggerFactoryBean(JobDetail jobDetail) {
CronTriggerFactoryBean ctFactory = new CronTriggerFactoryBean();
ctFactory.setName("Example Factory");
ctFactory.setCronExpression("0 0/1 * * * ?");
ctFactory.setJobDetail(jobDetail);
return ctFactory;
}
JobDetailFactoryBean createJobDetailFactoryBean(Class<? extends Job> jobClass) {
JobDetailFactoryBean factory = new JobDetailFactoryBean();
factory.setJobClass(jobClass);
return factory;
}
}
It cant find quartz.CronTriggerFactoryBean and quartz.JobDetailFactoryBean
Thanks in advance
I found the solution. If ı exclude spring-data-redis on spring-integration-redis it's not need adding spring-context-support
compile('org.springframework.boot:spring-boot-starter-integration')
compile('org.springframework.integration:spring-integration-redis') {
exclude group: 'org.springframework.data', module: 'spring-data-redis'
}

Ktor startup example errors

I'm very new to Kotlin and Ktor and Gradle, wanted to try Ktor, so gone through the steps explained here, and ended up with this code, and structure shown in the screenshot:
As seen there are lots of error, how to fix them?
package blog
import org.jetbrains.ktor.netty.*
import org.jetbrains.ktor.routing.*
import org.jetbrains.ktor.application.*
import org.jetbrains.ktor.host.*
import org.jetbrains.ktor.http.*
import org.jetbrains.ktor.response.*
fun main(args: Array<String>) {
embeddedServer(Netty, 8080) {
routing {
get("/") {
call.respondText("My Example Blog", ContentType.Text.Html)
}
}
}.start(wait = true)
}
The build.gradle file is auto generated as:
group 'Example'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.1.4-3'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'java'
apply plugin: 'kotlin'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
You have incomplete build.gradle script (missing dependencies) - see here for details. Here's the good one:
group 'Example'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.1.4-3'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'java'
apply plugin: 'kotlin'
sourceCompatibility = 1.8
ext.ktor_version = '0.4.0'
repositories {
mavenCentral()
maven { url "http://dl.bintray.com/kotlin/ktor" }
maven { url "https://dl.bintray.com/kotlin/kotlinx" }
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
compile "org.jetbrains.ktor:ktor-core:$ktor_version"
compile "org.jetbrains.ktor:ktor-netty:$ktor_version"
compile "ch.qos.logback:logback-classic:1.2.1"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
kotlin {
experimental {
coroutines "enable"
}
}
I would recommend using the IntelliJ Ktor plugin to bootstrap your app. The ./gradlew run script runs right out of the box with this configuration without you needing to fiddle with the Gradle configuration. It's the easiest way to get started.
Here is an example Ktor app that uses the configuration: https://gitlab.com/tinacious/ktor-example
If you'd like to run your application from IntelliJ, check out this answer for the run configuration I use: https://stackoverflow.com/a/65350680/1870884

Resources