Home » Java » Enterprise Java » Simulating CDI’s Session and Request Scope in a J2SE app

About Dan Haywood

Simulating CDI’s Session and Request Scope in a J2SE app

We’re currently considering refactoring the Naked Objects framework to use JSR-330 (dependency injection) and EE-oriented big brother, JSR-299 (CDI). Using vanilla JSR-330 is a no-brainer, but there are also some nice features in JSR-299 that we’d like to exploit (such as events and decorators). The snag? The Naked Objects must also run transparently in J2SE environments.

Now JSR-299 (at least, the Weld reference implementation) can run on J2SE, but it isn’t possible to use beans that are annotated as either @SessionScoped or @RequestScoped… not surprising really, because there is no HttpSession or HttpServletRequest to hook into. On the other hand, at least in the Naked Objects framework in a J2SE context, we do have the ability to map these concepts onto its own internal lifecycle … eg, for a client-side app, the user is always in deemed to be running in one long session.

How, then, to setup contexts for these scopes, and make them automatically active when running in J2SE?

First, let’s look at the code we want to run:

package org.nakedobjects.experiments.cdi;

import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.event.Observes;
import org.jboss.weld.environment.se.bindings.Parameters;
import org.jboss.weld.environment.se.events.ContainerInitialized;

@RequestScoped
public class HelloWorld {
    public static void main(String[] args) {
        // bootstrap
        org.jboss.weld.environment.se.StartMain.main(new String[]{"JSR","299"});
    }
    public void printHello(@Observes ContainerInitialized event, @Parameters List<String> args) {
        System.out.println("Hello " + args);
        System.out.flush();
    }
}

Because this is a CDI bean, we need an empty META-INF/beans.xml.

The above class would print out “Hello [JSR, 299]” if annotated as @ApplicationScoped, but not with it being annotated as @RequestScoped. What we therefore need to do is write an extension. It’s a bit hacky, but it works:

package org.jboss.weld.manager; // required for visibility to BeanManagerImpl#getContexts()

import java.lang.annotation.Annotation;

import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AfterDeploymentValidation;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.Extension;

import org.jboss.weld.context.AbstractThreadLocalMapContext;
import org.jboss.weld.context.beanstore.HashMapBeanStore;

public class WeldServletScopesSupportForSe implements Extension {

 public void afterDeployment(@Observes AfterDeploymentValidation event,
   BeanManager beanManager) {

  setContextActive(beanManager, SessionScoped.class);
  setContextActive(beanManager, RequestScoped.class);
 }

 private void setContextActive(BeanManager beanManager,
   Class<? extends Annotation> cls) {
  BeanManagerImpl beanManagerImpl = (BeanManagerImpl) beanManager;
  AbstractThreadLocalMapContext context = (AbstractThreadLocalMapContext) beanManagerImpl
    .getContexts().get(cls).get(0);
  context.setBeanStore(new HashMapBeanStore());
  context.setActive(true);
 }
}

Like all Weld extensions, this needs to be registered in META-INF/services, in this case in a file called javax.enterprise.inject.spi.Extension containing the fully-qualified class name.

Now, when we run the application, the session and request scopes will both be set up, and our HelloWorld bean will fire.

For developers writing apps in Naked Objects they will need to include a dependency to an additional module, if deploying a client (-t client or a server on a non-web backend (-t server with socket-level remoting, say). For the latter, we’ll need to include some smarts to figure out whether we are running in a webapp or not, and only set up the Contexts if we determine that we’re not (eg can’t find javax.servlet classes on the classpath.

If you want to try out the code, you can check it out using

svn co https://nakedobjects.svn.sourceforge.net/svnroot/nakedobjects/framework/trunk/experiments .

Reference: Simulating CDI’s Session and Request Scope in a J2SE app from our JCG partner Dan Haywood at the Dan Haywood blog.

Related Articles :

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

and many more ....

 

Leave a Reply

Your email address will not be published. Required fields are marked *

*


two × 2 =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Do you want to know how to develop your skillset and become a ...

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!
Get ready to Rock!
To download the books, please verify your email address by following the instructions found on the email we just sent you.

THANK YOU!

Close