I'm interested is it possible to disable features into Spring Boot/Cloud which are not used?
If there is no way to remove a lot of the necessary features? Do you know some guide how I can make a custom build?
I'm interested how Spring Boot can be optimized for read-time processing.
You can exclude features as tomcat from starter's dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>tomcat-embed-el</artifactId>
<groupId>org.apache.tomcat.embed</groupId>
</exclusion>
<exclusion>
<artifactId>tomcat-embed-core</artifactId>
<groupId>org.apache.tomcat.embed</groupId>
</exclusion>
<exclusion>
<artifactId>tomcat-embed-websocket</artifactId>
<groupId>org.apache.tomcat.embed</groupId>
</exclusion>
</exclusions>
</dependency>
Or similar for Logback by removing from build or classpath:
Spring Boot tries to work with whatever is in the classpath, so if you don't want logback, take it off the classpath.
Add exclusion to both the spring-boot-starter and spring-boot-starter-web to resolve the conflict.
Or cloud config/discovery:
#Disable discovery
spring.cloud.discovery.enabled = false
#Disable cloud config and config discovery
spring.cloud.config.discovery.enabled = false
spring.cloud.config.enabled = false
What are the features are you expecting to disable ?
If you feel any dependency is not used try tag in your pom.xml. So that you can cut down some dependency and make you application lightweight.
Related
I have a project that uses Spring Boot 2.0.0.RC2. I need to deploy it to a customer environment using traditional deployment for Tomcat 7.0.82.
I've managed to build a war that can be deployed successfully by configuring web.xml in a typical way for Spring applications (with DispatcherServlet) instead of using SpringBootServletInitializer.
I also would like to have a quick way of starting the app on local environment using an embedded Tomcat container by simply running the main method in the application class with #SpringBootApplication annotation. It works fine if I'm using the default Tomcat version (8.5.28). However, I would like to start the embedded container also in 7.0.82 version. This is important for me for another reason - I'm using SpringBootTest and it would be nice if those tests run on the exact same container as the customer environment. Unfortunately, I can't use the Spring Boot parent POM and override tomcat.version property.
I've tried #SpringBootApplication(exclude = ServletWebServerFactoryAutoConfiguration.class) create TomcatServletWebServerFactory bean manually
#Bean
public ServletWebServerFactory tomcatServletWebServerFactory() {
return new TomcatServletWebServerFactory();
}
and add tomcat 7.0.82 dependencies explicitly in pom.xml (${tomcat.version} = 7.0.82):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-annotations-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-annotations-api</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-util</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
<version>${tomcat.version}</version>
</dependency>
but I'm still getting a java.lang.NoClassDefFoundError: org/apache/tomcat/util/scan/StandardJarScanFilter error.
Could you please advise if there is any way to meet my requirements?
Spring boot 2:
The minimum supported version of Tomcat is 8.5
Reference: https://dzone.com/articles/spring-boot-20-new-features-infrastructure-changes
activemq not compatibale with spring 4.3.6. And i cant change spring version. I use following dependencies in pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>4.3.6.RELEASE</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- ActiveMQ -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.15.0</version>
</dependency>
Where activemq show dependency on 4.3.9 i also tried 5.14.4 which have dependency on 4.1.9.
How can i resolve this issue.
I used client dependency only and now its working.
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
<version>5.15.0</version>
</dependency>
This does not have spring dependencies. Either we can use exclusion if we are using all jar or can use specific dependencies needed for project. Thanks for help.
I'm including spring-data in my pom.xml like so:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.5.1.RELEASE</version>
</dependency>
However it includes a bunch of older Spring 3.2.8 jar files that I don't want bundled. Do I need to put exclusions for the 7 or so spring jars to not be included?
Thanks!
Yes, set exclusions. You can either set all of them individually or if you want to exclude all transitive Spring dependencies that come with Spring Data you may use a wildcard.
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.5.1.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
Maven will log a warning because that feature will only be supported in upcoming Maven versions even though it's been there for years.
I have JavaEE application that uses Spring and Logback.
I want be able to set log file path in application.properties file (which stores Spring properties).
Setting property ${path.to.log.file} in logback.xml do not work (and it's understandable). What is good way to do it then?
Based on Spring reference documentation:
Make sure that you exclude commons-logging from Spring dependencies. Note that this exclusion may happen for more than one module of Spring.
Assuming that you're using SLF4J, make sure that you also include jcl-over-slf4j in your dependencies.
Include the proper Logback dependencies that you need.
Place logback.xml configuration in the root of your classpath.
Probably something like this finally:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${version.spring}</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${version.slf4j}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${version.slf4j}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${version.logback}</version>
</dependency>
One way to achieve this will be by setting a property for logpath in system variable.
Suppose you are using tomcat, then in your setenv.bat/setenv.sh file set the property as
-Dpath.to.log.file="/home/birendra/"
Now you can refer the path in your logback.xml
I have a question about exclusion of maven dependencies. Consider the following
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${spring-security.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.1.0.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>
<dependency>
I am trying to achieve a transition from Spring 3.0.6 to 3.1.0 . Spring security 3.1.0 had a dependency on spring-security-web version 3.0.6 which in turn had a dependency on spring-web 3.0.6. I need to bring it all to 3.1.0. So I exclude spring-security-web from Spring security, have a separate dependency for spring-security-web 3.1.0 which in turn excludes the spring-web 3.0.6 version and I provide a separate spring-web 3.1.0 version. This work but I feel there would be a much easier approach. I tried putting an exclusion for spring web under Spring security but it did not work.
You can utilize the dependency management mechanism.
If you create entries in the <dependencyManagement> section of your pom for spring-security-web and spring-web with the desired 3.1.0 version set the managed version of the artifact will override those specified in the transitive dependency tree.
I'm not sure if that really saves you any code, but it is a cleaner solution IMO.
Global exclusions look like they're being worked on, but until then...
From the Sonatype maven reference (bottom of the page):
Dependency management in a top-level POM is different from just
defining a dependency on a widely shared parent POM. For starters, all
dependencies are inherited. If mysql-connector-java were listed as a
dependency of the top-level parent project, every single project in
the hierarchy would have a reference to this dependency. Instead of
adding in unnecessary dependencies, using dependencyManagement allows
you to consolidate and centralize the management of dependency
versions without adding dependencies which are inherited by all
children. In other words, the dependencyManagement element is
equivalent to an environment variable which allows you to declare a
dependency anywhere below a project without specifying a version
number.
As an example:
<dependencies>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
It doesn't make the code less verbose overall, but it does make it less verbose where it counts. If you still want it less verbose you can follow these tips also from the Sonatype reference.