spring feign with hateos - spring-boot

I am understand more on spring boot with cloud.
It was all fine when I did not not feign dependency to pom.xml. Till then app boot started failing with initially, RelProvider cannot be null! and when I provided linkRelProvider to the depedency. it has not started failing on MessageResolver
exception:
Caused by: java.lang.IllegalArgumentException: MessageResolver must not be null!
at org.springframework.util.Assert.notNull(Assert.java:198) ~[spring-core-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.hateoas.mediatype.hal.Jackson2HalModule$HalLinkListSerializer.<init>(Jackson2HalModule.java:131) ~[spring-hateoas-1.0.3.RELEASE.jar:1.0.3.RELEASE]
at org.springframework.hateoas.mediatype.hal.Jackson2HalModule$HalLinkListSerializer.<init>(Jackson2HalModule.java:121) ~[spring-hateoas-1.0.3.RELEASE.jar:1.0.3.RELEASE]
at org.springframework.hateoas.mediatype.hal.Jackson2HalModule$HalHandlerInstantiator.<init>(Jackson2HalModule.java:753) ~[spring-hateoas-1.0.3.RELEASE.jar:1.0.3.RELEASE]
at org.springframework.hateoas.mediatype.hal.Jackson2HalModule$HalHandlerInstantiator.<init>(Jackson2HalModule.java:738) ~[spring-hateoas-1.0.3.RELEASE.jar:1.0.3.RELEASE]
at org.springframework.hateoas.mediatype.hal.Jackson2HalModule$HalHandlerInstantiator.<init>(Jackson2HalModule.java:722) ~[spring-hateoas-1.0.3.RELEASE.jar:1.0.3.RELEASE]
at org.springframework.cloud.openfeign.hateoas.FeignHalAutoConfiguration.halJacksonHttpMessageConverter(FeignHalAutoConfiguration.java:80) ~[spring-cloud-openfeign-core-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_231]
FeignHalAutoConfiguration sets-up the required dependency which also needs message resolver, which I am struggling to figure out.
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.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.test.spring</groupId>
<artifactId>spring-examples</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-examples</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency> -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- <dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-hal-browser</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
</exclusion>
</exclusions>
</dependency> -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</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>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
appConfig.java
package com.test.spring.springexamples;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.hateoas.client.LinkDiscoverer;
import org.springframework.hateoas.client.LinkDiscoverers;
import org.springframework.hateoas.mediatype.collectionjson.CollectionJsonLinkDiscoverer;
import org.springframework.hateoas.server.LinkRelationProvider;
import org.springframework.hateoas.server.core.AnnotationLinkRelationProvider;
import org.springframework.plugin.core.SimplePluginRegistry;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#Configuration
#EnableSwagger2
public class AppConfig {
#Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("message");
return messageSource;
}
#Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2);
}
#Bean
public LinkDiscoverers discoverers() {
List<LinkDiscoverer> plugins = new ArrayList<>();
plugins.add(new CollectionJsonLinkDiscoverer());
return new LinkDiscoverers(SimplePluginRegistry.create(plugins));
}
#Bean
public LinkRelationProvider linkRelationProvider() {
return new AnnotationLinkRelationProvider();
}
}
Please advise what I am doing wrong here.

If you add debug=true to application.properties you will see in your report
HypermediaAutoConfiguration.HypermediaConfiguration:
Did not match:
- #ConditionalOnMissingBean (types: org.springframework.hateoas.client.LinkDiscoverers; SearchStrategy: all) found beans of type 'org.springframework.hateoas.client.LinkDiscoverers' discoverers (OnBeanCondition)
Matched:
- #ConditionalOnClass found required class 'com.fasterxml.jackson.databind.ObjectMapper' (OnClassCondition)
The HypermediaConfiguration backs off because of your custom LinkDiscoverers bean.
Either remove that bean definition or add
#EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL)
On you application class.

Related

My rest controller is not get called from URL

My Rest Controller is not getting called. Can you kindly guide me?
I have created an API for bus reservation scenario for that my controller is not getting called.
Is there any issue in configuration?
I have tried by using following URL:
http://localhost:9090/service/api/bus/enter link description here
debug breakpoint is also not coming.
import org.slf4j.Logger;
import java.sql.Date;
import java.util.List;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.ApiOperation;
#RestController
#RequestMapping(value = "/service")
public class ServiceController {
#Autowired
private ComponentDetailsService busService;
#ApiOperation("This is the hello world api")
#GetMapping("/api/bus/")
public String hello() {
ComponentDetailsEntity bus = new ComponentDetailsEntity();
bus.setArrivalTime("10");
bus.setBusNumber("TN11");
bus.setDepature("salem");
bus.setDestinationCity("chennai");
bus.setDuration("5");
bus.setOperatorName("bala");
bus.setPrice(350);
bus.setReturnDate(Date.valueOf("2020-5-4"));
bus.setSourceCity("Salem");
bus.setTravelDate(Date.valueOf("2020-5-3"));
busService.postBus(bus);
System.out.println("a");
return "hello";
}
#GetMapping("/api/bus/{sourceCity}/{destinationCity}/{travelDate}")
public List<ComponentDetailsEntity> findAll(#PathVariable("sourceCity") String sourceCity, #PathVariable("destinationCity") String destinationCity,
#PathVariable("travelDate") String strdate) {
Date date = Date.valueOf(strdate);
return busService.findAll(sourceCity,destinationCity,date);
}
}
server.port=9090
spring.datasource.url=jdbc:h2:mem:db
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=h2
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.h2.console.enabled=true
<?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.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.codejudge</groupId>
<artifactId>sb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sb</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<swagger.version>2.4.0</swagger.version>
</properties>
<dependencies>
<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>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springf
ramework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
</dependencies>
<build>
<finalName>spring-boot-in-docker</finalName>
<plugins>
<!-- This is needed if deploying with embedded server -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Please check your console output, e.g. if there is any exception in your service class. The code you provided does work and generates the output "hello".

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;
------------------------------------------------------------------------

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

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.

