4 Stimmen

EJB-Interceptoren werden bei Verwendung generischer Schnittstellen nicht aufgerufen

Bei folgendem Code

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");
        }
    }
}

Wenn wir eine Methode auf der Gegenseite aufrufen,

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

o

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

der Interceptor wird nicht aufgerufen (bei Verwendung von Glassfish 3.0.1).

Das Problem scheint auf die Tatsache zurückzuführen zu sein, dass die kompilierte Klassendatei für die Schnittstelle

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

und für BarImpl ist es

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();
}

Wenn wir also anrufen

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

Intern wird die Methode

public java.lang.Object get(); 

aufgerufen wird, die dann an

public java.lang.String get();

Abfangjäger scheinen nur dann aufgerufen zu werden, wenn letztere direkt aufgerufen werden. Wenn ich die Schnittstelle Bar in

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

Der Interceptor wird beim ersten Aufruf (bar.get()) aufgerufen, aber nicht beim zweiten Aufruf (foo.get()). Die Definition der Interceptoren auf Klassenebene könnte das Problem beheben, ist aber in unserem Fall keine Option.

Machen wir etwas falsch, oder ist dies ein allgemeines Problem von Java-ee-6, oder ist dies ein Fehler in Glassfish? Gibt es eine Umgehung? Oder sollten wir die Verwendung von Generika in unseren Diensten überhaupt aufgeben?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X