NullPointerException in unit tests after migrating from groovy to kotlin gradle script - spring-boot

I have no idea what's happening here, there shouldn't be a connection. Not one that manifests this specifically, anyways.
After moving the buildscript of a major spring-boot project from groovy to kotlin-DSL, some unit tests are throwing NullPointerException. It's all the unit tests that deal with methods that have manual transaction management using a TransactionTemplate. This has not happened before the move, and by now I have compared the old and the new buildscript a dozen times over and am pretty confident that I didn't forget anything.
Let's start out by comparing the two versions of the build scripts.
Old groovy:
buildscript {
ext {
kotlinVersion = '1.4.10'
springBootVersion = '2.3.3.RELEASE'
awsSdkVersion = '1.11.381'
springfoxVersion = '2.9.2'
kotlintestVersion = '3.1.7'
}
repositories {
mavenLocal()
jcenter()
mavenCentral()
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion"
classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlinVersion"
// liquibase stuff
classpath 'mysql:mysql-connector-java:5.1.44'
classpath 'org.yaml:snakeyaml:1.19'
classpath('org.liquibase:liquibase-gradle-plugin:1.2.3') {
exclude group: "org.liquibase", module: "liquibase-core"
}
classpath "org.liquibase:liquibase-core:3.5.3" // should be in sync with the version included in spring boot
}
}
plugins {
id 'net.researchgate.release' version '2.6.0'
}
apply plugin: 'kotlin'
apply plugin: 'kotlin-spring'
apply plugin: 'kotlin-jpa'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'jacoco'
apply plugin: 'org.liquibase.gradle'
apply plugin: 'idea'
group = 'webcam.yellow.service'
sourceCompatibility = 1.8
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
jacocoTestReport {
reports {
xml.enabled = true
html.enabled = true
}
}
check.dependsOn jacocoTestReport
repositories {
mavenLocal()
mavenCentral()
jcenter()
maven { url = "http://clojars.org/repo/" }
maven {
credentials {
username "${mavenUser}"
password "${mavenPassword}"
}
url = "https://artifactory.yellow.webcam/artifactory/releases"
}
maven {
credentials {
username "${mavenUser}"
password "${mavenPassword}"
}
url = "https://artifactory.yellow.webcam/artifactory/snapshots"
}
}
idea {
module {
// if you hate browsing Javadoc
downloadJavadoc = false
// and love reading sources :)
downloadSources = true
}
}
dependencies {
// avisec libraries
compile "webcam.yellow.api:webcam-api:3.2.0"
compile "webcam.yellow.authentication:messaging-authentication:1.5"
// Spring Boot
compile 'org.springframework.boot:spring-boot-starter-actuator'
compile 'org.springframework.boot:spring-boot-starter-data-jpa'
compile 'org.springframework.boot:spring-boot-starter-web'
compile 'org.springframework.boot:spring-boot-starter-security'
compile 'org.springframework.boot:spring-boot-starter-activemq'
compile 'org.springframework.boot:spring-boot-starter-validation'
compile 'io.micrometer:micrometer-registry-influx'
compile 'com.fasterxml.jackson.module:jackson-module-kotlin'
compile 'com.fasterxml.jackson.datatype:jackson-datatype-joda'
// Joda
compile 'joda-time:joda-time'
compile 'org.jadira.usertype:usertype.core:6.0.1.GA'
// Libraries
compile group: 'org.apache.commons', name: 'commons-text', version: '1.1'
compile group: 'org.apache.commons', name: 'commons-csv', version: '1.8'
// Kotlin
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinVersion}"
compile "org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}"
// Mail
compile group: 'org.springframework.boot', name: 'spring-boot-starter-mail', version: '2.2.4.RELEASE'
compile group: 'org.apache.commons', name: 'commons-email', version: '1.5'
compile group: 'javax.mail', name: 'mail', version: '1.5.0-b01'
// AWS
compile "com.amazonaws:aws-java-sdk-s3:$awsSdkVersion"
compile group: 'com.amazonaws', name: 'aws-java-sdk-sqs', version: '1.11.558'
compile group: 'software.amazon.awssdk', name: 's3', version: '2.10.61'
compile group: 'com.amazonaws', name: 'aws-java-sdk-ec2', version: '1.11.740'
// Support old pw hash lib
compile group: 'buddy', name: 'buddy-hashers', version: '1.3.0'
// Hazelcast
compile group: 'com.hazelcast', name: 'hazelcast-spring'
compile group: 'com.hazelcast', name: 'hazelcast-aws', version: '2.4'
// Swagger
compile group: 'io.springfox', name: 'springfox-swagger2', version: springfoxVersion
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: springfoxVersion
// Database
runtime 'mysql:mysql-connector-java'
runtime 'org.liquibase:liquibase-core'
compile 'org.influxdb:influxdb-java:2.13'
// HTML Generation
compile group: 'org.jetbrains.kotlinx', name: 'kotlinx-html-jvm', version: '0.6.10'
// ActiveMQ
compile group: 'org.messaginghub', name: 'pooled-jms'
// Development
compile "org.springframework.boot:spring-boot-devtools"
// Testing
testCompile 'org.springframework.boot:spring-boot-starter-test'
testCompile 'org.springframework.security:spring-security-test'
testCompile 'com.h2database:h2'
testCompile 'io.kotlintest:kotlintest:2.0.7'
testCompile 'com.nhaarman:mockito-kotlin:1.6.0'
// GSON
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
}
liquibase {
activities {
main {
changeLogFile '/db/changelog/db.changelog-master.yaml'
url 'jdbc:mysql://localhost:3307/yellow'
username 'user'
password 'secret'
classpath 'src/main/resources'
}
}
}
springBoot {
buildInfo()
}
task ebextensions(type: Exec) {
executable "sh"
args "-c", "jar uf build/libs/webcam-service*.jar .ebextensions"
}
bootJar.finalizedBy ebextensions
afterReleaseBuild.dependsOn bootJar
test {
minHeapSize = "1024m"
maxHeapSize = "1024m"
jvmArgs = ["-Xloggc:build/gclog-%p.log", "-XX:+PrintGCDetails"]
}
And the new kotlin one:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
buildscript {
dependencies {
classpath("org.jfrog.buildinfo:build-info-extractor-gradle:4.9.6")
classpath("org.jetbrains.kotlin:kotlin-allopen:1.4.10")
// liquibase stuff
classpath("mysql:mysql-connector-java:5.1.44")
classpath("org.yaml:snakeyaml:1.19")
classpath("org.liquibase:liquibase-gradle-plugin:1.2.3") {
exclude("org.liquibase", "liquibase-core")
}
classpath("org.liquibase:liquibase-core:3.8.9") // should be in sync with the version included in spring boot
}
}
val awsSdkVersion = "1.11.740"
val springfoxVersion = "2.9.2"
plugins {
id("org.springframework.boot") version "2.3.3.RELEASE"
id("io.spring.dependency-management") version "1.0.9.RELEASE"
id("net.researchgate.release") version "2.6.0"
kotlin("jvm") version "1.4.10"
kotlin("plugin.spring") version "1.4.10"
`maven-publish`
id("com.jfrog.artifactory") version "4.14.1"
id("org.liquibase.gradle") version "2.0.4"
id("org.jetbrains.kotlin.plugin.noarg") version "1.4.10"
id("org.jetbrains.kotlin.plugin.jpa") version "1.4.10"
}
group = "webcam.yellow.service"
java.sourceCompatibility = JavaVersion.VERSION_1_8
val mavenUser: String by project
val mavenPassword: String by project
val artifactoryRepository = System.getenv("ARTIFACTORY_REPO") ?: "snapshots"
repositories {
mavenCentral()
jcenter()
maven {
credentials {
username = mavenUser
password = mavenPassword
}
url = uri("https://artifactory.yellow.webcam/artifactory/releases")
}
maven {
credentials {
username = mavenUser
password = mavenPassword
}
url = uri("https://artifactory.yellow.webcam/artifactory/snapshots")
}
}
dependencies {
// Spring Boot
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-activemq")
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-mail")
implementation("io.micrometer:micrometer-registry-influx")
// Kotlin
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlinx:kotlinx-html-jvm:0.6.8")
// Yellow Dependencies
implementation("webcam.yellow.api:webcam-api:3.2.0")
implementation("webcam.yellow.authentication:messaging-authentication:1.5")
// AWS
implementation("com.amazonaws:aws-java-sdk-s3:$awsSdkVersion")
implementation("software.amazon.awssdk:s3:2.10.61") // does not yet incorporate all functionality of 1.11.X
implementation("com.amazonaws:aws-java-sdk-sqs:$awsSdkVersion")
implementation("com.amazonaws:aws-java-sdk-ec2:$awsSdkVersion")
// Support old pw hash lib
implementation("buddy:buddy-hashers:1.3.0")
// Jackson
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("com.fasterxml.jackson.datatype:jackson-datatype-joda")
// Hazelcast
implementation("com.hazelcast:hazelcast-spring")
implementation("com.hazelcast:hazelcast-aws:2.4")
// Other Libs
implementation("org.apache.commons:commons-text:1.1")
implementation("org.apache.commons:commons-csv:1.8")
implementation("org.messaginghub:pooled-jms")
implementation("org.influxdb:influxdb-java:2.13")
implementation("org.jetbrains.kotlinx:kotlinx-html-jvm:0.6.10")
implementation("org.springframework.boot:spring-boot-devtools")
implementation("com.google.code.gson:gson:2.8.6")
implementation("joda-time:joda-time")
implementation("org.jadira.usertype:usertype.core:6.0.1.GA")
// Swagger
implementation("io.springfox:springfox-swagger2:$springfoxVersion")
implementation("io.springfox:springfox-swagger-ui:$springfoxVersion")
// Database
runtimeOnly("mysql:mysql-connector-java")
runtimeOnly("org.liquibase:liquibase-core")
implementation("org.influxdb:influxdb-java:2.13")
// Test
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.security:spring-security-test")
testImplementation("com.h2database:h2")
testImplementation("com.nhaarman:mockito-kotlin:1.6.0")
testImplementation("io.kotlintest:kotlintest:2.0.7")
}
tasks.withType<Test> {
useJUnitPlatform()
}
springBoot {
buildInfo()
}
liquibase {
activities.register("main") {
arguments = mapOf(
"changeLogFile" to "/db/changelog/db.changelog-master.yaml",
"url" to "jdbc:mysql://localhost:3307/yellow",
"username" to "user",
"password" to "secret",
"classpath" to "src/main/resources"
)
}
}
tasks {
withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "1.8"
}
}
bootJar {
from("./.ebextensions") { into(".ebextensions") }
launchScript()
}
afterReleaseBuild {
dependsOn(bootJar)
}
test {
minHeapSize = "1024m"
maxHeapSize = "1024m"
jvmArgs = listOf("-Xloggc:build/gclog-%p.log", "-XX:+PrintGCDetails")
}
}
Some things needed different handling, like moving some plugins from the classpath to the plugins section, the .ebsextensions are handled differently, and Jacoco isn't in there anymore because we never really used those reports in jenkins. All in all, pretty normal. Everything works, except for this one thing in the unit tests.
Here's a class initialisation and one of the tested methods:
#Service
class ImageService(private val imageRepository: ImageRepository,
private val imageSetRepository: ImageSetRepository,
private val permissionService: PermissionService,
private val s3Service: S3Service,
private val entityManager: EntityManager,
private val panoFeedRepository: PanoFeedRepository,
private val panoImageRepository: PanoImageRepository,
private val jobFacade: JobFacade,
private val jdbcTemplate: NamedParameterJdbcTemplate,
transactionManager: PlatformTransactionManager,
#Value("\${service.cleanup.enabled}")
private val cleanupEnabled: Boolean) {
private val readTransaction = org.springframework.transaction.support.TransactionTemplate(
transactionManager,
DefaultTransactionDefinition().apply {
isReadOnly = true
propagationBehavior = TransactionDefinition.PROPAGATION_REQUIRES_NEW
})
private val writeTransaction = org.springframework.transaction.support.TransactionTemplate(
transactionManager,
DefaultTransactionDefinition().apply {
isReadOnly = false
propagationBehavior = TransactionDefinition.PROPAGATION_REQUIRES_NEW
})
/**
* Deletes all passed images from the database while removing them from S3 asynchronously.
* Does not check any permissions.
* This opens its own write transaction, which could take a long time. If individual transactions take too long,
* invoke this method multiple times with smaller chunks to avoid issues with table locking.
* Since this is potentially long-running, commit preceding transactions beforehand.
*/
#Transactional(propagation = Propagation.NEVER)
internal fun delete(images: List<ImageIdAndImageKeyAndImagePreviewKey>) {
images.chunked(500).forEach { chunk ->
log.debug("Deleting s3 files of {} images", chunk.size)
jobFacade.executeAsync {
val keysToDelete = chunk
.flatMap { listOf(it.getImageKey(), it.getImagePreviewKey()) }
.asSequence()
.filterNotNull()
.filter { !it.isBlank() }
.toList()
s3Service.deleteImages(keysToDelete)
log.trace("deleted {} s3 files of {} images", keysToDelete.size, chunk.size)
}
log.debug("Deleting {} images from database", chunk.size)
writeTransaction.execute {
imageRepository.deleteAllByIdIn(chunk.map { it.getId()!! })
} // <---- Exception happens in here
log.trace("Deleted {} images from database", chunk.size)
}
}
}
And here's a test setup and a test that tests tat method:
class ImageServiceTest {
private val imageRepository: ImageRepository = mock()
private val imageSetRepository: ImageSetRepository = mock()
private val permissionService: PermissionService = mock()
private val s3Service: S3Service = mock()
private val hazelCastInstance: HazelcastInstance = mock()
private val panoFeedRepository: PanoFeedRepository = mock()
private val panoImageRepository: PanoImageRepository = mock()
private val jdbcTemplate: NamedParameterJdbcTemplate = mock()
private val transactionManager: PlatformTransactionManager = mock()
private val jobFacade: JobFacade
private val sut: ImageService
init {
val imap: IMap<String, String> = mock()
`when`(hazelCastInstance.getMap<String, String>(any())).thenReturn(imap)
jobFacade = JobFacade(hazelCastInstance)
sut = ImageService(
imageRepository, imageSetRepository, permissionService, s3Service, mock(),
panoFeedRepository, panoImageRepository, jobFacade, jdbcTemplate, transactionManager, false)
}
#Test
fun `deleting multiple images invokes S3Service in chunks and deletes images from DB`() {
val user = TestModelFactory.userWithOneCameraAndTablePermission()
val table = user.tablePermissions.first().table!!
val images = (1..800).map { TestModelFactory.image(table = table) }
sut.delete(images.map { ImageIdentifiers(it.id, it.imageKey, it.imagePreviewKey) })
Thread.sleep(2000) //leave enough time for S3 uploads to finish
val idChunks = images.map { it.id }.chunked(500)
verify(imageRepository, times(1)).deleteAllByIdIn(eq(idChunks[0]))
verify(imageRepository, times(1)).deleteAllByIdIn(eq(idChunks[1]))
verify(s3Service, times(2)).deleteImages(any())
}
And finally, the error:
java.lang.NullPointerException: Parameter specified as non-null is null: method webcam.yellow.service.service.ImageService$delete$$inlined$forEach$lambda$2.doInTransaction, parameter it
Now, there's several things I'm currently looking into about what might go wrong, involving the mocked TransactionManager and the non-mocked TransactionTemplates... But the really frustrating thing is that this simply didn't happen before migrating the build script, and nothing else changed.

It turns out that the transactionTemplate (which is not mocked) invoked a method on the mock of the platformTransactionManager, which returned null (obviously), and that caused the NullPointerException.
It was fixed relatively easily by configuring the mock instance to return a value instead:
given(transactionManager.getTransaction(any())).willReturn(mock())
What I don't know is why this ever worked before. This problem should always have been there, but it wasn't... Only when I migrated the build file did it show its head, which doesn't really make much sense.

Related

No compileOnly configuration in the build.gradle but it is

I have the following error message during the build, but no compileOnly dependency in my build.gradle. Why it's happens, and how to solve?
Regards
Resolving dependency configuration 'compileOnly' is not allowed as it
is defined as 'canBeResolved=false'. Instead, a resolvable
('canBeResolved=true') dependency configuration that extends
'compileOnly' should be resolved.
buildscript {
ext.kotlin_version = '1.6.0'
repositories {
mavenCentral()
maven {
url "https://oss.sonatype.org/content/repositories/snapshots/"
}
maven {
url "https://plugins.gradle.org/m2/"
}
repositories {
flatDir {
dirs 'jars'
}
}
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
plugins {
id "org.jetbrains.intellij" version "1.10.1"
id "org.jetbrains.grammarkit" version "2020.1"
}
configurations {
configurations.implementation.setCanBeResolved(true)
}
group 'com.interfaced'
version '0.2.7'
apply plugin: 'kotlin'
apply plugin: 'org.jetbrains.intellij'
sourceSets {
all {
java.srcDirs += ['src/main/gen']
kotlin.srcDirs += ['src/main/kotlin']
resources.srcDirs = ['src/main/resources']
}
}
grammarKit {
jflexRelease = '1.7.0-2'
}
repositories {
mavenCentral()
maven {
url "https://cache-redirector.jetbrains.com/intellij-dependencies"
}
}
dependencies {
// https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-stdlib
compileClasspath group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib', version: '1.7.22'
compileClasspath files('jars/grammar-kit.jar')
compileClasspath group: 'junit', name: 'junit', version: '4.12'
compileClasspath "org.jetbrains.kotlin:kotlin-stdlib-jdk7"
}
intellij {
version '2022.3'
}
import org.jetbrains.grammarkit.tasks.GenerateLexer
import org.jetbrains.grammarkit.tasks.GenerateParser
def GENERATE_GROUP = 'Generate'
task generateLexer(type: GenerateLexer) {
source = "src/main/grammar/BrightScript.flex"
targetDir = "src/main/gen/com/interfaced/brs/lang/lexer"
targetClass = "_BrsLexer"
skeleton = "src/main/grammar/idea-flex.skeleton"
purgeOldFiles = true
description = 'Generate Lexer Java sources for BrightScript'
group = GENERATE_GROUP
}
task generateParser(type: GenerateParser) {
source = "src/main/grammar/BrightScript.bnf"
targetRoot = 'src/main/gen'
pathToParser = 'src/main/gen/com/interfaced/brs/lang/BrsParser.java'
pathToPsiRoot = 'src/main/gen/com/interfaced/brs/lang/psi'
purgeOldFiles = true
description = 'Generate Parser Java sources for BrightScript'
group = GENERATE_GROUP
// patch up to date check
outputs.upToDateWhen { false }
}
compileKotlin {
kotlinOptions.jvmTarget = "17"
}
compileKotlin.dependsOn(generateLexer, generateParser)

Open webpages generated by restdocs

I want to display static pages using Spring Boot. I tried this configuration:
plugins {
id "java"
id "org.asciidoctor.jvm.convert" version "3.3.2"
}
repositories {
maven { url 'https://repo.spring.io/milestone' }
maven { url 'https://repo.spring.io/snapshot' }
mavenCentral()
mavenLocal()
}
group = 'com.example'
sourceCompatibility = 11
targetCompatibility = 11
ext {
restdocsVersion = '3.0.0-SNAPSHOT'
snippetsDir = file('src/static/docs')
}
configurations {
asciidoctorExtensions
}
dependencies {
asciidoctorExtensions "org.springframework.restdocs:spring-restdocs-asciidoctor:$restdocsVersion"
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.6.3'
implementation 'io.projectreactor.netty:reactor-netty-http:1.0.15'
testImplementation 'io.rest-assured:rest-assured:4.5.0'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.0'
testImplementation "org.springframework.restdocs:spring-restdocs-restassured:$restdocsVersion"
testImplementation 'org.springframework:spring-test'
testImplementation('org.junit.vintage:junit-vintage-engine') {
exclude group: 'org.hamcrest', module: 'hamcrest-core'
}
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.0'
}
test {
outputs.dir snippetsDir
useJUnitPlatform()
}
asciidoctor {
configurations "asciidoctorExtensions"
inputs.dir snippetsDir
dependsOn test
}
jar {
dependsOn asciidoctor
from ("${asciidoctor.outputDir}/html5") {
into 'static/docs'
}
}
I placed several .adoc files under this file location:
I started the project as a Spring Boot project but when I open http://localhost:8080/docs/index.html I get white label error:
Do you know how I can serve this content as web pages?

Gradle multiple project gradle build fail with lombok 1.8.10 but compile well

I'm developing a gradle-multiple-project java application, code works well with lombok in intellij (getter, setter method is visible), but when I run gradle build then fail, get the message:
~/EventStormingWorkShop/sources/coffeeshop/coffee-domain/src/main/java/solid/humank/port/adapter/OrderReceiverAdapter.java:41: error: cannot find symbol
String orderString= mapper.writeValueAsString(orderCreatedEvent.getDetail());
^
symbol: method getDetail()
location: variable orderCreatedEvent of type OrderCreatedEvent
Current environment:
Intellij : 2019.2.3
Gradle : 5.6.2
JDK : GraalVM 19.2.0 (compatible with JDK 1.8_0222)
lombok : 1.8.10
I had checked the lombok dependencies declaration in build.gradle.
compileOnly "org.projectlombok:lombok:${lombokVersion}"
annotationProcessor "org.projectlombok:lombok:${lombokVersion}"
testCompileOnly "org.projectlombok:lombok:${lombokVersion}"
testAnnotationProcessor "org.projectlombok:lombok:${lombokVersion}"
at compile time everything wen well.
Here is the build.gradle from my rootProject
buildscript {
ext {
quarkusJunitVersion = '0.22.0'
restAssuredVersion = '3.3.0'
cucumberVersion = '4.7.1'
lombokVersion = '1.18.10'
quarkusVersion = '0.23.1'
awsJavaVersion = '1.11.631'
awsVersion = '2.5.29'
}
}
apply from: file("${rootDir}/gradle/project.gradle")
List testCompilePackage = ["io.quarkus:quarkus-junit5:${quarkusJunitVersion}", "io.rest-assured:rest-assured:${restAssuredVersion}"]
List testImplementPackage = ["io.cucumber:cucumber-java8:${cucumberVersion}", "io.cucumber:cucumber-junit:${cucumberVersion}"]
List implementationPackage = ["io.quarkus:quarkus-resteasy",
"com.amazonaws:aws-java-sdk-lambda",
"com.amazonaws:aws-java-sdk-dynamodb",
"com.amazonaws:aws-lambda-java-core",
"com.amazonaws:aws-lambda-java-events",
"com.amazonaws:aws-java-sdk-events"]
subprojects { dir ->
repositories {
mavenCentral()
}
dependencies {
// Lombok Support
compileOnly "org.projectlombok:lombok:${lombokVersion}"
annotationProcessor "org.projectlombok:lombok:${lombokVersion}"
testCompileOnly "org.projectlombok:lombok:${lombokVersion}"
testAnnotationProcessor "org.projectlombok:lombok:${lombokVersion}"
// quarkus test
testCompile testCompilePackage
// cucumber test
testImplementation testImplementPackage
// quarkus
compile group: 'io.quarkus', name: 'quarkus-gradle-plugin', version: "${quarkusVersion}", ext: 'pom'
implementation enforcedPlatform("io.quarkus:quarkus-bom:${quarkusVersion}")
implementation platform("com.amazonaws:aws-java-sdk-bom:${awsJavaVersion}")
implementation platform("software.amazon.awssdk:bom:${awsVersion}")
implementation implementationPackage
}
if (dir.name.endsWith("-domain")) {
dependencies {
implementation project(":ddd-commons")
}
}
if (dir.name.endsWith("-application")) {
String modName = dir.name.substring(0, dir.name.lastIndexOf("-application"))
dependencies {
implementation project(":ddd-commons"), project(":${modName}-domain")
}
}
if (dir.name.endsWith("-web")) {
String modName = dir.name.substring(0, dir.name.lastIndexOf("-web"))
dependencies {
implementation project(":ddd-commons"), project(":${modName}-domain"), project(":${modName}-application")
}
}
}
The build.gradle will apply a project.gradle file
project.gradle:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'io.quarkus:quarkus-gradle-plugin:0.23.1'
}
}
defaultTasks 'clean', 'build'
apply plugin: 'idea'
subprojects {
apply plugin: 'java'
apply plugin: io.quarkus.gradle.QuarkusPlugin
group 'solid.humank.coffeeshop'
version '1.0'
sourceCompatibility = 1.8
targetCompatibility = 1.8
idea.module.inheritOutputDirs = true
dependencies{
compileOnly "org.projectlombok:lombok:1.18.10"
annotationProcessor "org.projectlombok:lombok:1.18.10"
testCompileOnly "org.projectlombok:lombok:1.18.10"
testAnnotationProcessor "org.projectlombok:lombok:1.18.10"
}
tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8'
options.deprecation = true
options.compilerArgs += ['-Xlint:none', '-proc:none', '-nowarn']
}
repositories {
mavenCentral()
mavenLocal()
}
buildDir = "${rootDir}/build/${rootDir.relativePath(projectDir)}"
tasks.named('test') {
useJUnitPlatform()
failFast = true
testLogging.showStandardStreams = true
testLogging.exceptionFormat 'full'
}
tasks.named('jar') {
// put parent name in final jar name, to resolve collision of child projects with same name under different parents
if (parent.depth > 0) {
archiveBaseName = "${parent.name}-${archiveBaseName.get()}"
}
}
afterEvaluate {
def buildTime = new Date()
tasks.withType(Jar) {
String ClassPathString = ''
configurations.runtime.each { ClassPathString += " lib\\" + it.name }
manifest {
attributes 'Implementation-Title': project.name,
'Implementation-Version': project.version,
'Created-By': "${System.getProperty('java.version')} (${System.getProperty('java.vendor')})",
'Built-With': "gradle-${project.gradle.gradleVersion}, groovy-${GroovySystem.version}",
'Built-By': System.getProperty('user.name'),
'Built-On': "${InetAddress.localHost.hostName}/${InetAddress.localHost.hostAddress}",
'Build-Time': buildTime.format('yyyy/MM/dd HH:mm:ss'),
'Class-Path': ClassPathString
}
}
}
}
Besides, there is the settings.gradle to include sub projects
pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
}
resolutionStrategy {
eachPlugin {
if (requested.id.id == 'io.quarkus') {
useModule("io.quarkus:quarkus-gradle-plugin:0.23.1")
}
}
}
}
rootProject.name = 'coffeeshop'
include 'ddd-commons'
include 'inventory-domain'
include 'inventory-application'
include 'inventory-web'
include 'coffee-application'
include 'coffee-domain'
include 'coffee-web'
include 'orders-application'
include 'orders-domain'
include 'orders-web'
I expect these settings could run gradle build well, but faced seems lombok annotation processer not worked issue in gradle runtime.
Because your project.gradle has '-proc:none'

