unable to remove tomcat jdbc dependency - spring

I am building a spring-boot application using an alternative to tomcat related stuff (jetty instead of tomcat and hikariCP instead of tomcat-jdbc) and want to exclude them from my dependencies written in pom.xml
I did that for 2 of the packages as shown below -
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.6.0</version>
</dependency>
But there is some dependency which is including tomcat-jdbc as part of it.
Is there a way to debug that and find out which dependency is including tomcat jdbc as part of it?

mvn dependency:tree
If you run mvn dependency:tree, you will see that there are now a number of additional dependencies.

Related

How do add Log4j to maven project with Spring Boot

I have a project that uses springboot, but mvn can't find any log4j-api although I included it in the dependencies. I want to know what is the proper way of adding it, here is the error msg I get for 'mvn install':
"Failure to find org.apache.logging.log4j:log4j-api-java9:pom:2.13.3 in https://devtools.jahia.com/nexus/content/repositories/jahia-releases was cached in the local repository, resolution will not be reattempted until the update interval of archetype has elapsed or updates are forced"
My pom.xml uses dependency manager for spring boot, because I have a different parent:
Thank you for your replies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Not sure if you are still looking for an answer. But springboot uses commons logging by default and if you want to change it, you need to specifically exclude springboot-starter-logging and add log4j2 dependency.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>``
Full doc:
https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto.logging.log4j

Where to get the exclusion items in Spring Boot Starter Packages

I'm using Spring initializr to have the necessary package and downloading. Once I download, there are changes that I'm making in the pom.xml like excluding packages like slf4j, logging (when i plan to use log4j2) and excluding tomcat when trying to deploy into standalone server.
I don't know what are the other items that are capable to exclude. Is there any documentation like which package contains additional artifacts? Trying to avoid certain jars while packaging so that I think I can reduce the package(jar/war) size.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
All spring boot starter packages can be found here:
https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-starters
They are all just pom.xml files. You can exclude anything you want from any dependency you are using by analyzing the pom's dependencies in the started packages.

Is it possible to configure the spring boot server explicitly?

I've a Spring Boot application where one of the dependencies is using spring and a embedded jetty to start an ad-hoc web server. This causes my spring boot app to start in a jetty instead of a tomcat.
My spring-boot-starter-web:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
</exclusion>
</exclusions>
</dependency>
The dependencies pom:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-http</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
</dependency>
Is there a possibility to configure the server to use by spring boot explicitly instead of being inferred by the dependency tree?
EDIT
I investigated the issue a little bit further and created a repo to reproduce the issue: github.com/svettwer/spring-server-test
org.eclipse.jetty.websocket:javax-websocket-server-impl causes spring to start with jetty without any other config required.
EDIT 2
The issue is not present anymore in Spring Boot 2.x
EDIT 3
I'll deleted the repo mentioned earlier, but here is the dependency setup that caused the issue:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.5.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>1.5.7.RELEASE</version>
<scope>test</scope>
</dependency>
<!-- Comment that in to start spring with jetty-->
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>javax-websocket-server-impl</artifactId>
<version>9.4.8.v20171121</version>
</dependency>
</dependencies>
Normally, if you have the spring-boot-starter-tomcat on your classpath (through spring-boot-starter-web), it should always select Tomcat since it has priority over other servlet containers. Even if you have the following dependencies, Spring boot will start with Tomcat:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
</dependency>
You can programmatically override the chosen servlet container by registering your own ServletWebServerFactory, for example:
#Bean
public ServletWebServerFactory factory() {
return new TomcatServletWebServerFactory();
}
You can choose the predefined TomcatServletWebServerFactory, JettyServletWebServerFactory or the UndertowServletWebServerFactory.
This guide may help you: https://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-web-servers.html
If you run an mvn dependency:tree and search for jetty you might find that you need to exclude it, e.g:
spring-boot-starter-jetty
excluded like in the example:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- Exclude the Tomcat dependency -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Use Jetty instead -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
which is favouring jetty over tomcat - but you get the idea hopefully...
Hope this helps.

So confused on how to use Spring boot logging

I have a spring boot app which I am struggling to get logging working with a rolling appender strategy.
Here's the relevant part of my pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>phoenix</groupId>
<artifactId>phoenix</artifactId>
<version>4.1.0-client-hadoop2</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>20030825.184428</version>
</dependency>
<dependency>
<groupId>org.apache.directory.studio</groupId>
<artifactId>org.apache.commons.pool</artifactId>
<version>1.6</version>
</dependency>
</dependencies>
When I just run my app with the pom.xml left alone, I get this error:
java.lang.IllegalStateException: Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar on the class path, preempting StackOverflowError. See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more details.
I read up on doing exclusions, so I figure I need to add the exclusion to the boot starter, like this:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<exclusions>
<exclusion>
<artifactId>log4j-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
Then when I run it, I get this other error:
java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.slf4j.impl.Log4jLoggerFactory loaded from file:/C:/maven/repo/phoenix/phoenix/4.1.0-client-hadoop2/phoenix-4.1.0-client-hadoop2.jar). If you are using Weblogic you will need to add 'org.slf4j' to prefer-application-packages in WEB-INF/weblogic.xml Object of class [org.slf4j.impl.Log4jLoggerFactory] must be an instance of class ch.qos.logback.classic.LoggerContext
So it's talking about some conflict I guess with the phoenix driver but I don't understand why. When I load my pom.xml and look at the Dependency Heirarchy and look for that jar, it doesn't list anything under it that I can try to exclude.
So at this point I don't know how to proceed.
To remove logback do this:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<exclusions>
<exclusion>
<artifactId>log4j-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
</exclusions>
</dependency>

where to put the log4j.properties file in a spring boot application

I have created a log4j.properties file, and I have put it in the resources folder as the application.properties file, in this file I have this line : logging.config=log4j.properties which indicated the name of my log4j properties file, but when I run my application I'm getting this error on my console :
Logging system failed to initialize using configuration from 'log4j.properties'
java.io.FileNotFoundException: C:\Users\***\Desktop\CapRecrute\log4j.properties (The system cannot find the file specified)
so I tried to change the logging.config property to src\\main\\resources\\log4j.properties, and then I got another error :
java.lang.IllegalStateException: Could not initialize Logback logging from src\main\resources\log4j.properties ... Caused by: ch.qos.logback.core.LogbackException: Unexpected filename extension of file [file:/C:/Users/Aimad%20MAJDOU/Desktop/CapRecrute/src/main/resources/log4j.properties]. Should be either .groovy or .xml
in my pom file I have this :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
How can I solve this ?
The simplest thing is to use Spring's Logback. You just need to add these 2 lines to application.properties
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR
and make sure there are no other logging related lines.
If you instead want log4j, then configure so in your pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
And then in your paplication.properties:
logging.path=/tmp/logs/
logging.file=/tmp/logs/myapplog.log
logging.config=log4j.properties
Also make sure log4j is in the root of your project (not under resources).
Spring boot is expecting a logback file by default and you have provided log4j configuration. If you add the log4j dependency you should find it works. If you are using maven you can do so like this:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
Two issues:
Is slf4j-log4j12 exclusion required?
I think that exclusion of spring-boot-starter-logging should be applied to spring-boot-starter.
That's not complete POM. I assume that spring-boot-starter is included, right?
If you remove slf4j-log4j12 exclusion and move spring-boot-starter-logging to spring-boot-starter your file should look like example from documentation.
http://docs.spring.io/spring-boot/docs/current/reference/html/howto-logging.html
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
</dependency>

Resources