SpringBoot test module doesn't search log4j2 configuration in the right classpath - java

I'm having some problems running tests in my SpringBoot project.
The project-structure is the following:
Project Structure Image
I can start the resourceService without issues, but if i even try to run the standard test of SpringBoot projects.....
package com.pcsystem;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
#RunWith(SpringRunner.class)
#SpringBootTest
public class ResourceserviceApplicationTests {
#Test
public void contextLoads() {
}
}
the program respond with this error:
Logging system failed to initialize using configuration from 'resourceservice/log4j2.xml'
java.io.FileNotFoundException: C:\java\IntelliJ_projects\baseprojectoauth2\resourceservice\resourceservice\log4j2.xml (Unable to find the specified classpath)
So i tried to change the application.properties specific property from
logging.config=resourceservice/log4j2.xml
to
logging.config=log4j2.xml
After the change i've noticed that resourceserviceApplication will not start because it can't find the log4j2.xml:
Logging system failed to initialize using configuration from 'log4j2.xml'
java.io.FileNotFoundException: C:\java\IntelliJ_projects\baseprojectoauth2\log4j2.xml (Unable to find the specified classpath)
I've tried to resolve in many ways and doing a lot of researches but at the moment i'm still stuck here.
Any idea?
ps: it seems that the Authorizationservice module doesn't suffer the same problem, but simply because i haven't set the logging.config property in Authorizationservice's application.properties (there is no need for now)
Thanks in advance and have a great day.
-UPDATE 1-
Configuration file is about all the resourceService module, so i've done as you said Kostiantyn ( thanks for you response ) but the problem still persist.
Actual situation:
Project structure after your reply
Now resourceServiceApplication won't start , saying :
Logging system failed to initialize using configuration from 'log4j2.xml'
java.io.FileNotFoundException: C:\java\IntelliJ_projects\baseprojectoauth2\log4j2.xml
and the contextLoads() method from the test package says:
java.io.FileNotFoundException: C:\java\IntelliJ_projects\baseprojectoauth2\resourceservice\log4j2.xml
Let me show you configuration file:
server.port=8888
logging.config=log4j2.xml
spring.data.mongodb.host=localhost
spring.data.mongodb.database=jogging
#spring.data.mongodb.username=admin
#spring.data.mongodb.password=pass
spring.data.mongodb.port=27017
As requested from user1615664 , below you can see my gradle file
(that's the gradle file about the resourceService module;
AuthorizationService have one specific gradle file and lastly there is
a root gradle file, that i will show to you at the end of this update)
Exscuse me for the lenght, i'm using a large number of libraries here.
buildscript {
ext {
springBootVersion = '1.5.4.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
configurations {
compile.exclude group:'ch.qos.logback'
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-mongodb')
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.springframework.boot:spring-boot-starter-web') {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
exclude module: "logback-classic"
}
compile('org.springframework.boot:spring-boot-starter-log4j2')
compile group: 'org.apache.tika', name: 'tika', version: '1.16', ext: 'pom'
compile group: 'org.apache.tika', name: 'tika-parsers', version: '1.16'
compileOnly('org.projectlombok:lombok')
compile("org.springframework.boot:spring-boot-starter-actuator")
//compile project(':authorizationservice')
// https://mvnrepository.com/artifact/org.springframework.hateoas/spring-hateoas
compile group: 'org.springframework.hateoas', name: 'spring-hateoas', version: '0.23.0.RELEASE'
// https://mvnrepository.com/artifact/org.springframework.security.oauth/spring-security-oauth2
// https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.6'
compile group: 'org.springframework.security.oauth', name: 'spring-security-oauth2', version: '2.1.1.RELEASE'
compile group: 'org.springframework.security', name: 'spring-security-jwt', version: '1.0.8.RELEASE'
// https://mvnrepository.com/artifact/org.apache.axis/axis
compile group: 'org.apache.axis', name: 'axis', version: '1.4'
// https://mvnrepository.com/artifact/axis/axis-jaxrpc
compile group: 'axis', name: 'axis-jaxrpc', version: '1.4'
// https://mvnrepository.com/artifact/commons-discovery/commons-discovery
compile group: 'commons-discovery', name: 'commons-discovery', version: '0.5'
// https://mvnrepository.com/artifact/org.slf4j/slf4j-api
// https://mvnrepository.com/artifact/javax.xml/jaxrpc-api
compile group: 'javax.xml', name: 'jaxrpc-api', version: '1.1.1'
// https://mvnrepository.com/artifact/org.apache.xmlrpc/xmlrpc
compile group: 'org.apache.xmlrpc', name: 'xmlrpc', version: '3.1.3', ext: 'pom'
// https://mvnrepository.com/artifact/javax.activation/activation
compile group: 'javax.activation', name: 'activation', version: '1.1.1'
// https://mvnrepository.com/artifact/javax.mail/mail
compile group: 'javax.mail', name: 'mail', version: '1.4.7'
// https://mvnrepository.com/artifact/wsdl4j/wsdl4j
compile group: 'wsdl4j', name: 'wsdl4j', version: '1.6.3'
testCompile('org.springframework.boot:spring-boot-starter-test')
}
PS: maybe is worthless , but in the root module ( baseProjectOauth2 )
we can admire this root gradle file
group 'com.pcsystem'
version '1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}

You've missing src/test/resources folder in your project structure, and looks like current location of log4j2.xml in the project root is not under classpath at all
Rely on Gradle project convention and place your config files accordingly, i.e. create either src/test/resources and put file in there, if your logging configuration is test specific:
src
test
java
...
resources
log4j2.xml
Or, if logging configuration inside your log4j2.xml will be used by your application during live run (included into .jar deliverable), move this file to src/main/resources instead
that will bring your logging.config=log4j2.xml working.
Further reading about Gradle project structure & resources folders is here

I feel greedy replying to my own question, but i think i've solved.
I've done these things:
-> created resource folder under test module
src
main
test
java
resources
application.properties
In that properties file i've only put this setup
logging.config=log4j2.xml
And all i have to say now is
"explicative image here"
Simply i have to deep study spring structure (and even gradle one) about auto detect of properties files

You can try to put value classpath:log4j2.xml instead of just log4j2.xml into your application.properties (or application.y[a]ml) file.
All the resources, including this file, should be placed inside the src/main/resources (where application.properties file is also placed). Regardless of a few possible exceptions.
If you want a different configuration of logging for tests, than you should put adapted file inside of tests' resources directory (src/test/resources), but if you want these to be the same, then you can leave it as is (inside src/man/resources only)

Related

How can I get in a multi-project gradle springoboot application a library jar in my classpath?

I’m working on a multi-project gradle springboot application using IntelliJ. I’m using Gradle for the dependencies and jars includes.
The main module (springboot) includes the other two, of which one of these uses an external library, out of our control that has to be located in a directory of mine. This external library contains its own settings located in a specific folder.
When I create the main jar (the one I want to execute) it includes all the depending jars, the two modules jars plus the external library jar.
First of all, I tried to add the class-path on the resources/META-INF/MANIFEST.MF of the module who needs the library, but when my intelliJ creates the Jar the resource is removed.
So because this library uses the settings from a /configs directory located 2 directories behind where the jar is. I have also tried adding the /config directory with my configurations inside the main jar 2 directories before finding the library jar, but it doesn’t work as It should. The program is unable to locate its configurations.
On the other hand, I have tried removing the library jar from the main jar and running the main jar using the command:
Java –cp (library directory) –jar (main jar)
And also
java -cp myJar.jar;/lib/xxx -Dloader.main=myMainApplicationClass org.springframework.boot.loader.PropertiesLauncher
[xxx represents one more directory before find the library jar]
see message Spring Boot Executable Jar with Classpath)
But I get a ClassNotFoundException error, so the module who uses the library couldn't found it.
How can I add the settings that the library jars and one module needs? so when I run the main jar it loads them correctly.
Finally, I must add that if I run the application from IntelliJ the program works correctly. The problem is when I want to run the application from the command line using the main jar.
Thank you!
EXAMPLES:
Example from what I have and what I want (Structure)
Config directory have to be externally from the External Library .JAR
build.gradle from module A:
plugins {
id 'java'
}
group 'MYCOMPANY.GROUP'
version '0.0.1-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
implementation group: 'org.projectlombok', name: 'lombok', version: '1.18.20'
annotationProcessor 'org.projectlombok:lombok:1.18.20'
implementation files('MODULE B.JAR')
implementation files('EXTERNAL LIBRARY .JAR')
implementation group: 'com.android.tools.build', name: 'gradle', version: '2.3.0'
//Includes
implementation group: 'javax.mail', name: 'mail', version: '1.4.7'
implementation 'org.apache.poi:poi:5.0.0'
implementation 'org.apache.poi:poi-ooxml:5.0.0'
//Includes from utils
implementation group: 'net.sourceforge.jexcelapi', name: 'jxl', version: '2.6.12'
implementation group: 'com.amazonaws', name: 'aws-java-sdk-s3', version: '1.12.39'
}
test {
useJUnitPlatform()
}
build.gradle from moduleB:
group 'MYCOMPANY.GROUP'
version '0.0.1-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.12.3'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.12.3'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.3'
}
test {
useJUnitPlatform()
}
build.gradle from main
plugins {
id 'org.springframework.boot' version '2.5.3'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'MYCOMPANY.GROUP'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation files('MODULE A.JAR')
implementation files('MODULE B.JAR')
//This includes the external library into main.JAR
//Allows to external library find the configs directory into JAR resources
implementation files('EXTERNAL LIBRARY .JAR')
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-web-services'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.aspectj:aspectjweaver:1.9.2'
implementation 'org.apache.poi:poi:5.0.0'
implementation 'org.apache.poi:poi-ooxml:5.0.0'
implementation group: 'com.google.guava', name: 'guava', version: '30.1.1-jre'
implementation group: 'org.seleniumhq.selenium', name: 'selenium-chrome-driver', version: '3.141.59'
implementation 'org.json:json:20210307'
implementation group: 'com.android.tools.build', name: 'gradle', version: '2.3.0'
}
test {
useJUnitPlatform()
}
You could try to not include externalLibrary.jar by changing the dependencies in main and a's build.gradle files to:
dependencies {
...
compileOnly files("path/to/folder/externalLibrary.jar")
testImplementation files("path/to/folder/externalLibrary.jar")
...
}
Then start your Spring application by this command:
$ java -Dloader.path=path/to/folder/ -jar path/to/main.jar
I've tested this setup and it works. However, I do not know how externalLibrary.jar interacts with configs/custom.properties. If it reads it via classpath instead of filesystem, things could be more compilcated.

