Учитывая следующий код
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();
перехватчик не вызывается (using Glassfish 3.0.1).
Проблема, по-видимому, связана с тем, что скомпилированный файл класса для интерфейса имеет вид
javap Foo
Compiled from "Foo.java"
public interface Foo{
public abstract java.lang.Object get();
}
, а для BarImpl -
* 1016.*
Итак, когда мы вызываем
Bar bar = ...;
bar.get();
Внутренне вызывается метод
public java.lang.Object get();
, который делегирует
public java.lang.String get();
Перехватчики кажутся тольковызываться, когда последний вызывается напрямую.Когда я изменяю интерфейс Bar на
@Remote
public interface Bar extends Foo<String> {
@Override
String get();
}
Перехватчик вызывается при первом вызове (bar.get ()), но не при втором вызове (foo.get ()).Определение перехватчиков на уровне класса может исправить проблему, но в нашем случае это не вариант.
Мы делаем что-то не так, или это общая проблема java-ee-6, или этоошибка в стеклянной рыбе?Есть ли обходной путь?Или мы вообще должны отказаться от использования дженериков в наших Сервисах?