unable to start embedded tomcat server - spring-boot

I use eclipse spring boot ide.
and it works fine inside eclipse.
but, build when I run jar, I get an error.
The error details are as follows.
Application run failed
org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat server
my build.Gradle dependencies config as follows.
dependencies {
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.2.4.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-websocket'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}

Related

Swagger - Error in deploying spring webflux boot war in tomcat with swagger boot starter

I am trying to deploy the spring webflux boot war in apache tomcat server.
On including the below dependency to add swagger functionality in build gradle,
compile 'io.springfox:springfox-boot-starter:3.0.0'
The war deployment is failing with below error
Failed to introspect Class [springfox.boot.starter.autoconfigure.SwaggerUiWebMvcConfiguration] from ClassLoader [ParallelWebappClassLoader
context: ROOT
delegate: false
----------> Parent Classloader:
java.net.URLClassLoader#6a78afa0
]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:481)
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:358)
at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:414)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.lambda$getTypeForFactoryMethod$2(AbstractAutowireCapableBeanFactory.java:742)
at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1737)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:741)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:680
... 43 more
Caused by: java.lang.NoClassDefFoundError: org/springframework/web/servlet/config/annotation/WebMvcConfigurer
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
... 67 more
Caused by: java.lang.ClassNotFoundException: org.springframework.web.servlet.config.annotation.WebMvcConfigurer
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1365)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1188)
... 78 more
It is expecting org/springframework/web/servlet/config/annotation/WebMvcConfigurer to be present on classpath but since this is built on spring webflux, it doesn't have it on path.
Followed springfox documentation and demos github repo for reference
https://springfox.github.io/springfox/docs/current/#gradle
https://github.com/springfox/springfox-demos/tree/master/boot-webflux
The demo repo starts the app as spring boot jar but I need to deploy as war on server.
Did anyone face this issue while deploying the spring webflux boot war on server?
Could someone please help what I'm missing on my configuration?
Edit: Added build.gradle
plugins {
id 'org.springframework.boot' version '2.3.2.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'war'
id 'groovy'
}
ext {
set('springCloudVersion', "Hoxton.SR6")
}
dependencies {
compile group: 'org.codehaus.groovy', name: 'groovy-all', version: '3.0.4', ext: 'pom'
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.13.3'
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.13.3'
compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.13.3'
compile 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'io.springfox:springfox-boot-starter:3.0.0'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.codehaus.groovy:groovy'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
compile 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testCompile group: 'org.spockframework', name: 'spock-spring', version: '2.0-M2-groovy-2.5'
testCompile group: 'io.projectreactor', name: 'reactor-test', version: '3.3.8.RELEASE'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}

How to use Spring's reactive WebClient in a Spring Web Application which runs on Tomcat

Unable to use Spring's reactive WebClient in a Spring boot based Web Application which runs on Tomcat. Application startup itself is failing due to unresolved dependencies.
I looked at https://github.com/spring-projects/spring-boot/issues/9690 but unfortunately thats not an option for me as I cannot set the WebApplication type to None
My gradle file:
dependencies {
compile(group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa') {
exclude(module: 'tomcat-juli')
}
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-redis'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web'
compile group: 'org.springframework.session', name: 'spring-session'
compile group: 'org.hibernate', name: 'hibernate-java8'
compile group: 'org.hibernate', name: 'hibernate-validator', version: '5.2.4.Final'
compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-guava'
compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-hibernate5'
compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310'
compile group: 'com.google.guava', name: 'guava'
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.3.2'
compile group: 'org.postgresql', name: 'postgresql'
compile group: 'io.jsonwebtoken', name: 'jjwt', version:'0.9.0'
compile group: 'com.nimbusds', name: 'nimbus-jose-jwt', version:'5.12'
// Spring managed dependency is not working, so resorted to using specific version
// compile('org.springframework.boot:spring-boot-starter-webflux')
compile group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: '2.1.4.RELEASE'
/*
compile group: 'org.springframework', name: 'spring-web-reactive', version: '5.0.0.M1'
compile group: 'org.springframework', name: 'spring-web', version: '5.1.6.RELEASE'
*/
implementation 'com.auth0:jwks-rsa:0.7.0
}
bootRepackage {
enabled = false
}
Error:
Caused by: java.lang.NoClassDefFoundError: org/springframework/http/client/reactive/ClientHttpConnector
at org.springframework.web.reactive.function.client.WebClient.create(WebClient.java:144)
I then tried adding,
compile group: 'org.springframework', name: 'spring-web-reactive', version: '5.0.0.M1'
Which then complained about something else, which made me add
compile group: 'org.springframework', name: 'spring-web', version: '5.1.6.RELEASE'
But then another error shows up while starting my application, which makes me think there is some other problem.
To be precise,I simply want to call a MicroService using Reactive WebClient from within another MicroService (which is Spring Boot based Web Application).
Using RestTemplate works fine but I just wanted to try the reactive WebClient and stuck with error.
Due to the way we host our dependencies, managed dependencies are not working. Our dependency server is unable to resolve them. That's the reason for having specific version of spring boot dependencies
org.springframework.http.client.reactive.ClientHttpConnector is part of the spring-web jar so it should be available if use use spring-boot-starter-webflux or spring-boot-starter-web. If you're writing a traditional servlet based application then you should be using spring-boot-starter-web.
Check the output of gradle dependencies to ensure that you have a spring-web jar. If you do, the chances are it's somehow been corrupted and you should clear your gradle cache.
I'd also recommend that you use Spring Boot's managed dependencies rather than specifify version numbers on each dependency. This will ensure that you get versions that are known to work well together.

