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