Search code examples
javaejb

Class name of an EJB


I have some code along the lines of this:

@EJB
protected SomeService service;

// Somewhere in a method
service.getClass().getSimpleName();

What I was looking for was the name of the EJB class, which in this case should have been something along the lines of SomeServiceBean. What I get instead, however, is for example $Proxy2128.

Is there a way I can get the name of the actual EJB class that I implemented, instead of the proxy class?

Think we're using ejb 3.0 with geronimo or something like that.


Solution

  • It's probably not a good idea to do this. I suspect you are better off doing something like adding a method to the bean which returns a type string that is under your control. The simplest such implementation

    public String getSimpleClassName() {
        return getClass().getSimpleName();
    }
    

    That is safe in the face proxying. It is not safe in the face of dynamic subclassing, but i don't know of any EJB implementations that do that (although there are certainly JPA implementations which do that).

    A slightly more complicated, but fundamentally more straightforward, implementation would be to define:

    public abstract String getSimpleClassName();
    

    in a base class (or interface), and then writing:

    public String getSimpleClassName() {
        return SomeService.class.getSimpleName();
    }
    

    In SomeService. That is cast-iron guaranteed to work.

    Alternatively, if you are working with no-interface views, and don't mind reflection, and the risk of your system bursting into flames at any moment, then in the calling code, you can do:

    private String findBeanClassName(Object beanRef) {
        return findBeanClass(beanRef).getSimpleName();
    }
    
    private Class<?> findBeanClass(Object beanRef) {
        return findAncestorWithAnnotation(beanRef.getClass(), Stateless.class);
    }
    
    private Class<?> findAncestorWithAnnotation(Class<?> cl, Class<? extends Annotation> annotation) {
        while ((cl != null) && !cl.isAnnotationPresent(annotation)) {
            cl = cl.getSuperclass();
        }
        return cl;
    }
    

    That ought to work. Obviously, you'd need to use a different annotation class if you are using a stateful bean.