I am working through a tutorial creating a eureka server and eureka client. Prior to adding the feign client, the eureka client is able to register with the eureka server. After I added the feign maven dependency and created the annotations in the PriceServiceApplication.java and PriceClient.java, I seem to be be getting an "Caused by: java.lang.IllegalStateException: Only single-level inheritance supported: PriceClient". This is a multimodule SpringBoot application project, containing both eureka client (price service) and eureka server. I am using Spring Data Rest with the price service microservice ensuring I could afford not to add the controller and service class. I will add the full errors and code snippet below. Thanks in advance for your help. I will appreciate any advice how to get rid of this error and get the code to work.
2023-04-04 15:29:04.693 ERROR 12212 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'pricingServiceApplication': Unsatisfied dependency expressed through field 'priceRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.udacity.pricing.domain.price.PriceClient': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: Only single-level inheritance supported: PriceClient
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:843) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142) ~[spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) ~[spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) ~[spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) ~[spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) ~[spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at com.udacity.pricing.PricingServiceApplication.main(PricingServiceApplication.java:32) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.1.5.RELEASE.jar:2.1.5.RELEASE]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.udacity.pricing.domain.price.PriceClient': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: Only single-level inheritance supported: PriceClient
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:178) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:101) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1674) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getObjectForBeanInstance(AbstractAutowireCapableBeanFactory.java:1249) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:257) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:277) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1471) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1428) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1211) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1168) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
... 24 common frames omitted
Caused by: java.lang.IllegalStateException: Only single-level inheritance supported: PriceClient
at feign.Util.checkState(Util.java:127) ~[feign-core-10.1.0.jar:na]
at feign.Contract$BaseContract.parseAndValidatateMetadata(Contract.java:55) ~[feign-core-10.1.0.jar:na]
at feign.ReflectiveFeign$ParseHandlersByName.apply(ReflectiveFeign.java:154) ~[feign-core-10.1.0.jar:na]
at feign.ReflectiveFeign.newInstance(ReflectiveFeign.java:52) ~[feign-core-10.1.0.jar:na]
at feign.Feign$Builder.target(Feign.java:251) ~[feign-core-10.1.0.jar:na]
at org.springframework.cloud.openfeign.HystrixTargeter.target(HystrixTargeter.java:37) ~[spring-cloud-openfeign-core-2.1.0.RELEASE.jar:2.1.0.RELEASE]
at org.springframework.cloud.openfeign.FeignClientFactoryBean.getTarget(FeignClientFactoryBean.java:271) ~[spring-cloud-openfeign-core-2.1.0.RELEASE.jar:2.1.0.RELEASE]
at org.springframework.cloud.openfeign.FeignClientFactoryBean.getObject(FeignClientFactoryBean.java:235) ~[spring-cloud-openfeign-core-2.1.0.RELEASE.jar:2.1.0.RELEASE]
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:171) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
... 35 common frames omitted
Process finished with exit code 1
PricingServiceApplication.java
@EnableDiscoveryClient
@EnableFeignClients
public class PricingServiceApplication implements CommandLineRunner{
@Autowired
PriceRepository priceRepository;
public static void main(String[] args) {
SpringApplication.run(PricingServiceApplication.class, args);
}
/**
* Gets a random price to fill in for a given vehicle ID.
* @return random price for a vehicle
*/
private static BigDecimal randomPrice() {
return new BigDecimal(ThreadLocalRandom.current().nextDouble(1, 5))
.multiply(new BigDecimal(5000d)).setScale(2, RoundingMode.HALF_UP);
}
@Override
public void run(String... args) throws Exception {
/**
* Holds {ID: Price} pairings (current implementation allows for 20 vehicles)
*/
final Map<Long, Price> PRICES = LongStream
.range(1, 20)
.mapToObj(i -> new Price("USD", randomPrice(), i))
.collect(Collectors.toMap(Price::getVehicleId, p -> p));
for (Map.Entry<Long, Price> entry : PRICES.entrySet())
{
System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
}
priceRepository.saveAll(PRICES.values());
}
}
PriceRepository.java
@RepositoryRestResource(collectionResourceRel = "vehicle-price", path = "vehicle-price")
public interface PriceRepository extends CrudRepository<Price, Long> {
@RequestMapping(method = RequestMethod.GET, value = "/prices/{vehicleId}")
List<Price> findPriceByVehicleId(@Param("vehicleId") Long vehicleId);
}
PriceClient.java
@FeignClient(name="pricing-service", url = "pricing-service")
public interface PriceClient extends PriceRepository{
}
pom.xml
<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.5.RELEASE</version>
<relativePath/>
<!-- lookup parent from com.udacity.pricing.repository -->
</parent>
<groupId>com.udacity</groupId>
<artifactId>pricing-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>pricing-service</name>
<description>Pricing Service</description>
<properties>
<java.version>11</java.version>
</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-web</artifactId>
</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>
<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-rest</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-core -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.11</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</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>
<repositories>
<repository>
<id>netflix-candidates</id>
<name>Netflix Candidates</name>
<url>https://artifactory-oss.prod.netflix.net/artifactory/maven-oss-candidates</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
application.properties
server.port=8082
#configure base path for rest apis
spring.data.rest.base-path=/api/v1/services
#h2
#spring.h2.console.enabled=true
#spring.h2.console.path=/h2
#spring.datasource.url=jdbc:h2:mem:pricedata
#
#spring.datasource.driverClassName=org.h2.Driver
#spring.datasource.username=sa
#spring.datasource.password=password
#spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
#Eureka
spring.application.name=pricing-service
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
eureka.client.service-url.default-zone=http://localhost:8761/eureka/
instance.preferIpAddress=true
eureka.client.enabled=true
spring.cloud.config.enabled=false
eureka.instance.hostname=localhost
spring.cloud.loadbalancer.ribbon.enable=false
Spring Cloud Feign does not support inheritance of more than one level. In the feign client classes, you are inheriting from some repository that itself inherits from CrudRepository, not to mention that CrudRepostory itself inherits from the Repository interface!
So basically you are using Feign the wrong way. You should create the abstract methods inside the Feign Client classes, and enable HyperMediaSupport in your application, so that it can parse HATEOAS-enabled JSON generated by Spring Data Rest.
Note that the feign client classes can inherit from other classes or interfaces, only if those classes or interfaces do not have parents.
This link might be of help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With