Gradle dependencies in JHipster format "groupId:artifact"

I am posting here to understand how does JHipster work with Gradle dependencies, in particular with regards to the fact that I am unable to copy some of them into a Gradle submodule I have created inside my JH project.
For example, the following doesn't work in a Gradle submodule
compile "junit:junit"
Error is
Could not resolve: junit:junit
However, the classic one copied from mvnrepository works great
compile group: 'junit', name: 'junit', version: '4.12'
Some additional information: I am creating a submodule that contains a set of classes related to testing, mainly a large load of custom Hamcrest matchers copied from another project from the Ant world. The original project had a lot of spaghetti code mess, so now I am refactoring into an isolated Gradle module. The testlib module shall depend on the testing frameworks and contain everything required for writing good tests. It can be compared to spring-test project you would use to write your own Spring-based tests.
At the moment, the gradle file looks like
plugins {
id "java"
}
configurations {
providedRuntime
implementation.exclude module: "spring-boot-starter-tomcat"
}
repositories {
mavenLocal()
mavenCentral()
jcenter()
}
group 'org.example' //different from com.acme of super-project
version '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
dependencies {
compile group: 'org.assertj', name: 'assertj-core', version: '3.13.2'
compile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.2'
compile group: 'org.hamcrest', name: 'hamcrest', version: '2.1'
compile group: 'org.mockito', name: 'mockito-core', version: '3.0.0'
compile group: 'org.springframework.boot', name: 'spring-boot', version: spring_boot_version
compile "junit:junit" //Fails
}
Question
So the question is in two parts:
why does the scope "orgId:name" syntax work in the JHipster-generated module but not in submodules? Is it part of standard Gradle syntax?
why is that not working in a sub-module? Does JHipster apply a custom plugin to apply the correct version number that is clearly missing? How I do the same in a sub-module that is supposed to contain only Java library code?
With regards to JHipster, a little of more investigation helped. According to this answer, there is a trick in Gradle called Bill Of Materials project, so...
TL;DR
Add the following to the sub-project
// import JHipster dependencies BOM
implementation platform("io.github.jhipster:jhipster-dependencies:${jhipster_dependencies_version}")
So that the whole block looks like
dependencies {
// import JHipster dependencies BOM
implementation platform("io.github.jhipster:jhipster-dependencies:${jhipster_dependencies_version}")
compile "org.assertj:assertj-core"
compile "org.junit.jupiter:junit-jupiter-api"
compile "org.hamcrest:hamcrest"
compile "org.mockito:mockito-core"
compile "org.springframework.boot:spring-boot"
compile "junit:junit"
}
Long answer
Maybe in the future when I will understand Gradle more. Or just edit this answer 😁 to contribute
The bom defines the versions (besides other things) of 3rd party dependencies to be used so you can omit the explicit version. If you do not use the bom you can also write compile "junit:junit:4.12" but keep in mind jhipster uses already junit5 for all tests by default.
Regarding the import of the bom you can do it like you proposed or try to apply that dependency to all gradle subprojects in your main gradle file.