How to correctly run gradle test task?

I try to build my project with gradle when I run gradle test from Intellij Idea everything is fine - all tests are passed but when I do the same operation from command line using command gradle test some unit tests failed. That is my build.gradle file:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.5.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
bootJar {
baseName = 'myProjectName'
}
repositories {
mavenCentral()
maven {
url "my_repo_url"
}
maven {
url "my_repo_url"
credentials {
username = System.getenv("MVN_USER")
password = System.getenv("MVN_PASS")
}
}
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile ('org.apache.poi:poi-ooxml:4.0.1')
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.7'
compile ('org.springframework.boot:spring-boot-starter:2.0.5.RELEASE') {
exclude module : 'spring-boot-starter-logging'
}
compile group: 'org.apache.poi', name: 'poi-ooxml-schemas', version: '4.0.1'
testCompile('org.springframework.boot:spring-boot-starter-test:2.0.1.RELEASE')
testCompile('com.jayway.jsonpath:json-path')
testCompile group: 'commons-io', name: 'commons-io', version: '2.6'
testCompile group: 'pl.pragmatists', name: 'JUnitParams', version: '1.1.1'
compile group: 'joda-time', name: 'joda-time', version: '2.9.4'
}
and there is my junit test class:
public class MyTest {
#Test
public void testSimpleIfParsing() throws IOException {
String complicatedStructure = "testString";
IfTemplateElement MyClass = new MyClass(
complicatedStructure // This variable NOT null, but I have NullPointerException
);
Object response = MyClass.evaluate();
Assert.assertNotNull( response );
}
}
and MyClass constructor:
public class MyClass {
public MyClass( String s ) {
s = s.substring( 0, 5 ); // there I have NullPointerException.
}
}
Exception:
com.mypackage.MyTest > testSimpleIfParsing FAILED
java.lang.NullPointerException at MyTest.java:28
but if in the MyClass in the constructor I insert System.out.println(s) all tests passed in both cases (from CLI and Intellij Idea).
Can anyone help me what is goin on?
Where I mistake?
Sounds strange.
I suggested that you will try to debug the UT with intelij and after that try with gradle.
How to change the unit test runner in inteliJ?
Go to settings -> Build,Execution,Deployment > Build Tools > Gradle > Runner

