I tried to use the Springframework WebClient (I use IntelliJ with gradle), and in the "dependencies" section of the build.gradle, I added
“compile group: ‘org.springframework.boot’, name: ‘spring-boot-starter-webflux’, version: versions.spring_boot”
However, when I do gradle build, it failed in the lintGradle task with the following errors:
This project contains lint violations. A complete listing of the violations follows.
Because some were serious, the overall build status has been changed to FAILED
error unused-dependency one or more classes in jakarta.annotation:jakarta.annotation-api:1.3.5 are required by your code directly (no auto-fix available)
error transitive-duplicate-dependency-classjakarta.annotation:jakarta.annotation-api:1.3.5 in configuration ‘:compile’ has 15 classes duplicated by javax.annotation:javax.annotation-api:1.3.2 (use --info for detailed class list) (no auto-fix available)
error transitive-duplicate-dependency-classjakarta.annotation:jakarta.annotation-api:1.3.5 in configuration ‘:runtime’ has 15 classes duplicated by javax.annotation:javax.annotation-api:1.3.2 (use --info for detailed class list) (no auto-fix available)
error transitive-duplicate-dependency-classjakarta.annotation:jakarta.annotation-api:1.3.5 in configuration ‘:testCompile’ has 15 classes duplicated by javax.annotation:javax.annotation-api:1.3.2 (use --info for detailed class list) (no auto-fix available)
error transitive-duplicate-dependency-classjakarta.annotation:jakarta.annotation-api:1.3.5 in configuration ‘:implementation’ has 15 classes duplicated by javax.annotation:javax.annotation-api:1.3.2 (use --info for detailed class list) (no auto-fix available)
error transitive-duplicate-dependency-classjakarta.annotation:jakarta.annotation-api:1.3.5 in configuration ‘:integrationTestCompile’ has 15 classes duplicated by javax.annotation:javax.annotation-api:1.3.2 (use --info for detailed class list) (no auto-fix available)
error undeclared-dependency one or more classes in jakarta.annotation:jakarta.annotation-api:1.3.5 are required by your code directly
error unused-dependency this dependency should be removed since its artifact is empty (no auto-fix available)
build.gradle:122
compile group: ‘org.springframework.boot’, name: ‘spring-boot-starter-webflux’, version: versions.spring_boot
Not sure if I need to add something else to the gradle build setting environment? Or if the webflux dependency conflicts with other dependencies?
There is a parent folder Par and child folder Child, they both have their build.gradle respectively. The build task in the Child folder passed but failed in the Par folder with the errors above. The use of WebClient is in the child folder and the dependency is added to the build.gradle file of the Child foler.
The build.gradle file for Par folder:
plugins {
id 'org.springframework.boot' version '2.2.6.RELEASE'
id 'nerv-java-war-module-plugin' version '10.9.0'
id 'nerv-tab-checkstyle-plugin' version '4.5.0'
id 'hackathon-teamcity-auto-increment' version '3.1.0'
id 'microservice-incremental-deploy-plugin' version '1.2.0'
id 'protobuf-java-consumer-plugin' version '4.2.0'
id 'nebula.lint' version '16.0.2'
id 'application'
id 'eclipse-wtp'
}
subprojects {
apply plugin: 'nerv-java-war-module-plugin'
apply plugin: 'nerv-tab-checkstyle-plugin'
apply plugin: 'hackathon-teamcity-auto-increment'
}
incrementalDeploy.packageNames += 'Par'
// Notice about Spring Dependency Management: It doesn't work in this project due to a
// nebula.lint bug: https://github.com/nebula-plugins/gradle-lint-plugin/issues/227
gradleLint {
criticalRules += 'all-dependency'
excludedRules += ['overridden-dependency-version']// Ignore for dependency lock
/*gradle daemon locks the Child.jar file which prevents from
cleaning the build
cause: linting rules 'undeclared-dependency','unused-dependency'
Workaround: run gw --stop and then clean */
alwaysRun = false
build.finalizedBy lintGradle
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
// Integration tests related setup for sources
sourceSets {
integrationTest {
java {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
srcDir file('src/integrationTest/java')
}
resources.srcDir file('src/integrationTest/resources')
}
}
// When running locally, configure Log4J via system property
application {
mainClassName = 'Par.ParApplication'
applicationDefaultJvmArgs = ["-Dlog4j.defaultInitOverride=false",
"-Dlogging.config=${buildDir}/config/log4j2.xml"]
}
// When running locally, we need some config files that would normally live in
// resources. However, resources get included in the published WAR file, which
// we need to avoid. We copy these to the build dir so that the same config files
// can be used by both this service, and the accompanying contractTest.
task copyConfig(type: Copy) {
from("${buildscript.sourceFile.parent}/config/")
into("${buildDir}/config")
}
bootRun.dependsOn(copyConfig)
ext.versions = [
// These definitions are shared with the contractTest application,
// so version numbers can be updated in one place.
config_decrypt: '^3.0',
grpc_helpers_java: '^19.0',
// Fixed versions for third-party packages
grpc: '1.32.1',
guava: '29.0-jre',
javax_annotation: '1.3.2',
junit: '4.12',
log4j: '2.13.1',
protobuf_java: '3.12.0',
servlet_api: '4.0.1',
slf4j: '1.7.30',
spring: '5.2.9.RELEASE',
spring_boot: '2.2.10.RELEASE'
]
configurations {
gradleLint.ignore {
// These exclusions are useful for application projects to make sure they aren't getting any log4j v1 dependencies transitively
all*.exclude group: 'log4j', module: 'log4j'
all*.exclude group: 'org.slf4j', module: 'slf4j-log4j12'
// ignore logging libraries
all*.exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
// Favor org.slf4j:jcl-over-slf4j
all*.exclude group: 'org.springframework', module: 'spring-jcl'
integrationTestCompile.extendsFrom testCompile
integrationTestRuntime.extendsFrom testRuntime
integrationTestRuntimeOnly.extendsFrom testRuntimeOnly
}
dependencies {
compile project(':Child')
compile nerv('grpc-helpers-java', versions.grpc_helpers_java)
compile group: 'com.google.guava', name: 'guava', version: versions.guava
compile group: 'com.google.protobuf', name: 'protobuf-java', version: versions.protobuf_java
compile group: 'io.grpc', name: 'grpc-api', version: versions.grpc
compile group: 'io.grpc', name: 'grpc-protobuf', version: versions.grpc
compile group: 'io.grpc', name: 'grpc-stub', version: versions.grpc
compile group: 'javax.annotation', name: 'javax.annotation-api', version: versions.javax_annotation
compile group: 'org.springframework', name: 'spring-beans', version: versions.spring
compile group: 'org.springframework', name: 'spring-context', version: versions.spring
gradleLint.ignore {
// Avoid unused-dependency error on spring-web. It is detected as a service provider which gradleLint thinks
// should be a runtime dependency. There are compile time dependencies on spring-web so use an ignore block.
compile group: 'org.springframework', name: 'spring-web', version: versions.spring
compile group: 'org.springframework.boot', name: 'spring-boot', version: versions.spring_boot
compile group: 'org.springframework.boot', name: 'spring-boot-autoconfigure', version: versions.spring_boot
compile group: 'org.springframework', name: 'spring-core', version: versions.spring
}
gradleLint.ignore { // See https://github.com/nebula-plugins/gradle-lint-plugin/issues/126
// Add javax.servlet-api for compiling but the implementations will be provided at runtime by the container
compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: versions.servlet_api
}
runtime group: 'org.apache.logging.log4j', name: 'log4j-api', version: versions.log4j
runtime group: 'org.apache.logging.log4j', name: 'log4j-core', version: versions.log4j
runtime group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: versions.log4j // For SLF4J 1.7.x releases or older.
// to consume encrypted configuration generated by tsm/tab-core-crypto, include this runtime dependency
// and set features.SecureSecretStorage = true anywhere in your application properties
runtime nerv('tab-microservice-config-decrypt-spring', versions.config_decrypt)
testCompile ( group: 'junit', name: 'junit', version: versions.junit )
gradleLint.ignore { // See https://github.com/nebula-plugins/gradle-lint-plugin/issues/126
// Add javax.servlet-api for compiling but the implementations will be provided at runtime by the container
testCompile group: 'org.springframework.boot', name: 'spring-boot-test', version: versions.spring_boot
testCompile group: 'org.springframework', name: 'spring-test', version: versions.spring
}
constraints {
implementation("com.netflix.nebula:gradle-scm-plugin:4.1.0"){
because("Breaking changes for Gradle 7 compatibility")
}
}
// Bring in logging modules. Code should be written to the slf4j API.
// At runtime, this is resolved to log4j for this service.
// PLEASE Remember to include these dependencies in all WAR files. Failure to include this will lead
// to very difficult to diagnose problems with logging not working correctly.
compile group: 'org.slf4j', name: 'slf4j-api', version: versions.slf4j
runtime group: 'org.slf4j', name: 'jcl-over-slf4j', version: versions.slf4j // slf4j implementation for commons-logging
runtime group: 'org.slf4j', name: 'slf4j-log4j12', version: versions.slf4j // Send slf4j calls to log4j
// Applications projects only: Spring Boot add the compatible Log4J implementation (omit for libraries)
// All 3 are necessary! Logging still may work without all 3 because you're getting some of these transitively, but that shouldn't be relied on.
runtimeOnly group: 'org.apache.logging.log4j', name: 'log4j-api', version: versions.log4j
runtimeOnly group: 'org.apache.logging.log4j', name: 'log4j-core', version: versions.log4j
runtimeOnly group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: versions.log4j // For SLF4J 1.7.x releases or older.
integrationTestCompile nerv('grpc-helpers-java',versions.grpc_helpers_java)
// to consume encrypted configuration generated by tsm/tab-core-crypto, include this runtime dependency
// and set features.SecureSecretStorage = true anywhere in your application properties
integrationTestCompile group: 'junit', name: 'junit', version: versions.junit
// Bring in logging modules. Code should be written to the slf4j API.
// Runtime configuration resolves this to a specific output implementation.
// The jcl-over-slf4j module directs java common logging to slf4j
// slf4j is then directed to log4j for the service and consumer, like we expect in Production.
integrationTestCompile group: 'org.springframework', name: 'spring-test', version: versions.spring
integrationTestCompile group: 'org.springframework.boot', name: 'spring-boot-test', version: versions.spring_boot
}
def testSystemProperties = [
"spring.config.location": "${project.projectDir}/build/resources/integrationTest/application-integration-test.properties",
"logging.config": "${project.projectDir}/build/resources/integrationTest/log4j2.xml"
]
task integrationTest(type: Test) {
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
outputs.upToDateWhen { false }
}
eclipse {
classpath {
defaultOutputDir = file('build-eclipse/classes')
}
}
distZip.enabled = false
distTar.enabled = false
bootRun.systemProperties = application.properties
The build.gradle file for Child folder:
version '0.1.0'
sourceCompatibility = 1.8
targetCompatibility = 1.8
ext.versions = [
spring: '5.2.9.RELEASE',
spring_boot: '2.2.10.RELEASE',
slf4j: '1.7.30',
grpc_helpers_java: '^19.0'
]
dependencies {
compile nerv('grpc-helpers-java', versions.grpc_helpers_java)
compile group: 'org.springframework', name: 'spring-core', version: versions.spring
compile group: 'org.springframework', name: 'spring-beans', version: versions.spring
compile group: 'org.springframework', name: 'spring-context', version: versions.spring
compile group: 'org.springframework', name: 'spring-web', version: versions.spring
compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version:'2.10.5'
compile group: 'com.fasterxml.jackson.core',name:'jackson-core', version:'2.10.5'
compile group: 'com.fasterxml.jackson.core', name:'jackson-databind', version:'2.10.5'
compile group: 'org.slf4j', name: 'slf4j-api', version: versions.slf4j
compile group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: versions.spring_boot
runtime group: 'org.slf4j', name: 'slf4j-log4j12', version: versions.slf4j
gradleLint.ignore {
// Avoid unused-dependency error on spring-web. It is detected as a service provider which gradleLint thinks
// should be a runtime dependency. There are compile time dependencies on spring-web so use an ignore block.
compile group: 'org.springframework', name: 'spring-web', version: versions.spring
//compile group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: versions.spring_boot
}
}
Thank you
If you are using Spring MVC and the new WebClient from Spring WebFlux in the same application, Spring MVC will be used by default. You can override that easily by calling setWebApplicationType(WebApplicationType).
It will be helpful if you can share build.gradle.
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.
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 :)
gradle looks like:
dependencies{
compile files('libs/myJarContainingGuava.jar')
compile group: 'com.google.guava', name: 'guava', version: '18.0'
}
myJarContainingGuava has an old guava version in it.
My current code is picking that jar instead of picking the guava 18.
I cannot modify myJarContainingGuava.jar
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.