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.

7 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?

navya said...

Interesting Article

EJB 3 Online Training | Java Online Training

Java Online Training from India | Core Java Online Training