0

The key is that the @RestController class is from a 3rd party package that I can't touch. I want all the other classes in that package but not a particular @RestController because I want to replace those endpoints with my own.

It also seems this class is @Import'ed by another class that's also in the 3rd party package that I don't control (see Edit3 below)

It's similar to this question/answer, however in that question, OP has access to the @RestController and can append a @ConditionalOnExpression, whereas I cannot.

Is there another way to disable a @RestController in spring?

The specific @RestController class I want to disable is GraphQLController.

Edit1

Here are some ways I tried to exclude it but fails

@ConfigurationPropertiesScan("com.mycomp.package")
@SpringBootApplication(exclude = {graphql.kickstart.spring.webflux.GraphQLController.class})
public class Application {

  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}

The above attempt throws a

java.lang.IllegalStateException: The following classes could not be excluded because they are not auto-configuration classes: - graphql.kickstart.spring.webflux.GraphQLController

As suggested below, I also tried @ComponentScan.Filter of ASSIGNABLE_TYPE

@ConfigurationPropertiesScan("com.mycomp.package")
@ComponentScan(excludeFilters={
    @ComponentScan.Filter(type= FilterType.ASSIGNABLE_TYPE, value=graphql.kickstart.spring.webflux.GraphQLController.class)})
@SpringBootApplication
public class Application {
  ....
}

No errors but it's still instantiating the bean.

Also tried @ComponentScan.Filter of REGEX

@ConfigurationPropertiesScan("com.mycomp.package")
@ComponentScan(excludeFilters={
    @ComponentScan.Filter(type= FilterType.REGEX, pattern = "graphql.kickstart.spring.webflux.GraphQLController")})
@SpringBootApplication
public class Application {
  ....
}

That didn't seem to work either

Also tried @ComponentScan.Filter of CUSTOM

@ConfigurationPropertiesScan("com.mycomp.package")
@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.CUSTOM,
    classes = GraphQLControllerBeanFilter.class))
@SpringBootApplication
public class Application {
  ....
}

public class GraphQLControllerBeanFilter implements TypeFilter {

  @Override
  public boolean match(MetadataReader metadataReader,
      MetadataReaderFactory metadataReaderFactory) {
    ClassMetadata classMetadata = metadataReader.getClassMetadata();
    String fullyQualifiedName = classMetadata.getClassName();
    return fullyQualifiedName.equals("graphql.kickstart.spring.webflux.GraphQLController");    
  }
}

The custom filter doesn't seem to ever see the GraphQLController. In fact, I printed out all the fullyQualifiedName it scans and only the ones in my com.mycomp.package package show. Nothing from 3rd party libraries even though it's loading them.

I'm wondering if the @ComponentScan.Filter ever sees 3rd party packages or if maybe I have some other spring setting overriding it.

I also tried adding @Primary to my Controller

@Primary
@RestController
public class MyGraphQLController extends graphql.kickstart.spring.webflux.GraphQLController

But that results in this error

java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'graphql.kickstart.spring.webflux.GraphQLController'

Edit2

This is the 3rd party library that contains the @RestController I'm trying to exclude

implementation "com.graphql-java-kickstart:graphql-kickstart-spring-boot-starter-webflux:11.0.0"

Edit3

It looks like graphql.kickstart.spring.webflux.boot.GraphQLSpringWebfluxAutoConfiguration is importing the GraphQLController in an @Import annotation.

Is there anyway to disable or replace it in this case?

kane
  • 5,465
  • 6
  • 44
  • 72
  • 1
    Can you provide setup to enable `GraphQLController`? I can disable a Controller created in local using `@ComponentScan.Filter`. – samabcde May 16 '21 at 09:49
  • I provided the package coordinates that enables `GraphQLController` in **Edit2**. – kane May 16 '21 at 15:03
  • You can use spring securty to block access to certain paths – Antoniossss May 16 '21 at 15:17
  • @Antoniossss That's an interesting idea. It would not be ideal for me in this case because the path is determined by `GraphQLController`'s parent class `AbstractGraphQLController` and I actually want to inject my own implementation of `GraphQLController`. So I don't want to block the endpoint, I want to replace the implementation – kane May 16 '21 at 15:24
  • I think you can override `GraphQLController` by implementing your own class and add `@Primary` to it. – Grigorii Riabov May 17 '21 at 05:30
  • I don't see `GraphQLController` bean by adding the dependency stated. I check with following method. @Bean public CommandLineRunner commandLineRunner(ApplicationContext ctx) { return args -> { System.out.println("Let's inspect the beans provided by Spring Boot:"); String[] beanNames = ctx.getBeanDefinitionNames(); for (String beanName : beanNames) { System.out.println(beanName); } }; } – samabcde May 17 '21 at 13:41
  • @GrigoriiRiabov I tried `@Primary` but something is still trying to map the original bean because I get an `java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'graphql.kickstart.spring.webflux.GraphQLController' method ` – kane May 17 '21 at 16:58
  • @kane, can you attach the code of the class that overrides `GraphQLController`? – Grigorii Riabov May 18 '21 at 06:27
  • @GrigoriiRiabov I added my code that overrides `GraphQLController` in the post – kane May 18 '21 at 15:43
  • I also found out that `GraphQLSpringWebfluxAutoConfiguration` explicitly @Imports the `GraphQLController`. Maybe that's why the suggested strategies aren't working – kane May 18 '21 at 15:45
  • @kane try to extend to `AbstractGraphQLController` like this code: `@Primary @RestController public class MyGraphQLController extends AbstractGraphQLController`. You can try my [repo](https://github.com/GrinRus/graph-ql-demo) and check in spring actuator only one bean `MyGraphQLController` – Grigorii Riabov May 19 '21 at 06:59

0 Answers0