Someone already set up Spring Boot 2 Release and spring-cloud-starter-netflix-zuul?
If I add this dependency in pom file then I have a runtime error: NoSuchFieldError: BINDER_BEAN_NAME.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-zuul</artifactId>
<version>2.0.0.M6</version>
</dependency>
This might be because of dependency management.
Trying adding the dependency management in pom.xml
<properties>
<spring-cloud.version>Finchley.M7</spring-cloud.version>
</properties>
Related
I have upgraded my Spring Boot project to 2.7.4 & Springfox to 3.0.0.
But this resulted in the exception,
Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
After doing some research, I added the following config in the application.properties, but the issue was still not fixed.
spring.mvc.pathmatch.matching-strategy=ant-path-matcher
Then I found out that, Spring Actuator is causing this issue, and setting the following property fixed the issue.
management.server.port=8082
I don't want to define a custom management port, instead I want it to take the default server port.
Why is Actuator conflicting with Springfox? How do I fix this issue?
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.4</version>
<relativePath />
</parent>
<properties>
<java.version>1.8</java.version>
<spring.cloud-version>2021.0.4</spring.cloud-version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
Springfox Swagger Config
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.basePackage("com.swagger.io")).paths(PathSelectors.any()).build();
}
}
Springfox has not been maintained for quite some time now. Getting it to work with Spring Boot 2.7 is possible by disabling more recent Spring Boot features but probably not worth your time. It's unlikely to work at all with Spring Boot 3.
You can use Springdoc instead. The migration is usually not much work: https://springdoc.org/migrating-from-springfox.html
In my application I am using grovvy dependency for using a class called GrovvyClassLoader. Earlier I was using spring version 2.2.11.RELEASE and my grovvy was on 2.5.13. Since I have upgraded to spring 2.6.6, it tends to download grovvy version 3.0.10 automatically.
I have tried to use <grovvy.version> tag inside <properties> tag in pom file to prevent spring from downloading grovvy automatically but even that is not helpful. Surprising is the fact that even grovvy dependency in my pom is set to version 2.5.13.
This my pom(parent pom),
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.6</version>
<relativePath/>
</parent>
<properties>
.
.
.
<groovy.version>2.5.13</groovy.version>
</properties>
This is a child pom to the above pom where I am actually setting dependency for grovvy,
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>2.5.13</version>
</dependency>
Can anybody tell me why is spring overriding my version and how can stop it.
I'm working in a Spring boot project which has different ways to connect with database, in dev I connect with it only with postgresql driver, and for qa and prod, I need connect through spring-cloud-gcp-starter-sql-postgresql 'cause we have a cloud environment.
So for manage all this possibilities I'm working with profiles in maven which controls my Spring profiles.
But I have a problem starter dependencies of spring cloud which are placed on my profile declaration 'cause they has no version and maven cannot recognize the default version.
This is a chunk of my pom with the version error:
So, how can I solve this problem?
Is there a way to know which is the default version for starter dependencies and save that information in a variable to be used in profile tag?
Any ideas will help a lots.
Thanks for reading and for you time. Greetings to all
You can safely extract dependencyManagement out of your profiles.
Reference: dependency-scope
import This scope is only supported on a dependency of type pom in the
<dependencyManagement> section. It indicates the dependency is to be
replaced with the effective list of dependencies in the specified
POM's <dependencyManagement> section. Since they are replaced,
dependencies with a scope of import do not actually participate in
limiting the transitivity of a dependency.
So, you can safely extract dependencyManagement out of your profiles.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<profiles>
<profile>
<id>prod</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-sql-postgresql</artifactId>
</dependency>
</dependencies>
</profile>
...
</profiles>
Or you could provide the resolved versions yourself; for Greenwich.SR2 that will be 1.1.2.RELEASE...
Im looking to create a Spring library project to share across an internal team.
At a very basic concept level The library will send message events to a queue and my plan is to standardise this within a team across several Spring Boot Microservices send messages the same way.
My pom in the library project looks something like this
<artifactId>my-library</artifactId>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
etc...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.16.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.2.Final</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.6</version>
</dependency>
I have a service in the library project that looks like this
public class EventService {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
public void sendAuditEvent(AuditMessage auditMessage){
Set<ConstraintViolation<AuditMessage>> violations = validator.validate(auditMessage);
if(!isEmpty(violations)){
log.error("Unable to send audit message");
violations.stream().forEach( v-> log.error(v.getMessage()));
}
log.info("Found {} violations", violations.size());
// etc blah blah
return;
}
}
When I import the library into another project my thinking is that I can Autowire the EventService. By adding it in the pom and then
#ComponentScan({"my.library.package.eventlibrary.service"})
How do I prevent spring version locking? If the library is using spring 2.1.5.RELEASE today and the project that imports the library uses a different version would I not end up with potentially maven conflicts?
Also lets say the project that imports the library uses a lower version of hibernate api and the library has 6.0.16.Final. How would I prevent the project from using the newer one found one in the library classpath?
To clarify my question further is there a way I can separate the dependencies in the library from the project that uses it.
Pre Java 9. You can exclude the spring dependencies using maven when you declare the dependency to your module, same goes on for Hibernate. But you can't tell to your module to use a different hibernate version in a WAR.
If you want to work around this you can develop your library as independent micro service expose interface in the form of REST or Websocket if you want full duplex communication or something else JMS whatever....
Post Java 9 you can use java modularity to define the exact dependencies for your jar module. Check Project Jigsaw https://www.baeldung.com/project-jigsaw-java-modularity.
In your case in order to have different versions of the same library (hibernate). You would need two separate class loaders. To achieve this you would need to use layering read here http://openjdk.java.net/projects/jigsaw/spec/sotms/#layers
And here is the source code of many examples including ones that use layers. Focus on them : https://github.com/accso/java9-jigsaw-examples/tree/master/jigsaw-examples
You can try to exclude all transitive dependencies that your library can bring to projects that will use it.
To do this you should replace spring-boot-starter-parent with spring-boot-dependencies in dependencyManagement section and use provided scope for all dependencies which the library needs to work with and which will be exactly used by the projects, that will work with the library.
For example, a pom.xml of your library can be looks like this:
<!-- ... -->
<groupId>com.example</groupId>
<artifactId>library</artifactId>
<version>0.1.0</version>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<spring-boot.version>2.1.5.RELEASE</spring-boot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- ... -->
Then you will be able to use your library in the different projects, that use for example the old Spring Boot:
<!-- ... -->
<groupId>com.example</groupId>
<artifactId>old-project</artifactId>
<version>0.13.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.19.RELEASE</version>
<relativePath/>
</parent>
<!-- ... -->
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>library</artifactId>
<version>0.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!-- ... -->
So this project will use hibernate-validator:5.3.6.Final from its spring-boot-starter-web.
Important notes - the code of your library should be 'compatible' with this version of Spring Boot. In other words, you should test your library with different versions of Spring Boot in which you are interested.
See my project as an example.
Might be not what you are looking for, but you can distribute your library as a spring-boot-starter auto configuration module (of course, if the clients are spring boot applications).
This way you can control your dependencies in an agile way and you give your clients more freedom in using the library.
In your particular case, if you need to send a message to a queue you for sure need to have a corresponding classes in classpath. With auto configuration you can have Class Conditions or Been Conditions based on which you can track if your clients have correct configurations in runtime. You can also fail the context loading if something is wrong (providing a meaningful error message).
Spring also provides tracking mechanisms of what could happen if a particular class/library is missing.
I have project which used JIRA REST Java Client. It worked fine until I tried to integrate it with Spring Boot. Since that I am not able to invoke createWithBasicHttpAuthentication from AsynchronousJiraRestClientFactory without error. I get:
ClassNotFoundException: org.apache.http.util.Args
So I added HttpComponents Core blocking I/O(httpcore) dependency to my pom.xml, but I after that I got
ClassNotFoundException: org.apache.http.nio.NHttpMessageParserFactory
Which I resolved with adding HttpComponents Core non-blocking I/O(httpcore-nio) to pom.xml. Now I have
NoSuchMethodError: org.apache.http.nio.client.HttpAsyncClient.start()V
I've compared dependency:tree when project has spring boot parent and when it's commented out. It shown me that adding spring boot parent changes versions of my dependencies. You can check diff here( on left without spring boot, on right with spring boot)
It seems that JIRA REST Java Client need older versions of some dependencies.
How can I solve this problem?
pom.xml
...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.0.0.RELEASE</version>
</parent>
...
<dependencies>
<dependency>
<groupId>com.atlassian.jira</groupId>
<artifactId>jira-rest-java-client-core</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore-nio</artifactId>
<version>4.3</version>
</dependency>
</dependencies>
...
I was able to fix runtime in my Spring Boot application by overriding these properties in my pom.xml
<properties>
<httpasyncclient.version>4.0-beta3-atlassian-1</httpasyncclient.version>
<httpclient.version>4.2.1-atlassian-2</httpclient.version>
</properties>
Note that there can be other problems if you decide to use http-client and/or httpassync client in your project (eg. using RestTemplate).
Atlassian should definitely upgrade the dependencies.