How to run custom task within gradle build?

I have a Spring Boot web application which uses Gradle and NPM. I created a package.json file and npm install works fine. But I'd like to be able to run npm install automatically when I run gradle build. Here's my build file:
plugins {
id 'org.springframework.boot' version '1.5.10.RELEASE'
id 'java'
id 'war'
id "org.ysb33r.nodejs.base" version "0.1"
id "org.ysb33r.nodejs.npm" version "0.1"
}
group 'com.Blahblah'
version '1.0-SNAPSHOT'
war {
baseName = 'Blahblah'
version = '0.0.1'
}
sourceCompatibility = 1.8
repositories {
mavenCentral()
jcenter()
maven { url "http://repo.spring.io/libs-snapshot" }
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
compile group: 'commons-io', name: 'commons-io', version: '2.6'
compile group: 'commons-fileupload', name: 'commons-fileupload', version: '1.3.3'
compile group: 'com.cloudinary', name: 'cloudinary-core', version: '1.17.0'
compile group: 'com.cloudinary', name: 'cloudinary-http44', version: '1.17.0'
compile group: 'mysql', name: 'mysql-connector-java', version: '6.0.6'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '1.5.10.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-jersey', version: '1.5.10.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-mail', version: '1.5.10.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.5.10.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-tomcat', version: '1.5.10.RELEASE'
classpath "gradle.plugin.org.ysb33r.gradle:nodejs-gradle-plugin:0.1"
testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '1.5.10.RELEASE'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
apply plugin: "org.ysb33r.nodejs.base"
apply plugin: "org.ysb33r.nodejs.npm"
I added the ysb33r parts in plugins, dependencies and apply plugin sections, but now I get an error at the line:
classpath "gradle.plugin.org.ysb33r.gradle:nodejs-gradle-plugin:0.1"
It says:
A problem occurred evaluating root project 'Blahblah'.
> Could not find method classpath() for arguments [gradle.plugin.org.ysb33r.gradle:nodejs-gradle-plugin:0.1] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
Before I added the ysb33r lines, the build worked fine. What could be the problem? And when the problem is solved, how should I proceed in order to run npm install automatically?
Thanks.
A couple of issues:
Exec.commandLine is a String array
Your println is happening in the configuration phase, put it in a doLast block so it executes in the execution phase
Eg:
task npmInstall(type: Exec) {
commandLine 'npm install'.split(' ')
doLast {
println 'DONE!'
}
}
Rather than calling npm via Exec task, you should consider one of the gradle/nodejs plugins. Most of these are able to use an embedded nodejs version, downloaded from a repository, to execute nodejs commands rather than require a nodejs installation on the machine
See: https://plugins.gradle.org/search?term=nodejs
Eg: http://ysb33rorg.gitlab.io/nodejs-gradle-plugin/

Gradle & SLF4J refusing to exclude transitive dependencies results in IllegalStateException

I am getting this error when running unit tests on my project:
Caused by: java.lang.IllegalStateException: Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the class path, preempting StackOverflowError. See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more details.
at org.slf4j.impl.Log4jLoggerFactory.<clinit>(Log4jLoggerFactory.java:54)
... 29 more
I need SLF4J, but not the clash that the following dependencies is setting up:
dependencies {
compile("org.springframework:spring-core:$springVersion")
compile("org.springframework:spring-jdbc:$springVersion")
// compile("org.springframework:spring-orm:$springVersion"
compile("org.springframework:spring-tx:$springVersion")
compile("org.springframework.data:spring-data-jpa:1.10.1.RELEASE") {
exclude module: "slf4j-api"
exclude module: "slf4j-over-slf4j"
exclude module: "jcl-over-slf4j"
}
// tag::jetty[]
compile("org.springframework.boot:spring-boot-starter-web:1.3.5.RELEASE") {
exclude module: "spring-boot-starter-tomcat"
exclude module: "slf4j-api"
exclude module: "slf4j-over-slf4j"
exclude module: "jcl-over-slf4j"
}
compile("org.springframework.boot:spring-boot-starter-jetty")
// end::jetty[]
// tag::actuator[]
compile("org.springframework.boot:spring-boot-starter-actuator")
// end::actuator[]
testCompile("junit:junit")
compile(group: 'org.hibernate.javax.persistence', name: 'hibernate-jpa-2.1-api', version: '1.0.0.Final')
compile("org.apache.velocity:velocity:1.7")
compile(group: 'org.slf4j', name: 'slf4j-api', version: '1.7.21')
compile('org.slf4j:log4j-over-slf4j:1.7.21')
compile(group: 'org.projectlombok', name: 'lombok', version: '1.16.8')
testCompile("org.springframework.boot:spring-boot-starter-test")
testCompile(group: 'junit', name: 'junit', version: '4.11')
}
I can stop the error via:
configurations {
all*.exclude group: "org.slf4j"
}
but then I get ClassNotFoundExceptions at runtime because slf4j is needed (and its adapters).
Any ideas? I just want to exclude slf4j from Spring's dependencies. I have seen plenty of threads on this issue but not resolve it -- are my exclusions correct?
I just excluded spring-boot-starter-logging:
configurations {
all*.exclude module: 'spring-boot-starter-logging'
}
My dependencies now look like this:
dependencies {
compile "org.springframework:spring-core:$springVersion"
compile "org.springframework:spring-jdbc:$springVersion"
compile "org.springframework:spring-orm:$springVersion"
compile "org.springframework:spring-tx:$springVersion"
compile "org.springframework.data:spring-data-jpa:1.10.1.RELEASE"
compile("org.springframework.boot:spring-boot-starter-web") {
exclude module: "spring-boot-starter-tomcat"
}
compile("org.springframework.boot:spring-boot-starter-jetty")
compile group: 'org.hibernate.javax.persistence', name: 'hibernate-jpa-2.1-api', version: '1.0.0.Final'
compile "org.apache.velocity:velocity:1.7"
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.21'
compile group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.7.21'
compile group: 'org.projectlombok', name: 'lombok', version: '1.16.8'
testCompile("junit:junit")
testCompile "org.springframework.boot:spring-boot-starter-test"
testCompile group: 'junit', name: 'junit', version: '4.11'
}
Your problem is, that you have log4j-over-slf4j - which redirects all log4j logging to slf4j - and slf4j-log4j12 - which outputs all slf4j logging to log4j - in your classpath. This means you would have an endless loop which is wrong of course.
So you have to decide what you want. Do you want to redirect all log4j logging to slf4j and then direct all slf4j logging to some other logging framework (or slf4j-simple e. g. for logging to System.out or no binding to suppress the logging) or do you want to direct all slf4j logging to log4j, then it doesn't make sense to redirect log4j logging to slf4j in the first place.
How you correctly resolve your problem heavily depends on the desired result.
You can also find out what pulls in a dependency using the gradle task dependencyInsight.

Error building project while excluding transitive dependency in build.gradle file

I am creating a multi module project with Spring Boot for deploying my application and using gradle as my build tool.
Now, I am creating independent deployments for some modules in the project. Some of the project requires Embedded tomcat and some do not. All the common dependencies have been put on a common project and all other modules are dependent on this common project.
Most of the other deployment modules require an embedded tomcat application server and other web components (provided by org.springframework.boot', name: 'spring-boot-starter-web) so this has been included in the build.gradle for common project
Here is the build.gradle for common project:
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: springBootVersion
compile group: 'org.springframework.boot', name: 'spring-boot-starter-actuator', version: springBootVersion
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: springBootVersion
compile group: 'org.springframework.data', name: 'spring-data-jpa', version: springDataJpaVersion
Now, one of the other modules which is going to be deployed independently does not require this embedded tomcat and other mvc jars which comes with including spring-boot-starter-web but requires the other transitive dependencies from common project. As such, I want to exclude the transitive dependency for
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: springBootVersion
I am doing it like this in the build.gradle other project
dependencies {
compile project(':common') {
exclude group 'org.springframework.boot', module:'spring-boot-starter-web'
}
}
But while building it is throwing this error:
startup failed: build file
'/Users/user1/Documents/repo/storm/build.gradle': 30: expecting '}',
found ',' # line 30, column 44.
oup 'org.springframework.boot', module:'
changing it to:
dependencies {
compile project(':common'){
exclude group 'org.springframework.boot:spring-boot-starter-web'
}
}
throws:
Could not find method exclude() for arguments [parent-project name] on
project ':common'.
How can I exclude transitive dependency here?
You need to invoke exclude on compile not on project:
dependencies {
compile(project(':common')) {
exclude group: 'org.springframework.boot', module:'spring-boot-starter-web'
}
}

Resources