1

Having a Spring boot with Jersey, I want to use some filters which internally use dependency injection.

The problem is, that it seems the Jersey Server is not able to use the ApplicationContext of Spring, where we define that dependency.

Here the JerseyConfiguration

@Configuration
public class JerseyConfig extends ResourceConfig {

    private static final String CONTEXT_CONFIG = "contextConfig";

    private static final String RESOURCE_PACKAGE = "presentation.resource";

    public JerseyConfig() {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        applicationContext.refresh();
        property(CONTEXT_CONFIG, applicationContext);
        register(SpringLifecycleListener.class);
        register(MyFilter.class); //Filter I want to use 
        packages(RESOURCE_PACKAGE);
    }
}

Here the Filter that has an @Autowire

@Priority(40)
@Primary
@Provider
@MyFilter
class MyFilter(@Context var resourceInfo: ResourceInfo) extends ContainerRequestFilter with DefaultRuntime {

  implicit var finagleService: CommonFinagleService = _

  @Primary
  @Autowired(required = false)
  def setHttpFinagleService(@Autowired(required = false)
                            @Primary
                            _finagleService: CommonFinagleService): Unit = {
    finagleService = _finagleService
    finagleService.init(getProperties())
  }

  override def filter(context: ContainerRequestContext): Unit = {
    logger.debug(null, "filter running.....")
  }
}

This is how it looks the applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

    <bean id="httpFinagleService" class="foo.bla.CommonFinagleService"/>

</beans>

Finally the Spring boot main class

@Configuration
@SpringBootApplication(exclude = {org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration.class,
        org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration.class,
        org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration.class,
        org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration.class})
public class SpringBootRestApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {

        new SpringBootRestApplication().configure(new SpringApplicationBuilder(SpringBootRestApplication.class)).run(args);
    }

I run the main class, and the JerseyConfig class is invoked, and I´m able to register the filter. Unfortunately, once that the Service is running, when I run a request to one endpoint, the filter is invoked to the setHttpFinagleService method passing null dependency of CommonFinagleService

I'm also using jersey-spring4 dependency

<dependency>
            <groupId>org.glassfish.jersey.ext</groupId>
            <artifactId>jersey-spring4</artifactId>
            <version>2.27</version>
        </dependency>

And Spring boot and Spring is 2.1.0 and 5.1.8

Any idea what can be wrong here

With Grizzly + Jersey everything works just fine.

Regards

paul
  • 12,873
  • 23
  • 91
  • 153

1 Answers1

0

You need to make MyFilter picked by Spring as Bean,

Add to class level @Component and make sure it's picked up with component scan, if you have

Notice that @Provider may be redundant here if you use Spring DI

Community
  • 1
  • 1
Ori Marko
  • 56,308
  • 23
  • 131
  • 233
  • but then how I register in ResourceConfig?. Using same code with Grizzly + Jersey works, and is hk2 Dependecy Injection the one that Inject dependency. Here I think the problem is that spring-boot-starter-jersey is not doing DI properly. I will try to change Primary by Component anyway. – paul Nov 17 '19 at 12:14
  • MyFilter since is Jersey Filter cannot being instantiated by Spring boot DI, but by Jersey Spring + Hk2, since it has some internal dependencies that Spring does not know how to instantiateted. If I try the change you mention I receive the error: Parameter 0 of constructor in foo.bla. MyFilter required a bean of type 'javax.ws.rs.container.ResourceInfo' that could not be found. – paul Nov 17 '19 at 12:20