Spring Cloud Gateway not starting when deployed as WAR showing webFluxConversionService error - spring

I'm trying to do a sample with Spring Cloud Gateway for JWT authentication and URL routing purpose.
All is running well when i run as a JAVA application or using Embedded Tomcat Container but when the same is deployed to a Tomcat server as a War, then i ge the below dependency injection error.
APPLICATION FAILED TO START
Description:
Parameter 4 of method routeDefinitionRouteLocator in org.springframework.cloud.gateway.config.GatewayAutoConfiguration required a bean of type 'org.springframework.core.convert.ConversionService' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Qualifier(value=webFluxConversionService)
Action:
Consider defining a bean of type 'org.springframework.core.convert.ConversionService' in your configuration.
I have tried adding jars related to spring web flux but the error did not go
my POM.XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gateway</groupId>
<artifactId>gateway</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<name>gateway</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-webflux -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web-reactive -->
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>mxgateway</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin> <artifactId>maven-war-plugin</artifactId>
<configuration> <outputDirectory>E:/apache-tomcat-9.0.22/webapps</outputDirectory>
</configuration> </plugin>
</plugins>
</build>
</project>
The gateway configuration is
package com.gateway.gateway;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder.Builder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.gateway.gateway.bean.ProgramRouteDetail;
import com.gateway.gateway.security.CustomGatewayFilter;
#SpringBootApplication
#Configuration
public class GatewayApplication extends SpringBootServletInitializer{
#Autowired
CustomGatewayFilter customGatewayFilter;
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
public List<ProgramRouteDetail> filterRequest(){
List<ProgramRouteDetail> programRouteDetails = new ArrayList<ProgramRouteDetail>();
for(int i =0;i<=2;i++){
ProgramRouteDetail detail = new ProgramRouteDetail();
detail.setDestUri("http://localhost:9090");
detail.setProgramId("users");
detail.setPath("/user/**");
programRouteDetails.add(detail);
}
return programRouteDetails;
}
#Override
protected SpringApplicationBuilder configure(
SpringApplicationBuilder builder) {
return builder.sources(GatewayApplication.class);
}
public RouteLocator constructRouteAndFilters(RouteLocatorBuilder builder ){
Builder routes = builder.routes();
List<ProgramRouteDetail> programRouteDetails = filterRequest();
for(ProgramRouteDetail programDetail : programRouteDetails){
routes.route(p -> p.path(programDetail.getPath()).filters(f->f.filter(customGatewayFilter)).uri(programDetail.getDestUri()));
}
return routes.build();
}
#Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder) {
return constructRouteAndFilters(builder);
}
}

Spring Cloud Gateway does not support WAR deployments. It is based on Spring Webflux and Spring Boot does not support war deployments of webflux.
From the documentation:
Because Spring WebFlux does not strictly depend on the Servlet API and
applications are deployed by default on an embedded Reactor Netty
server, War deployment is not supported for WebFlux applications.

Related

Springboot REST API returning 404 when deployed in Jboss EAP.7.1.0

