Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FeignClient support for multiple inheritance #1029

Closed
vishwanathpatil2193 opened this issue Aug 1, 2019 · 2 comments
Closed

FeignClient support for multiple inheritance #1029

vishwanathpatil2193 opened this issue Aug 1, 2019 · 2 comments
Labels
invalid spring-cloud Issues related to Spring Cloud OpenFeign

Comments

@vishwanathpatil2193
Copy link

vishwanathpatil2193 commented Aug 1, 2019

Hi Guys, I had to support two URI's in my project. For this, I made something like this:

preface:

  1. FeignClient used is of "org.springframework.cloud.netflix.feign.FeignClient",
  2. Name of the two feign clients are different
public interface A extends ThirdPartyContract{
@RequestMapping(path="something", and other parameters)
public <type> someMethod(){
}
}

@ConditionalOnProperty(name="someProperty",havingValue="false", matchIfMissing=true)
@FeignClient(name="SomeName", url="SomeUrl", configuration={Config.class})
public interface Aa extends A{
}

@ConditionalOnProperty(name="someProperty",havingValue="true", matchIfMissing=false)
@FeignClient(name="SomeName-abc", url="SomeUrl", configuration={Config.class, ConfigSomeOtherType.class})
public interface Bb extends A{
}

Also,
It worked perfectly fine when I ran in my local workstation but failed in the staging Environment.

**The reason it said was:

Caused by: java.lang.IllegalStateException: Only single-level inheritance supported: Bb
     at feign.Util.checkState(Util.java:128)
     at feign.Contract$BaseContract.parseAndValidatateMetadata(Contract.java:53)**

I debugged in my local workstation using the stacktrace given above and found that for --Only single-level inheritance supported -- to happen, this condition--**if

(targetType.getInterfaces().length == 1) {
        checkState(targetType.getInterfaces()[0].getInterfaces().length == 0,
                   "Only single-level inheritance supported: %s",
                   targetType.getSimpleName());
      }

-- should be false. When this happens, the above exception is thrown. However, I did not face this in my local system but in staging Environment.

** question**
In any time, the code above should provide only one the beans and should work as expected, right?

@kdavisk6
Copy link
Member

kdavisk6 commented Aug 5, 2019

@vishwanathpatil2193

Your issue not with Feign but your Spring Bean autoconfiguration. Your configuration will result in both Beans Aa and Bb being created due to your conflicting @ConditionalOnProperty annotations. I recommend you reduce your configuration to just one client get that working first before applying the autoconfiguration.

Since this is not a Feign issue, but a Spring Issue, I recommend that you reach out to folks there or on StackOverflow for more help.

@kdavisk6 kdavisk6 closed this as completed Aug 5, 2019
@kdavisk6 kdavisk6 added invalid spring-cloud Issues related to Spring Cloud OpenFeign labels Aug 5, 2019
@silkentrance
Copy link
Contributor

silkentrance commented Oct 6, 2020

@kdavisk6 The problem stems from interface A extending yet another interface ThirdPartyContract and is not because of some malformed spring configuration.

I have the same situation here, where I have multiple base service interfaces, e.g. one for a single object retrieve operation and one for a bulk retrieve operation, one for a single object create operation and one for a bulk update operation and so on.

I then tried to assemble my client / service base interfaces as such

interface FooService extends BulkRetrieveService<ModelClass>, CreateService<ModelClass>, DeleteService<String> {
}

with the actual client and service then implementing / extending the interface

public class FooWebService implements FooService { ... }

@FeignClient(...)
public interface FooWebClient extends FooService { ... }

The reason for that is that I would like to further decompose my standard tests that need to be reused across multiple different modules.

Why would I have to instead use

public class FooWebService implements BulkRetrieveService<ModelClass>, CreateService<ModelClass>, DeleteService<String> { ... }

@FeignClient(...)
public interface FooWebClient extends BulkRetrieveService<ModelClass>, CreateService<ModelClass>, DeleteService<String> { ... }

Dunno if the latter (FeignClient declaration) is possible, though.

Regardless, in my case, the shared service interface and also the base interfaces that it is composed of, do not declare any request mappings and more or less act as marker interfaces with additional method declarations.
So I have to override these methods In both the web service implementation class and also the feign client interface.

Perhaps the check should be extended so as to prevent multiple inheritance from interfaces that do have request mapping annotations on their methods? and if no such annotated methods exist, then the check would succeed.

I will look at the code and propose a PR to you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid spring-cloud Issues related to Spring Cloud OpenFeign
Projects
None yet
Development

No branches or pull requests

3 participants