Rouliboy
Rouliboy

Reputation: 1377

Injection of custom CDI scope in @ApplicationScoped bean of Batchlet

I have problems injecting a bean annotated with my own @JobScoped CDI Scope in an @ApplicationScoped bean of a Batchlet (Batch API).

I have defined the @JobScoped annotation :

@Documented
@Scope
@Target({ TYPE, METHOD, FIELD })
@Retention(RUNTIME)
public @interface JobScoped
{
}

I have registered my custom JobScopeContext through a CDI extension.

public class JobScopeExtension implements Extension
{
   public void registerJobScopeContext(@Observes final AfterBeanDiscovery p_event, final BeanManager p_beanManager)
   {
      p_event.addContext(new JobScopeContext(p_beanManager));
   }
}

And the JobScopeContext, implementing get methods of Context API to manage creation of my @JobScoped bean.

public class JobScopeContext implements Context {

    /**
     * {@inheritDoc}
     * 
     * @see javax.enterprise.context.spi.Context#get(javax.enterprise.context.spi.Contextual)
     */
    @Override
    public <T> T get(final Contextual<T> p_contextual) {
        // do stuff
    }

    /**
     * {@inheritDoc}
     * 
     * @see javax.enterprise.context.spi.Context#get(javax.enterprise.context.spi.Contextual,
     *      javax.enterprise.context.spi.CreationalContext)
     */
    @Override
    public <T> T get(final Contextual<T> p_contextual, final CreationalContext<T> p_creationalContext) {
        // do stuff
    }
}

I will not talk here about the way I manage the lifecycle of my @JobScoped beans as it does not matter for my problem.

I now defined my @JobScoped bean :

@JobScoped
public class MyBeanJobScopedImpl implements MyBeanJobScoped {

    @Override
    public String getId() {
        return "MyString";
    }

}

And an @ApplicationScoped bean which has the previous bean as a dependency :

@ApplicationScoped
public class MyBeanApplicationScoped {

    @Inject
    private MyBeanJobScoped m_beanJobScoped;

    public String callBeanJobScoped()
    {
        return m_beanJobScoped.getId();
    }

}

Here is now the behaviour I observes :

Use in JAX-RS resource

If I inject my MyBeanApplicationScoped bean in a JAX-RS resource :

@Path("custom")
public class RessourceREST {

    @Inject
    private MyBeanApplicationScoped m_beanApplicationScoped;

    @GET
    @Path("testApplicationScoped")
    public String test() {
        return m_beanApplicationScoped.callBeanJobScoped();
    }
}

Then every time I call the m_beanApplicationScoped.callBeanJobScoped() method, the Context#get(Contextual) and Context#get(Contextual, CreationalContext) method of my JobScopeContext class are called to resolve the injected bean. This is the normal behaviour.

Use in a Batchlet (does not work as expected)

Now if I inject my MyBeanApplicationScoped bean in a Batchlet :

@Named("MyBatchlet")
@Dependent
public class MyBatchlet extends AbstractBatchlet{

    @Inject
    private MyBeanApplicationScoped m_beanApplicationScoped;

    @Override
    public String process() throws Exception {
        // TODO Auto-generated method stub

        m_beanApplicationScoped.callBeanJobScoped();
        return "OK";
    }


}

The first time the Batchlet is called (launching the job which owns this Batchlet), the the Context#get(Contextual) and Context#get(Contextual, CreationalContext) method of my JobScopeContext class are called to resolve the injected bean.

But if I call once again the job, the get methods of Context are never called again. It's as if the @JobScoped bean was injected in the @ApplicationScoped bean as an @ApplicationScoped bean.

Am I missing something or is there something wrong with my implementation?

Thanks.

Upvotes: 0

Views: 948

Answers (1)

Rouliboy
Rouliboy

Reputation: 1377

I solved the problem replacing the @Scope annotation of my JobScoped scope by @NormalScope.

Upvotes: 0

Related Questions