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?