Spring boot app, neo4j LoadOneDelegate null - Runs spring boot + IDE not jar

I'm building an application that uses Spring boot and neo4j ogm.
When i run it from spring tool suite or from gradle boot run, it works fine. However, after packaging it into a jar I get this error.
java.lang.NullPointerException: null
at org.neo4j.ogm.session.delegates.LoadOneDelegate.lookup(LoadOneDelegate.java:56) ~[neo4j-ogm-core-2.0.4.jar!/:na]
at org.neo4j.ogm.session.delegates.LoadOneDelegate.load(LoadOneDelegate.java:49) ~[neo4j-ogm-core-2.0.4.jar!/:na]
at org.neo4j.ogm.session.Neo4jSession.load(Neo4jSession.java:142) ~[neo4j-ogm-core-2.0.4.jar!/:na]
at comds.service.GenericService.find(GenericService.java:32) ~[classes!/:na]
at comds.service.UserServiceImpl.find(UserServiceImpl.java:36) ~[classes!/:na]
at comds.service.UserServiceImpl.find(UserServiceImpl.java:25) ~[classes!/:na]
at comds.linkedIn.LinkedInSaveUser.saveUser(LinkedInSaveUser.java:84) ~[classes!/:na]
at comds.controller.LinkedInController.home(LinkedInController.java:64) ~[classes!/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_45]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_45]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_45]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_45]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.2.7.RELEASE.jar!/:4.2.7.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-4.2.7.RELEASE.jar!/:4.2.7.RELEASE]
I suspect this is to do with the ogm configuration as the packages are used to define the meta data in ogm, which seems to be null:
package comds;
import org.neo4j.ogm.config.Configuration;
import org.neo4j.ogm.session.Session;
import org.neo4j.ogm.session.SessionFactory;
public class Neo4jSessionFactory {
private final static String [] packages = {"comds.domain"};
private final static SessionFactory sessionFactory = new SessionFactory(getConfiguration(),packages);
private static Neo4jSessionFactory factory = new Neo4jSessionFactory();
public static Neo4jSessionFactory getInstance() {
return factory;
}
private Neo4jSessionFactory() {
}
private static Configuration getConfiguration() {
Configuration configuration = new Configuration();
configuration.driverConfiguration()
.setDriverClassName("org.neo4j.ogm.drivers.http.driver.HttpDriver")
.setURI("http://neo4j:test#localhost:7474");
return configuration;
}
public Session getNeo4jSession() {
return sessionFactory.openSession();
}
}
For some reason the COMDS user class is not being read:
#Service("userService")
public class UserServiceImpl extends GenericService<COMDSUser> implements UserService{
#Override
public Class<COMDSUser> getEntityType() {
return COMDSUser.class;
}
#Override
public COMDSUser find(Long id) {
COMDSUser user = super.find(id);
if(user != null){
return applyPrivacySettings(user);
}
return null;
}
//... more stuff
public class COMDSUser extends COMDSEntity{
public enum privacySettings{
SHOW_ALL, HIDE_PERSONAL_INFO,HIDE_ALL;
}
private String firstName;
private String lastName;
/// .. more stuff
package comds.domain;
import org.neo4j.ogm.annotation.GraphId;
public abstract class COMDSEntity {
#GraphId
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || id == null || getClass() != o.getClass()) return false;
COMDSEntity entity = (COMDSEntity) o;
if (!id.equals(entity.id)) return false;
return true;
}
#Override
public int hashCode() {
return (id == null) ? -1 : id.hashCode();
}
}
And gradle build:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.6.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'war'
war {
baseName = 'COM_DS'
version = '0.1.0'
}
jar {
baseName = 'COM_DS'
version = '0.1.0'
}
repositories {
mavenCentral()
maven { url "https://repo.spring.io/libs-release" }
maven{ url "https://mvnrepository.com/artifact"}
maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local/' }
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:1.3.6.RELEASE")
compile "io.springfox:springfox-swagger2:2.5.1-SNAPSHOT"
compile("io.springfox:springfox-swagger-ui:2.5.0")
compile 'org.neo4j.driver:neo4j-java-driver:1.0.1'
compile group: 'org.neo4j', name: 'neo4j', version: '3.0.3'
compile group: 'org.neo4j', name: 'neo4j-ogm-core', version: '2.0.4'
compile group: 'org.neo4j', name: 'neo4j-ogm-api', version: '2.0.4'
compile group: 'org.neo4j', name: 'neo4j-ogm-http-driver', version: '2.0.4'
compile group: 'org.neo4j', name: 'neo4j-ogm-bolt-driver', version: '2.0.4'
compile group: 'org.neo4j', name: 'neo4j-ogm-embedded-driver', version: '2.0.4'
compile group: 'com.voodoodyne.jackson.jsog', name: 'jackson-jsog', version: '1.1'
compile("org.hibernate:hibernate-validator")
compile("org.springframework.boot:spring-boot-starter-social-facebook")
compile('org.springframework.boot:spring-boot-devtools')
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-test')
compile "org.springframework.social:spring-social-core:1.1.4.RELEASE"
compile("org.springframework.social:spring-social-security:1.1.4.RELEASE")
compile("org.springframework.social:spring-social-config:1.1.4.RELEASE")
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
compile group: 'joda-time', name: 'joda-time', version: '2.9.4'
testCompile 'junit:junit:4.10'
compile group: 'org.springframework', name: 'spring-test', version: '4.3.2.RELEASE'
compile fileTree(dir: 'resources', include: ['*.jar'])
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
}
task wrapper(type: Wrapper) {
gradleVersion = '2.3'
}
Note Im a using a custom spring social linked in class, that is being imported in the last compile
Your help would be greatly appreciated :)
Found a work around solution. Instead of exporting to a war, I exported just a jar. The issue was that exporting the file as a war changed the file structure meaning the ogm mapping couldn't be done properly. My new gradle build looks like this:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.6.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
jar {
baseName = 'name'
version = '0.1.0'
}
repositories {
mavenCentral()
maven { url "https://repo.spring.io/libs-release" }
maven{ url "https://mvnrepository.com/artifact"}
maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local/'}
maven { url 'https://oss.sonatype.org/content/repositories/snapshots'}
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:1.3.6.RELEASE")
compile "io.springfox:springfox-swagger2:2.5.1-SNAPSHOT"
compile("io.springfox:springfox-swagger-ui:2.5.0")
compile 'org.neo4j.driver:neo4j-java-driver:1.0.1'
compile group: 'org.neo4j', name: 'neo4j', version: '3.0.3'
compile group: 'org.neo4j', name: 'neo4j-ogm-core', version: '2.0.4'
compile group: 'org.neo4j', name: 'neo4j-ogm-api', version: '2.0.4'
compile group: 'org.neo4j', name: 'neo4j-ogm-http-driver', version: '2.0.4'
compile group: 'org.neo4j', name: 'neo4j-ogm-bolt-driver', version: '2.0.4'
compile group: 'org.neo4j', name: 'neo4j-ogm-embedded-driver', version: '2.0.4'
compile group: 'org.pac4j', name: 'spring-webmvc-pac4j', version: '1.1.1'
compile group: 'org.pac4j', name: 'pac4j-oauth', version: '1.9.2-SNAPSHOT'
compile group: 'org.pac4j', name: 'pac4j-core', version: '1.9.2-SNAPSHOT'
compile group: 'com.voodoodyne.jackson.jsog', name: 'jackson-jsog', version: '1.1'
compile("org.hibernate:hibernate-validator")
compile('org.springframework.boot:spring-boot-devtools')
compile group: 'javax.servlet.jsp.jstl', name: 'jstl', version: '1.2'
compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-jasper', version: '8.5.4'
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-test')
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
testCompile 'junit:junit:4.10'
compile group: 'org.springframework', name: 'spring-test', version: '4.3.2.RELEASE'
compile fileTree(dir: 'resources', include: ['*.jar'])
}
task wrapper(type: Wrapper) {
gradleVersion = '2.3'
}

Resources