Spring Boot Application giving 404 after upgrading to springboot 2.6.6 - java

I have changed the spring boot version of my web application from 2.1.2 to 2.6.6 . Here is the POM---
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.6</version>
<relativePath>/</relativePath> <!-- lookup parent from repository -->
</parent>
A1fter version upgrade I faced some circular dependency issues which I resolved using constructor injection with #Lazy annotation. Below is example---
#Autowired
public ServiceImpl(#Lazy ABCService abcService,
#Lazy XYZService xyzService,
#Lazy PQRMapper pqrMapper,
#Lazy PQRService pqrRepositoryService) {
super();
this.abcService = abcService;
this.xyzService = xyzService;
this.pqrMapper = pqrMapper;
this.pqrRepositoryService = pqrRepositoryService;
}
But if I am trying to hiit any API it is giving me 404.
Can anyone suggest what I can do to resolve this.

I found the issue after going through all the release documents, I figured out that spring-boot disables the default-dispatcher-servlet. so we need to enable it with property-
server.servlet.register-default-servlet=true
This solution worked for me.

in log there is info exposing one endpoint beneath base path '/internal'
maybe those controllers you try to use are not created maybe package is not scaned

Related

REST API returning http status 404 when deployed on EC2 instance on AWS

I have a simple spring boot app which has just 2 rest controllers and I am exporting the war for the same.
I am deploying the same war using the tomcat manager on EC2 instance on AWS, but unfortunately I am getting http status 404 when trying to hit the API.
URL that I am trying to hit is -
[public IP shared by AWS]:[port number on which tomcat is running:8080]/[context route which is the name of my war file]/[my mapped urls]
[publicIP]:8080/aws-0.0.1-SNAPSHOT/login/code
My Controller class
#RestController
#RequestMapping("/login")
public class TestController {
#GetMapping("code")
public String returnCode() {
return "returning code";
}
#GetMapping("received-code")
public String returnReceivedCode(#RequestParam String code) {
return code;
}
}
My pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.test</groupId>
<artifactId>aws</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>aws</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
I tried with java version 8 as well, the tomcat version that I have on my EC2 instance is 9 (apache-tomcat-9.0.70)
I also tried getting one sample war application that tomcat shares for the testing purpose -
https://tomcat.apache.org/tomcat-7.0-doc/appdev/sample/
But surprisingly, this is working fine which tells me that my tomcat and java installations don't have any issues.
Any help would be appreciated.
As highlighted by #khmarbaise above, I was using spring boot 3.0.0 but I had java 8 installed on my EC2 instance and spring boot 3.0.0 requires java version 17+, and that is why I was getting 404 when hitting my APIs.
After downgrading my spring boot version to 2.7.6 I am able to get a corresponding response from the APIs.
Also, as mentioned by other comments regarding the use of "/", omitting the slash was not an issue as the slash is an optional parameter.
Thanks
You have to add a "/" before "code"
#GetMapping("/code")
you forgot to add / for your path in controller methods because of you use path:
/logincode
instead /login/code

Spring Framework upgrade 5.X leads to error class file for org.springframework.context.SmartLifecycle not found