After adding SQLServer dependency to Gradle, jar can't find Main class

I have a Gradle project with some third party dependencies.
My jar has been working fine until I added SQLServer dependency.
Here is a snapshot of build.gradle:
group 'MyApp'
version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'idea'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile 'com.amazonaws:aws-java-sdk:1.11.60'
compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.6'
compile files('mylibraries/ojdbc7.jar')
compile files('mylibraries/postgresql-42.1.4.jar')
compile files('mylibraries/mssql-jdbc-6.2.1.jre8.jar')
}
jar {
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes 'Main-Class': 'MainLauncher'
}
}
Everything breaks down after compile files('mylibraries/mssql-jdbc-6.2.1.jre8.jar') has been added to dependencies. The error I get:
Error: Could not find or load main class MainLauncher
What could be a potential problem? Thank you!
Today i faced exactly same issue and i reached to this page to get the resolution
I was running jar with below dependency
group: 'com.microsoft.sqlserver', name: 'mssql-jdbc', version: '6.2.2.jre8'
and i was facing exactly same issue,
Error: Could not find or load main class
later i changed dependency with older version and it run fine after this change
group: 'com.microsoft.sqlserver', name: 'mssql-jdbc', version:
'6.2.1.jre7'
I've had the same problem some time ago. I just imported the project and wanted to do a gradle clean build. I had exactly the same error.
I could solve this by just making sure I had at least one migration. It may sound silly but just try to create 1 migration for your database.
At least it solved my problem and I surely hope it solves yours too!

