使用通用接口时不会调用EJB拦截器

时间:2011-03-17 10:36:40

标签: java generics java-ee glassfish-3 interceptor

给出以下代码

public interface Foo<T> {
    T get();
}

@Remote
public interface Bar extends Foo<String> {
}

@Stateless
public class BarImpl implements Bar {
    @Interceptors(ExceptionInterceptor.class)
    public String get() {
        throw new RuntimeException("not implemented");
    }
}

public class ExceptionInterceptor {
    @AroundInvoke
    public Object convertExceptionForExternalSystem(InvocationContext ctx) throws RuntimeException, Error {
        try
        {
            return ctx.proceed();
        }
        catch (Throwable e)
        {
            if (e instanceof Error)
                throw new Error("Changed");
            throw new RuntimeException("Changed");
        }
    }
}

当我们在遥控器上调用方法时,

Bar bar = context.lookup(Bar.class.getName());
bar.get();

Foo foo = context.lookup(Bar.class.getName());
foo.get();

未调用拦截器(使用Glassfish 3.0.1)。

问题似乎是由于接口的已编译类文件是

javap Foo
Compiled from "Foo.java"
public interface Foo{
    public abstract java.lang.Object get();
}

而对于BarImpl来说,它是

javap BarImpl
Compiled from "BarImpl.java"
public class BarImpl extends java.lang.Object implements Bar{
    public BarImpl();
    public java.lang.String get();
    public java.lang.Object get();
}

所以,当我们打电话时

Bar bar = ...;
bar.get();

内部方法

public java.lang.Object get(); 
调用

,它将委托给

public java.lang.String get();

当直接调用后者时,似乎只会调用拦截器。当我将界面栏更改为

@Remote
public interface Bar extends Foo<String> {
    @Override
    String get();
}

拦截器在第一次调用(bar.get())中调用,但不在第二次调用(foo.get())中调用。在类级别定义拦截器可能会修复问题,但在我们的情况下不是一个选项。

我们做错了什么,或者这是java-ee-6的一般问题,还是这是glassfish中的错误?有解决方法吗?或者我们应该放弃在服务中使用泛型?

1 个答案:

答案 0 :(得分:3)

由于我们正在处理Java,因此在运行时类型擦除会占用,而您的业务接口将只包含:

public Object get();

您正在将接口转换为Bar并且没有(没有运行时类转换异常),但是被调用的业务方法是业务接口中存在的业务方法(因为这是客户端知道的唯一方法) :Object get()版本。

此外,由于设计上只拦截了业务方法调用,因此Object get()上的String get()委托不会被截获(它只是一种调用另一种方法的方法)。这意味着,在您的初始场景中,您试图拦截不属于业务接口的方法,因此永远不会被截获。

由于EJB3规范实际上并不清楚泛型(通常没有说明),实现确实将该部分委托给JVM。在这种情况下无法获得真正的通用支持,我会说你被类拦截器或改变业务接口所困扰。