I have created a simple Springboot REST api, which is working fine when deployed in Tomacat container but returning 404 message when deployed in Jboss EAP 7.1.0. Need help to resolve this problem.
Below are the classes i wrote along with pom.xml and application.properties
SpringRestApiApplication.java
package com.test.spring;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class SpringRestApiApplication{
public static void main(String[] args) {
SpringApplication.run(SpringRestApiApplication.class, args);
}
}
RestExample.java
package com.test.spring.web.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping(value = "/test")
public class RestExample {
#GetMapping(value = "/hello")
public String HelloWorldAPI() {
return "Hello World!";
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>SpringRestAPI</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>SpringRestAPI</name>
<description>Rest API Test Example</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>rest-api</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
server.servlet-path=/*
You are using 7.1.0 right. Remove this and try server.servlet-path=/*

Spring tool suite - console error - whitelabel Error page - access denied

Spring boot sample program with Mysql backend. very simple code. I checked application. properties, access to the DB etc. No clue why I am getting this error.
POM.XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.skb.course.apis</groupId>
<artifactId>library-apis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>library-apis</name>
<description>Project for developing Library APIs</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- JPA Data (We are going to use Repositories, Entiries, Hibernate, etc...) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- For MySQL Connector-J -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- For implementing API Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- For handling JWT related functionality-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.0</version>
</dependency>
<!-- Test related dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<!-- Used for Integration Tests. Spring's TestRestTemplate throws an error while sending PUT requests with
authorization error: java.net.HttpRetryException: cannot retry due to server authentication, in streaming mode
Therefore we need to use Apaches's HTTP client. Please refer:
https://stackoverflow.com/questions/16748969/java-net-httpretryexception-cannot-retry-due-to-server-authentication-in-stream
-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Console has no errors and tomcat is configured to run on 3000 port
application.properties file
Mysql db showing list of databaseds
Theere is data available in the PUBLISHER TABLE. but access denied error is thrown
Rest controller code
package com.skb.course.apis.libraryapis.publisher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.UUID;
#RestController
#RequestMapping(path = "/v1/publishers")
public class PublisherController {
private static Logger logger =
LoggerFactory.getLogger(PublisherController.class);
private PublisherService publisherService;
public PublisherController(PublisherService publisherService) {
this.publisherService = publisherService;
}
#GetMapping(path = "/{publisherId}")
public ResponseEntity<?> getPublisher(#PathVariable Integer publisherId,
#RequestHeader(value = "Trace-Id", defaultValue = "") String traceId)
throws LibraryResourceNotFoundException {
if (!LibraryApiUtils.doesStringValueExist(traceId)) {
traceId = UUID.randomUUID().toString();
}
return new ResponseEntity<>(publisherService.getPublisher(publisherId, traceId), HttpStatus.OK);
}
}

Application run failed spring boot aplication

I'm new in spring boot development. I created my first Spring Boot application and when i tried to run it as spring boot app i got this message.
Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class HelloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(HelloWorldApplication.class, args);
}
}
my configuration classe :
package com.example.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class AppConfiguration {
#RequestMapping("/hello")
public String hellow() {
return "hellow world";
}
}
my pom.xml look like:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>HelloWorld</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>HelloWorld</name>
<description>Hello World Project</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Is this a web application you are creating?
If not, try setting this property in your application.yml file:
spring:
main:
web-application-type: none
If so, you need to have a ServletWebServerFactory bean. One example:
MyConfiguration {
#Bean
ServletWebServerFactory servletWebServerFactory(){
return new TomcatServletWebServerFactory();
}
}
More info here.
Oh, and install maven.

Autowire not working with org.springframework.boot.autoconfigure.jms.artemis.ArtemisProperties

I'm trying to autowire the org.springframework.boot.autoconfigure.jms.artemis.ArtemisProperties in a library that is used in a SpringBoot application and I've got an error that the bean type cannot be found. During build time I have no issues.
The library were I would like to retrieve some values from the ArtemisProperties class.
The pom.xml from this library imports the artemis libraries.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xxx.ems.microservice.core</groupId>
<artifactId>core-library</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>CoreLibrary</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
<dependencies>
<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-test</artifactId>
<scope>test</scope>
<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-artemis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jms-server</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>co.elastic.apm</groupId>
<artifactId>apm-agent-api</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-manifests</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
</project>
Within the library I've got a class where I would like to have some values of the host where Artemis is trying to connect
package com.xxx.ems.microservice.core.queue;
import java.util.regex.PatternSyntaxException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jms.artemis.ArtemisProperties;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.stereotype.Component;
import com.xxx.ems.microservice.core.queue.MessageDispatcherConfiguration.DispatchInfo;
import co.elastic.apm.api.CaptureSpan;
import lombok.extern.slf4j.Slf4j;
// Message Dispatcher
#Component
#EnableJms
#Slf4j
public class MessageDispatcher {
#Autowired
MessageDispatcherConfiguration messageDispatcherConfiguration;
#Autowired
MessageSender messageSender;
#Autowired
private ArtemisProperties artemisProperties;
private void sendFile(DispatchInfo dispatcheInfo, MessageInformationExtractor messageInformationExtractorForDispatch, EMSFileMessage emsFileMessage, int ... priority) throws EMSQueueException{
if (hasToBeSend(dispatcheInfo, messageInformationExtractorForDispatch, emsFileMessage)){
for (String destinationQueue:dispatcheInfo.getDestinationQueueNames()){
log.debug("Will send {} to {}:{} and queue {}", emsFileMessage.getId(), artemisProperties.getHost(), artemisProperties.getPort(), destinationQueue);
messageSender.send(destinationQueue, emsFileMessage, priority);
} ;
}
}
....
In my spring-boot application pom.xml I'm including the dependency with the library and I am including the component scan for the classes within the library:
package com.xxx.ems.microservice.msdiskloader;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import com.xxx.ems.microservice.core.app.EMSMicroserviceApplication;
#SpringBootApplication
#ComponentScan("com.xxx.ems")
#Configuration
#EnableAsync
public class MSDiskLoaderApplication extends EMSMicroserviceApplication{
public static void main(String[] args) {
EMSMicroserviceApplication.run(MSDiskLoaderApplication.class, args);
}
}
Any clue why I have this autowired error? The dependency from the artemis libraries have been properly added. Might the any incompatibility with other libraries?
The full error is the following
**************************
APPLICATION FAILED TO START
***************************
Description:
Field artemisProperties in com.xxx.ems.microservice.core.queue.MessageDispatcher required a bean of type 'org.springframework.boot.autoconfigure.jms.artemis.ArtemisProperties' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'org.springframework.boot.autoconfigure.jms.artemis.ArtemisProperties' in your configuration.
Thanks
#ConfigurationProperties and auto-configurations are not public APIs so I would strongly suggest you not to use that in your own code. This bean is created by the auto-configuration, if your custom code makes it backs-off, it won't be created anymore.
#EnableConfigurationProperties(ArtemisProperties.class) is the best way to make sure it is registered in the context and bound to the environment.
First create a bean of ArtemisProperties and set properties in it and then you can autowired it.
#Bean
public ArtemisProperties artemisProperties () {
ArtemisProperties artemisObj = new ArtemisProperties();
return artemisObj;
}
#Autowired private ArtemisProperties artemis;
------------------------------------------------------------------------

Unable to Autowire an interface which extends CRUD repository

I am new to spring boot and trying to build a demo app. I would like to connect to a mysql DB using hibernate and fetch contents from a table. This is what my project structure looks like:
The class DemoApplication.java looks like this:
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
The HibernateTestController.java looks like this:
package com.example.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.example.repositories.PatchRepository;
#Controller
public class HibernateTestController {
#Autowired
PatchRepository patchRepository;
#RequestMapping(value={"/hibernateTest"})
public ModelAndView home() {
//List<Patch> patches = patchRepository.findAll();
return new ModelAndView("hibernateTest");
}
}
The PatchRepository.java looks like this:
package com.example.repositories;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.example.models.Patch;
#Repository
public interface PatchRepository extends CrudRepository<Patch, Long> {
List<Patch> findAll();
}
Now, whenever I start the application, I get an error saying:
*************************** APPLICATION FAILED TO START
Description:
Field patchRepository in
com.example.controllers.HibernateTestController required a bean of
type 'com.example.repositories.PatchRepository' that could not be
found.
Action:
Consider defining a bean of type
'com.example.repositories.PatchRepository' in your configuration.
I am not able to figure out why the Autowire for PatchRepository is not working. I think my project structure is right and that PatchRepository should automatically be detected by spring as a bean.
This is what the POM.xml looks like:
<?xml version="1.0" encoding="UTF-8"?>
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.1.1-1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons-core</artifactId>
<version>1.4.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.10.6.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
try using the repository scan in your DemoApplication class
#SpringBootApplication
#EnableJpaRepositories("com.example.repositories")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
lets try to add "#ComponentScan"
#SpringBootApplication
#ComponentScan("com.example")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Be sure that you have
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
and
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
into your pom.xml
Proper configs
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
And your Patch class is annotated with #Entity and have an Id Attribute annotated with #Id.
Everything should work.
I refactored my code as follows and things worked:
package com.example.repositories;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.example.models.Patch;
public interface PatchRepository extends CrudRepository<Patch, Long> {
List<Patch> findAll();
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.1.1-1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
spring.thymeleaf.cache: false
##DB connections##
spring.datasource.url=jdbc:mysql://localhost/testdb
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# Keep the connection alive if idle for a long time (needed in production)
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
# Hibernate Configuration
spring.jpa.hibernate.ddl-auto=update
packagesToScan=com.example
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql=false
hibernate.format_sql=true
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
entitymanager.packagesToScan=com.example
# Use spring.jpa.properties.* for Hibernate native properties (the prefix is
# stripped before adding them to the entity manager)
#logging.level.org.springframework.web=DEBUG
#logging.level.org.hibernate=DEBUG
package com.example.controllers;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.example.models.Patch;
import com.example.repositories.PatchRepository;
#Controller
public class HibernateTestController {
#Autowired
PatchRepository patchRepository;
#RequestMapping(value={"/hibernateTest"})
public ModelAndView home() {
List<Patch> patches = patchRepository.findAll();
return new ModelAndView("hibernateTest");
}
}
Application.properties looks like this:
spring.thymeleaf.cache: false
##DB connections## spring.datasource.url=jdbc:mysql://localhost/testdb spring.datasource.username=root spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# Keep the connection alive if idle for a long time (needed in production) spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
# Hibernate Configuration spring.jpa.hibernate.ddl-auto=update packagesToScan=com.example
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql=false hibernate.format_sql=true
# Naming strategy spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
entitymanager.packagesToScan=com.example
# Use spring.jpa.properties.* for Hibernate native properties (the prefix is
# stripped before adding them to the entity manager)
#logging.level.org.springframework.web=DEBUG
#logging.level.org.hibernate=DEBUG

Resources