Gradlew doesn't add dependencies to my external libraries(class path) in IDEA 16.2

tl;dr; adding adding dependencies to build.gradle downloads it fine but doesn't add it to the classpath/external libraries in idea.
Hi guys
Im new to developing webapps in java, and im trying to depend on a few jars on mvnrepository.com, the only time the dependencies are downloaded into the external libraries and added to the classpath is when i import the project as a gradle project, as in, each time i have a project up and running and i add a new dependency i would have to import the whole project into intellij again.
my build.gradle file looks like this:
group 'project_name'
version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'idea'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
// https://mvnrepository.com/artifact/com.google.inject/guice
compile group: 'com.google.inject', name: 'guice', version: '3.0'
// https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-core
compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '9.0.0.M9'
// https://mvnrepository.com/artifact/com.sun.jersey/jersey-core
compile group: 'com.sun.jersey', name: 'jersey-core', version: '1.19.1'
// https://mvnrepository.com/artifact/com.sun.jersey/jersey-json
compile group: 'com.sun.jersey', name: 'jersey-json', version: '1.19.1'
// https://mvnrepository.com/artifact/org.glassfish.jersey.core/jersey-client
compile group: 'org.glassfish.jersey.core', name: 'jersey-client', version: '2.23.2'
// https://mvnrepository.com/artifact/com.sun.jersey/jersey-servlet
compile group: 'com.sun.jersey', name: 'jersey-servlet', version: '1.19.1'
// https://mvnrepository.com/artifact/com.sun.jersey/jersey-server
compile group: 'com.sun.jersey', name: 'jersey-server', version: '1.19.1'
testCompile group: 'junit', name: 'junit', version: '4.11'
}
task wrapper(type: Wrapper) {
gradleVersion = '2.5'
}
When i add a new dependency to the list, and run ./gradlew build, with or without the --refresh-dependencies option it does download the new dependencies but it doesn't add the downloaded files to the external libraries/classpath so i can't import them into the java code. I saw a question similar to this one, where they accepted answers like running:
./gradlew idea
In my case this doesn't help at all, it just adds some autogenerated files in the directory with no clear difference to behavior.
Then they accepted importing the project as a gradle project aswell, which i have done - which works, but adding new dependencies doesn't work.
FYI I am using the gradle 2.5 wrapper and IDEA community 16.2
Okay. I solved/figured it out, Apparently it didn't help to just run build,
inside of intellij i had to go to View --> Tool Windows --> Gradle, it then opens the gradle window, where i could click the refresh button, which downloads the dependencies.
Thanks to anyone who looked it over :)