I have been upgrading one of the app to spring framwork 5.X from 3.X, one of the problem I am failing to resolve it error is following - this makes a use of spring-jms
cannot access org.springframework.context.SmartLifecycle [ERROR]
class file for org.springframework.context.SmartLifecycle not found
I can see last version the exact same code works with Spring 4.3.9 (last of 4.X release) and breaks with Spring 5.0.0 (First of 5.X releases)
I don't see my code exposing the class SmartLifecycle but I have suspicion that DefaultMessageListenerContainer instance is at a fault.
public class Factory {
private DefaultMessageListenerContainer testListnerService;
public void start() {
final TestMessageListener testMessageListener = new TestMessageListener();
testListnerService = new DefaultMessageListenerContainer(); <-- This is where compilation breaks
testListnerService.setMessageListener(testMessageListener);
testListnerService.setSessionTransacted(true);
testListnerService.afterPropertiesSet();
}
I have created minimal example here https://github.com/milandesai47/com.jms.test/blob/master/pom.xml#L33
Am I missing anything obvious in terms of spring dependencies?
You need to add the following dependency to your pom.xml:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>

Caused by: java.lang.NoSuchMethodError: org.springframework.data.mongodb.core.MongoTemplate.<init>(Lcom/mongodb/Mongo;Ljava/lang/String;)V

While trying to run Spring-boot application (v2.1.0) getting below error:
Description:
An attempt was made to call the method org.springframework.data.mongodb.core.MongoTemplate.(Lcom/mongodb/Mongo;Ljava/lang/String;)V but it does not exist. Its class, org.springframework.data.mongodb.core.MongoTemplate, is available from the following locations:
file:/C:/Users/npatil/.m2/repository/org/springframework/data/spring-data-mongodb/2.1.2.RELEASE/spring-data-mongodb-2.1.2.RELEASE.jar!/org/springframework/data/mongodb/core/MongoTemplate.class
It was loaded from the following location:
file:/C:/Users/npatil/.m2/repository/org/springframework/data/spring-data-mongodb/2.1.2.RELEASE/spring-data-mongodb-2.1.2.RELEASE.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of org.springframework.data.mongodb.core.MongoTemplate
Below is a snnipet from my pom:
<dependencies>
.
.
<dependency>
<groupId>com.github.mongobee</groupId>
<artifactId>mongobee</artifactId>
<version>0.13</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
.
.
</dependencies>
Version of some of the jars that could help are:
spring-data-mongodb : 2.1.2.RELEASE
spring-web : 5.1.2.RELEASE
mongo-java-driver : 3.8.2.RELEASE
Deleted .m2 and did mvn clean install, but even that did not resolve the issue. Any help would be greatly appreciated.
Looks like jar is corrupted or missing,
check all spring related jar are 4.x or higher version
if that doent work then:
Mongobee depends on Spring 4.x jars which may conflicts with Spring boot 2.x
try the below way
#Bean
public Mongobee mongobee(){
Mongobee mongobee = new Mongobee("mongodb://localhost:27017/seed");
mongobee.setChangeLogsScanPackage(InitialData.class.getPackageName());
mongobee.setMongoTemplate(template);
return mongobee;
}
You need change Mongobee by Mongock if you use Springboot 2. The syntax is almost the same because the Mongock project is the continuation of the Mongobee project.
Springboot:
#Bean
public SpringBootMongock mongock(ApplicationContext springContext, MongoClient mongoClient) {
return (SpringBootMongock) new SpringBootMongockBuilder(mongoClient, "yourDbName", "com.package.to.be.scanned.for.changesets")
.setApplicationContext(springContext)
.setLockQuickConfig()
.build();
}
Spring:
#Bean
public SpringMongock mongock() {
MongoClient mongoclient = new MongoClient(new MongoClientURI("yourDbName", yourMongoClientBuilder));
return new SpringMongockBuilder(mongoclient, "yourDbName", "com.package.to.be.scanned.for.changesets")
.setLockQuickConfig()
.build();
}

Spring Boot - EnableAutoConfiguration with Exclude not working

I am using the latest spring boot version and I am trying to setup an application but I want to disable the DataSource configuration. My configuration class looks like this:
#Configuration
#ComponentScan
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class ApiApplicationConfig { }
but when I run the application, I am getting the following stacktrace:
Caused by: org.springframework.beans.factory.BeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath.
at org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.getDriverClassName(DataSourceProperties.java:137)
at org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$NonEmbeddedConfiguration.dataSource(DataSourceAutoConfiguration.java:116)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
... 31 more
Am I missing anything in my configuration to completely disable datasource configuration? I will be manually setting up a DataSource, so I dont want spring to handle this for me.
This seems to be a weird situation where DataSourceAutoConfiguration.NonEmbeddedDataSourceCondition finds a DataSource class loader, but no DataSource. We had this problem with spring-boot 1.2.2 while running an integration test.
Anyway, we ran gradle dependencies to find out what was pulling in tomcat-jdbc and ended up replacing our spring-boot-jdbc dependency with plain spring-jdbc. If you don't have tomcat-jdbc in your dependencies, it may help to set a breakpoint in DataSourceAutoConfiguration.NonEmbeddedDataSourceCondition.getDataSourceClassLoader() to find out what driver it finds.
When you manually configure your datasource, spring Boot will use your configuration and wouldn't try to initialize embedded datasource.
BTW, Spring boot by default uses these properties from application.properties to create datasource bean:
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
Take a look at this section of Spring Boot docs for more details about data source auto-configuration
The only thing that helped my exclusion problem was to exclude the tomcat jdbc dependency from the spring configuration:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
I had an issue when using #Configuration, #EnableAutoConfiguration and #ComponentScan while trying to exclude specific configuration classes, the thing is it didn't work!
Eventually I solved the problem by using #SpringBootApplication, which according to Spring documentation does the same functionality as the three above in one annotation.
#SpringBootApplication(exclude= {Foo.class})
public class MySpringConfiguration {}
#Configuration
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
By using this we can disable the spring boot embedded database configuration.
Its because when you disable the datasource config, spring boot uses in-memory database which is not present in your classpath. You have to add in-memory database dependency in your classpath -
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
This is the same issue occurs when you using #DataJpaTest for testing.

Error enabling SpringBeanAutowiringSupport within a JAX-WS web service

I am trying to enable Spring autowiring support in my webservice, following the lines of
public class MyService extends SpringBeanAutowiringSupport implements SomeInterface {
private Dao dao;
#Autowired
public void setDao(Dao dao) {
this.dao = dao;
}
With the MyService class annotated with
#WebService(endpointInterface = "SomeInterfacePath")
However, when I try and run this, I get a
java.lang.NoSuchMethodError: org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext()Lorg/springframework/web/context/WebApplicationContext;
at org.springframework.web.context.support.SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(SpringBeanAutowiringSupport.java:81)
at org.springframework.web.context.support.SpringBeanAutowiringSupport.<init>(SpringBeanAutowiringSupport.java:68)
error, which I haven't been able to find a resolution to. I'm using Spring 3.0 jars and apache-cxf. Spring autowiring works elsewhere in my project but doesn't seem to play nicely here. Any ideas as to what is going on? I have a a jaxws endpoint defined in my appConfig as
<jaxws:endpoint
id="myendpoint"
implementor="MyService"
address="/helloworld
/>
Until recently, Apache CXF pulled Spring 2.5.5 as a maven dependency.
However, CXF Version 2.3 and newer use Spring 3.
Apache CXF parent pom 2.2.1:
<spring.version>2.5.5</spring.version>
Apache CXF parent pom 2.3:
<spring.version>3.0.4.RELEASE</spring.version>
Both include a <dependencymanagement> section that ties Spring to the specified version.

Categories