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

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

Related

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?

why I could not refer ext properties in subproject

when I import spring cloud mavenBom,if I use code:
subprojects {
apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'
ext {
springCloudVersion = "Hoxton.SR8"
}
repositories {
maven { url 'https://maven.aliyun.com/repository/public/' }
mavenLocal()
mavenCentral()
}
dependencyManagement{
dependencies {
dependency(group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.3.7.RELEASE'){
exclude group: 'log4j', name: 'log4j', version: '1.2.16'
}
dependency(group: 'log4j', name: 'log4j', version: '1.2.17')
dependency('org.projectlombok:lombok:1.18.2')
}
imports {
mavenBom 'org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}'
}
}
}
it doesn't work, and the error is :
Could not find org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}.
if I transform ${springCloudVersion} to Hoxton.SR8,it work absolutely.
so, what result in this case?
If you want ${springCloudVersion} to be interpreted, you need a GString (use double quote ")
https://groovy-lang.org/syntax.html#_double_quoted_string
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"

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

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.

I need to invoke Cucumber Runner through gradle and which in turn does all the test execution and reporting also

I am not sure whether we can run the cucumber runner class which in turn runs all the tests and does even the reporting part also.
Just like in Cucumber Maven project we run the Cucumber runner file to execute the tests and even generates the reports after run in the same context is it doable in gradle by calling the Cucumber runner class.
My cucumber runner is as below
import org.testng.annotations.AfterClass;
import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;
#CucumberOptions(features = { "classpath:featurefile" }, glue = { "classpath:com.hals.brands.test.stepdefinition",
"classpath:com.hals.brands.helper" }, plugin = { "pretty", "json:target/HalsprosBrands.json",
"com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:" }, monochrome = true, tags = "#Api")
public class **HalProsbrandsTestRunner** extends AbstractTestNGCucumberTests {
#AfterClass(alwaysRun = true)
public static void writeExtentReport() {
ReporterUtil.archiveReport();
}
}
package runners;
import com.cucumber.listener.ExtentProperties;
import com.cucumber.listener.Reporter;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import stepDefinations.Hooks;
#RunWith(Cucumber.class)
#CucumberOptions(
features = ".//test//java//FeatureList",glue = "stepDefinations",
plugin = { "com.cucumber.listener.ExtentCucumberFormatter:",
"junit:target/cucumber-results.xml"},
tags="#Smoke-Login",
monochrome = true
)
public class TestRunner {
#BeforeClass
public static void setup(){
//Initializing extent reporting here
}
}
Here I am basically initializing my cucumber feature and class definition.
plugins {
id 'java'
}
group 'org.mytest'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
repositories {
mavenCentral()
}
dependencies {
//junit
testCompile 'junit:junit:4.12'
compile group: 'org.testng', name: 'testng', version: '6.10'
//cucumber
compileOnly 'info.cukes:cucumber-jvm-deps:1.0.5'
compile group: 'info.cukes', name: 'gherkin', version: '2.12.2'
compile group: 'net.masterthought', name: 'cucumber-reporting', version: '3.18.0'
testCompile group: 'info.cukes', name: 'cucumber-junit', version: '1.2.5'
testCompile group: 'info.cukes', name: 'cucumber-picocontainer', version: '1.2.4'
compile group: 'info.cukes', name: 'cucumber-java', version: '1.2.4'
//reporting
compile 'com.vimalselvam:cucumber-extentsreport:3.0.2'
compile 'com.aventstack:extentreports:3.1.2'
compile 'com.aventstack:extentreports:3.1.2'
//logger
compile group: 'log4j', name: 'log4j', version: '1.2.17'
//selenium
compile group: 'org.seleniumhq.selenium', name: 'selenium-chrome-driver', version: '3.14.0'
compile group: 'org.seleniumhq.selenium', name: 'selenium-remote-driver', version: '3.14.0'
compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.14.0'
compile group: 'org.seleniumhq.selenium', name: 'selenium-server', version: '3.14.0'
//compile group: 'org.seleniumhq.selenium', name: 'selenium-server', version: '2.53.1'
}
test {
reports {
junitXml.enabled = true
html.enabled = false
}
testLogging {
events 'passed', 'failed', 'standardError'
showStandardStreams = true
}
}
Here to run this- you need to use the command
gradle build or test
command needs to be run in terminal.
Let me know if this helps.

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

Resources