How to configure spock in spring boot with gradle 6+ and java 11+ - spring-boot

I want to use spock in my spring-boot project (using groovy, not java). I have some projects with spock already working in java 8 and lower versions of gradle but I can't find documentation about the newest versions.
This is my OLD build.gradle
buildscript {
ext {
springBootVersion = '2.1.0.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'groovy'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.test'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
implementation('org.springframework.boot:spring-boot-starter-data-mongodb')
implementation('org.springframework.boot:spring-boot-starter-web')
implementation('org.codehaus.groovy:groovy')
testImplementation('org.springframework.boot:spring-boot-starter-test')
testCompile(
'junit:junit:4.12',
'org.codehaus.groovy:groovy-all:2.4.4',
'org.spockframework:spock-core:1.2-groovy-2.4',
'cglib:cglib:2.2',
'org.spockframework:spock-spring:1.2-groovy-2.4',
)
}
this works and I can create spock tests but when I create a project with java 11 and gradle 6.4, nothing works anymore (the gradle syntax is way different and the spock libraries don't work anymore),
this is my CURRENT (and failing) build.gradle:
plugins {
id 'org.springframework.boot' version '2.3.2.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'groovy'
}
group = 'com.test'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.codehaus.groovy:groovy'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'org.postgresql:postgresql'
testImplementation("org.spockframework:spock-core") {
exclude group: "org.codehaus.groovy", module: "groovy-all"
}
testImplementation group: 'org.spockframework', name: 'spock-spring', version: '2.0-M3-groovy-3.0'
testImplementation(enforcedPlatform("org.spockframework:spock-bom:2.0-M1-groovy-2.5"))
}
test {
useJUnitPlatform()
}
With this, nothing works but the gradle build doesn't found the spock-spring libraries.
How can I apply the spock libraries to spring boot with the newest versions of java and gradle?

Think you got into a muddle of Groovy Versions with the dependencies:
I tested with this build:
plugins {
id 'org.springframework.boot' version '2.3.2.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'groovy'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
jcenter()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.codehaus.groovy:groovy:3.0.5'
testImplementation('org.spockframework:spock-core:2.0-M3-groovy-3.0')
testImplementation('org.spockframework:spock-spring:2.0-M3-groovy-3.0')
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
test {
useJUnitPlatform()
}
And this test ran and passed:
package test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.context.ApplicationContext
import spock.lang.Specification
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = Application)
class ContextSpec extends Specification {
#Autowired
ApplicationContext context
def "context is as expected"() {
expect:
context
context.getBean("echoService")
}
}
(Obviously, I had an echoService in my context)
For completeness, here's the service:
package test
import org.springframework.stereotype.Service
#Service("echoService")
class EchoService {
String echo(String value) {
value?.reverse()
}
}
The controller:
package test
import org.springframework.http.MediaType
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.bind.annotation.RestController
#RestController
class EchoController {
final EchoService echoService
EchoController(EchoService echoService) {
this.echoService = echoService
}
#RequestMapping(
value = "/echo/{message}",
method = RequestMethod.GET,
produces = MediaType.TEXT_PLAIN_VALUE
)
String doEcho(#PathVariable String message) {
return echoService.echo(message)
}
}
And the application class:
package test
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
#SpringBootApplication
class Application {
static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
And proof 😉
➜ curl localhost:8080/echo/hello
olleh%

Related

org.springframework.cloud cannot be resolved when import EnableDiscoveryClient for registering service with Eureka

In my spring-boot project, I try to register my project as eureka discovery client. This is my simple code:
package com.my.simpleService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
// Compiler error: org.springframework.cloud cannot be resolved
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
#EnableDiscoveryClient
#SpringBootApplication
public class MyServiceApplication {
public static void main(String[] args) {
SpringApplication.run(MyServiceApplication.class, args);
}
}
I get compiler error: import org.springframework.cloud cannot be resolved.
Following is my gradle.build file:
plugins {
id 'org.springframework.boot' version '2.5.3'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
apply plugin: 'io.spring.dependency-management'
group = 'com.my.simpleService'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' }
}
ext {
set('springCloudVersion', '2020.0.0')
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation group: 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client:3.0.3'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
test {
useJUnitPlatform()
}
Why I get that compiler error? What am I missing?
You need to add the spring-cloud-commons, e.g. update your dependencies to the following:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-commons'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

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
}

Why cant i import #RestController spring boot

enter image description herei'm just trying to set up a simple spring boot application that has rest controller. But cant import Rest Controller. Here is my main method
package com.test.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RestController;
#RestController
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
And here is my build.gradle. the script collects all the jars on the classpath and builds a single jar.
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.2.1.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
bootJar {
baseName = 'gs-spring-boot-docker'
version = '0.1.0'
}
repositories {
mavenCentral()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-rest'
implementation 'org.springframework.boot:spring-boot-starter-web'
compile("org.springframework.boot:spring-boot-starter-web")
testCompile("org.springframework.boot:spring-boot-starter-test")
}
Any Ideas? Thanks
You are missing import for #RequestMapping("/").
import org.springframework.web.bind.annotation.RequestMapping;
I invalidated and restarted the caches which worked!

Gradle, Kotlin, Multi Module Project: Getting build errors while compiling this project

I am getting the following error on running gradle build command on root folder.
E:\Code\mdh>gradle build
> Task :multidemo:compileKotlin FAILED
e: E:\Code\mdh\multidemo\src\main\kotlin\com\simbalarry\multidemo\SampleController.kt: (3, 23): Unresolved reference: somelib
e: E:\Code\mdh\multidemo\src\main\kotlin\com\simbalarry\multidemo\SampleController.kt: (18, 12): Unresolved reference: Tester
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':multidemo:compileKotlin'.
> Compilation error. See log for more details
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 5s
4 actionable tasks: 1 executed, 3 up-to-date
Below is my project structure and multidemo project is using some functionalities of somelib. Also, I have deliberetly kept somelib as spring boot project as I will be adding more spring boot related functionalities later.
Root Project
|
|---settings.gradle
|---somelib
| |
| |---build.gradle
| |---settings.gradle
| |---src/main/kotlin/somepackage/Tester.kt
| |---src/main/kotlin/somepackage/SomeLibApplication.kt
|
|---multidemo
| |---build.gradle
| |---settings.gradle
| |---src/main/kotlin/somepackage/SampleController.kt
| |---src/main/kotlin/somepackage/MultidemoApplication.kt
Below are the contents of every file
Root/settings.gradle
include ':somelib', ':multidemo'
somelib/build.gradle
plugins {
id 'org.springframework.boot' version '2.1.3.RELEASE'
id 'org.jetbrains.kotlin.jvm' version '1.3.21'
id 'org.jetbrains.kotlin.plugin.spring' version '1.3.21'
}
apply plugin: 'io.spring.dependency-management'
group = 'com.simbalarry'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
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'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
compileKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'
}
}
compileTestKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'
}
}
somelib/settings.gradle
pluginManagement {
repositories {
gradlePluginPortal()
}
}
rootProject.name = 'somelib'
somelib/src/main/kotlin/somepackage/Tester.kt
package com.simbalarry.somelib
/*
* Created on : 17-03-2019
* Author : Nayan Kurude
*/
object Tester {
fun getOutputText(): String {
return "Sample Text"
}
}
somelib/src/main/kotlin/somepackage/SomelibApplication.kt
package com.simbalarry.somelib
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
#SpringBootApplication
class SomelibApplication
fun main(args: Array<String>) {
runApplication<SomelibApplication>(*args)
}
multidemo/build.gradle
plugins {
id 'org.springframework.boot' version '2.1.3.RELEASE'
id 'org.jetbrains.kotlin.jvm' version '1.3.21'
id 'org.jetbrains.kotlin.plugin.spring' version '1.3.21'
}
apply plugin: 'io.spring.dependency-management'
group = 'com.simbalarry'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
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'
compile project(':somelib')
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
compileKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'
}
}
compileTestKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'
}
}
multidemo/settings.gradle
pluginManagement {
repositories {
gradlePluginPortal()
}
}
rootProject.name = 'multidemo'
multidemo/src/main/kotlin/somepackage/MultiDemoApplication.kt
package com.simbalarry.multidemo
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
#SpringBootApplication
class MultidemoApplication
fun main(args: Array<String>) {
runApplication<MultidemoApplication>(*args)
}
multidemo/src/main/kotlin/somepackage/SampleController.kt
package com.simbalarry.multidemo
import com.simbalarry.somelib.Tester
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
/*
* Created on : 17-03-2019
* Author : Nayan Kurude
*/
#RestController
class SampleController {
#RequestMapping("/hello")
fun hello(): String {
return Tester.getOutputText()
}
}
Could anyone please tell me where am i doing something wrong.
As I said in comments: somelib is supposed to be a library. So it shouldn't apply the spring boot plugin, whose role is to create a Spring Boot application.
Your build.gradle file for somelib should look like this:
plugins {
id 'java-library' // 1
id 'org.springframework.boot' version '2.1.3.RELEASE' apply false // 2
id 'io.spring.dependency-management' version '1.0.6.RELEASE' //3
id 'org.jetbrains.kotlin.jvm' version '1.3.21'
id 'org.jetbrains.kotlin.plugin.spring' version '1.3.21'
}
group = 'com.simbalarry'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencyManagement { // 4
imports {
mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
}
}
ext['kotlin.version'] = '1.3.21' // 5
dependencies {
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'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
compileKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'
}
}
compileTestKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'
}
}
Some explanations (see the comments in the code):
Applies the java library gradle plugin, since that's what you want to create: a library that can be used in the other project
Adds the Spring Boot plugin to the classpath of the build without applying it, in order to be able to use its BOM later. See https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/gradle-plugin/reference/html/#managing-dependencies-using-in-isolation
Applies the spring dependency management plugin to be able to specify dependencies without version, by using the version numbers specified in the spring boot BOM
Configure the dependency management plugin to use the spring boot BOM
Override the kotlin version used in the BOM (1.2.71) by the one you want to use. See https://docs.spring.io/dependency-management-plugin/docs/current-SNAPSHOT/reference/html/#dependency-management-configuration-bom-import-override-property

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'
}

Resources