Wednesday, July 30, 2008

Using EJBContext from an EJB 3 Interceptor

I got a question from a customer that he wants to use EJBContext from an EJB 3 Interceptor.

Yes, it’s very simple. Just inject the EJBContext into the interceptor using @Resource injection.

See the example code that uses methods of SessionContext as follows:


package actionbazaar.buslogic;

import javax.annotation.Resource;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class CheckPermissionInterceptor {
@Resource
private javax.ejb.SessionContext ctx;


@AroundInvoke
public Object checkUserRole(InvocationContext ic) throws Exception {
System.out.println("*** CheckPermission Interceptor invoked for "
+ ic.getTarget() + " ***");
if (!ctx.isCallerInRole("admin")) {
throw new SecurityException("User: '"
+ ctx.getCallerPrincipal().getName()
+ "' does not have permissions for method "
+ ic.getMethod());
}
return ic.proceed();
}
}

If you want the run-able version of the example code, you can download from http://manning.com/panda and look at Chapter 5 example.

6 comments:

Anonymous said...

Not Sure how you got this working. I am using weblogic 10 MP1.
When I deploy the application I get this error:
javax.naming.NameNotFoundException: remaining name: EJBContext
at weblogic.j2eeclient.SimpleContext.lookup(SimpleContext.java:49)
at weblogic.j2eeclient.SimpleContext.lookup(SimpleContext.java:59)
at weblogic.j2eeclient.SimpleContext.lookup(SimpleContext.java:64)
at weblogic.jndi.factories.java.ReadOnlyContextWrapper.lookup(ReadOnlyContextWrapper.java:45)
at weblogic.jndi.internal.AbstractURLContext.lookup(AbstractURLContext.java:130)
at javax.naming.InitialContext.lookup(InitialContext.java:351)
at com.bea.core.repackaged.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:124)
at com.bea.core.repackaged.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:86)
at com.bea.core.repackaged.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:122)
at com.bea.core.repackaged.springframework.jee.inject.DeploymentUnitMetadata.cacheInjectionValue(DeploymentUnitMetadata.java:118)
at com.bea.core.repackaged.springframework.jee.inject.DeploymentUnitMetadata.resolve(DeploymentUnitMetadata.java:133)
at com.bea.core.repackaged.springframework.jee.inject.Jsr250Metadata.resolve(Jsr250Metadata.java:271)
at com.bea.core.repackaged.springframework.jee.inject.Jsr250Metadata.applyInjections(Jsr250Metadata.java:230)
at com.bea.core.repackaged.springframework.jee.inject.Jsr250Metadata.inject(Jsr250Metadata.java:218)
at com.bea.core.repackaged.springframework.jee.inject.Jsr250Metadata.injectAndPostConstruct(Jsr250Metadata.java:249)
at com.bea.core.repackaged.springframework.jee.inject.Jsr250MetadataBeanPostProcessor.postProcessAfterInstantiation(Jsr250MetadataBeanPostProcessor.java:40)

Anonymous said...

I am using WLS 10 MP1 too and these injection resource is OK. Try defining a PersistenceContext in the intercepted class as next:

@Interceptors(TestFGAInterceptor.class)
@Stateless
@PersistenceContext(name="jdbc/testPersistenceContext")
public class TestInterceptedSession implements ITestInterceptedLocal {

public void interceptedMethod() { ....}

And the intercetor as next:

public class TestFGAInterceptor {

@Resource
private SessionContext sessionContext;

@AroundInvoke
public Object invokeMethod(InvocationContext invocationContext) throws Exception {

System.out.println("=====SessionContext==>" + sessionContext.toString());

Anonymous said...

Hello , i am also using weblogic 10 MP1 i am facing problems when i tried to recover the entityManager and execute a merge in a especific entity.

< Oct 22, 2008 2:47:18 PM BRT > < Error > < EJB > < BEA-010026 > < Exception occurred during commit of transaction ...

The transaction ocurrs in the Session Facade -> Business Method whose is wrapped by the interceptor.

Any hints for this case?

Tks

Debu Panda said...

Sorry this specific question was for OC4J and I did not test this piece of code in WebLogic.

Marcos Jara said...

Hello

I have an sales EJB project which controls the inventory, in and out of stock.

I want to add extra functionality to the EJB, such as payment and billing.

For this I want to use Interceptor in Session Bean class. I want to implement the new functionality as a component, decoupled from the current implementation.

But I have not access to the current session bean or Xml (ejb-jar), so I can not put the @ Interceptor in the class or method! how I can solve my problem?

Can I add @ Interceptor from another location, class or session? There is another way of doing?

Thanks for your help.

Philipp said...

Hmm it seems to me that @Resource injection is working with JEE5 style class Annotation @Interceptors(MyInterceptor.class). But with JEE6 style InterceptorBinding this does not work.. for now.. Tested on JBoss 6.1.x nightly build 20.7. ...Hope they get this working..

Can someone confirm this?