Finding out what EJB view was used
Asked Answered
G

1

6

Assume I have an EJB defining two views:

  • Local business,
  • Remote business.

Both interfaces share the same method signatures, so it's like:

public interface MyBusinessCommon {
    void myMethod(Object o);
}

@Local
public interface MyBusinessLocal extends MyBusinessCommon { }

@Remote
public interface MyBusinessRemote extends MyBusinessCommon { }

@Stateless
public class MyBusinessBean implements MyBusinessLocal, MyBusinessRemote {
    public void myMethod(Object o) {
        // ...
    }
}

Is there a way to figure out what EJB view was called from within the EJB itself (or its interceptor?)

Let's say I would like to perform different authorization procedures depending on used view. Remote should be more constrained and local shouldn't.

I can invoke SessionContext#getInvokedBusinessInterface() but this gives me information only about the class object - not about EJB semantics of it. Plainly using reflection to check annotations presence on interfaces or bean is not enough (what about views defined in ejb-jar.xml?)

I doubt it is possible using straight EJB specification but perhaps there's something I missed.

If not, is it possible to get this information from the inners of an application server? (let's consider only JBoss AS 7.x, Glassfish 3.x and TomEE 1.5.1).

Girand answered 18/3, 2013 at 12:28 Comment(4)
My gut feeling says this is just not possible in a portable way. If it is, I missed something too. A trick might be to use the convention of naming interfaces. You are already doing that; MyBusinessLocal ends with Local etc. A bit brittle, but conventions do work for e.g. JavaBeans.Harter
Thanks Arjan. I agree - some convention might be a solution here. I guess such EJB view recognition might be only possible using server internals... If it's possible at all!Girand
You're welcome. If you feel strongly about EJB needing this ability, then why not add a feature request for it at java.net/jira/browse/EJB_SPEC ?Harter
In JBoss there's an Invocation object which has a promising isLocal() public method. But in an interceptor you have access to an InvocationContext not an Invocation. They are related somehow, but I don't know how. It would be useful to try to do an isLocal() on the InvocationContext and see if the underlying object was JBoss' Invocation object.Rubalcava
G
0

It's just like Arjan said - it is impossible to do just by following EJB spec.

However, in Glassfish it's quite simple to do.

All EJB interceptors accept the InvocationContext parameter. InvocationContext implementation in Glassfish is in fact com.sun.ejb.EjbInvocation class. It has the isLocal field that tolds you if it's intercepting local business call (or isRemote for remote business calls). You can use it e.g. as follows:

import com.sun.ejb.EjbInvocation;

import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;

@Interceptor
public class CallSourceAwareInterceptor {

    @AroundInvoke
    public Object aroundInvoke(InvocationContext ictx) throws Exception {
        boolean isLocalCall = isLocalEJBCall(ictx);

        return ictx.proceed();
    }

    boolean isLocalEJBCall(final InvocationContext ictx) {
        if (ictx instanceof EjbInvocation) {
            return ((EjbInvocation) ictx).isLocal;
        }
        else {
            throw new IllegalArgumentException("Unknown InvocationContext implementation.");
        }
    }
}

To access this EjbInvocation internal Glassfish class you need to add following maven dependency:

<dependency>
    <groupId>org.glassfish.main.ejb</groupId>
    <artifactId>ejb-container</artifactId>
    <version>4.0.1-b02</version>
    <scope>provided</scope>
</dependency>

And you might need to add following specific repository to get access to this artifact:

<repositories>
    <repository>
        <id>maven-promoted</id>
        <url>https://maven.java.net/content/groups/promoted/</url>
    </repository>
</repositories>

I did a quick research (based on Richard's suggestion regarding Invocation object) how to achieve the same in JBoss but couldn't find answer...

Girand answered 19/9, 2013 at 21:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.