build.gradle for eclipse project with multiple source folders

I have a eclipse project with source folders like:
/src/main/java/module1
/src/main/java/module2
/src/main/java/module3
inside these src folders i have packages like:
com.example.module1.xxx
com.example.module2.yyy
com.example.module3.zzz
I have made a gradle build using java and eclipse plugin with sourcesets like:
apply plugin: 'java'
apply plugin: 'eclipse'
sourceSets {
main {
java {
srcDirs = ['src/main/java/module1']
srcDir 'src/main/resources'
srcDir 'src/main/java/module2'
srcDir 'src/main/java/module3'
}
}
}
jar{
manifest {
attributes 'Implementation-Title': 'Example Project',
'Implementation-Version': '1.0.0'
}
}
repositories {
mavenCentral()
}
dependencies{
compile group: 'com.zaxxer', name: 'HikariCP', version: '2.2.5'
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: log4j2Version
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: log4j2Version
compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: log4j2Version
compile group: 'org.apache.logging.log4j', name: 'log4j-jul', version: log4j2Version
compile group: 'org.apache.logging.log4j', name: 'log4j-jcl', version: log4j2Version
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.9'
}
The problem is when i generate eclipse project using gradle eclipse it correctly generates the 3 module source folders, a resources source folder but it also generates the super source folder src/main/java having all the nested source folders with packages like:
module1.com.exaple.module1.xxx
module2.com.exaple.module2.yyy
module3.com.exaple.module3.zzz
Thus i get error in eclipse "Cannot nest '${projectdir}/src/main/java/module1' inside '${projectdir}/src/main/java'. To enable the nesting exclude 'module1/' from '${projectdir}/src/main/java'"
How do i modify my tasks/sourcesets to get the right project structure?
Well finally figured out that the build.gradle is fine... what i was doing wrong is i was executing command gradle eclipse which was just appending entries into the existing .classpath file, To generate a fresh copy i had to execute gradle cleanEclipseClasspath eclipse which produced the correct .classpath file.

Categories

Resources