spring eclipselink static weaving was not enabled or did not occur

Project uses:
spring boot 2.1.1
oracle 12 database
eclipselink 2.6.5
maven 3.6.0
in this project we are using a provided jar with the entities and we created the configuration withouth persistence.xml. The project is created as a war to be deployed in weblogic 12c server but we are testing with springboot inbuilt tomcat server. And ocasionaly on a test server with Weblogic.
When we launch the application in either container we get a lot of EL warnings like the following one:
[EL Warning]: metadata: 2019-02-28 17:10:14.684--ServerSession(1764986459)--Reverting the lazy setting on the OneToOne or ManyToOne attribute [readonlyUserInformation] for the entity class [class com.adquira.mkp.persistence.entities.auditory.AuditoryEvent] since weaving was not enabled or did not occur.
after searching and looking everywhere how to solve this the only similar question we found was this question about static weaving not working in springboot
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.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.adus</groupId>
<artifactId>adus-backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>adus-backend</name>
<description>Adus back-end development</description>
<properties>
<java.version>1.8</java.version>
<springfox-swagger.version>2.9.2</springfox-swagger.version>
<eclipselink.version>2.6.5</eclipselink.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</exclusion>
<exclusion>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</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-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.adquira.orm</groupId>
<artifactId>adquira-orm</artifactId>
<version>1.0.20</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox-swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox-swagger.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>${eclipselink.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.core</artifactId>
<version>${eclipselink.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>${eclipselink.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
The class for configuration
package com.adus.adusbackend;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect;
import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
#Configuration
#EnableJpaRepositories(basePackages = { "com.adus.adusbackend.repository.user","com.adus.adusbackend.repository.market"})
public class DatasourceConfiguration {
#Bean(destroyMethod = "close")
#ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
#Bean
EclipseLinkJpaVendorAdapter jpaVendorAdapter() {
EclipseLinkJpaVendorAdapter jpaVendorAdapter = new EclipseLinkJpaVendorAdapter();
jpaVendorAdapter.setDatabasePlatform("org.eclipse.persistence.platform.database.oracle.Oracle12Platform");
jpaVendorAdapter.setGenerateDdl(Boolean.FALSE);
jpaVendorAdapter.setShowSql(Boolean.TRUE);
return jpaVendorAdapter;
}
#Bean
LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter());
entityManagerFactoryBean.setJpaDialect(new EclipseLinkJpaDialect());
// Instead of persistence.xml
entityManagerFactoryBean.setPersistenceUnitName("des");
entityManagerFactoryBean.setPackagesToScan("com.adquira.mkp.persistence.entities");
Properties jpaProperties = new Properties();
jpaProperties.put(PersistenceUnitProperties.WEAVING, detectWeavingMode());
jpaProperties.put(PersistenceUnitProperties.DDL_GENERATION, "none");
entityManagerFactoryBean.setJpaProperties(jpaProperties);
entityManagerFactoryBean.afterPropertiesSet();
return entityManagerFactoryBean;
}
#Bean
JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
private String detectWeavingMode() {
return InstrumentationLoadTimeWeaver.isInstrumentationAvailable() ? "true" : "static";
}
}
You have two challenges.
Firstly: to have static weaving to happen at all and entities enhanced you need a properly configured maven plugin to do that. You need to add weaver plugin to your plugin section. Example from Eclipselink Wiki-page:
<plugins>
...
<plugin>
<groupId>de.empulse.eclipselink</groupId>
<artifactId>staticweave-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>weave</goal>
</goals>
<configuration>
<persistenceXMLLocation>
META-INF/persistence.xml</persistenceXMLLocation>
<logLevel>FINE</logLevel>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>${eclipselink.version}</version>
</dependency>
</dependencies>
</plugin>
...
</plugins>
Secondly: you need to make plugin aware the classes in external jar. There were quite few articles about that and I am not sure if it is even possible (easily). The wiki page mentions only about sources to weave which can be in a jar but does not directly say if it is possible also for compiled classes.
For this reason I have always made my entity library jars readily enhanced when compiled from source. But anyway there are some related posts like this.

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