2010-10-29 4 views
14

Приложение My Java EE 6 состоит из модуля войны и ejb, упакованного в файл уха. Я использую CDI для DI (т. Е. У меня есть файл beans.xml в обоих модулях). Я хочу использовать перехватчик регистрации, который также определен в модуле ejb в военном модуле. Я включил перехватчик в beans.xml EJB-в:CDI: Использование перехватчиков в разных архивах модулей/бобов

<beans> 
    <interceptors> 
     <class>com.test.interceptor.LoggingInterceptor</class> 
    </interceptors> 
</beans> 

Это работает только для классов, которые снабженными перехватчика в модуле в EJB. Классы в военном модуле не перехватываются (хотя они тоже аннотируются с перехватчиком). Я думал, что решение будет состоять в том, чтобы включить перехватчик в перехватчике войны (как и выше). Но приложение не может быть развернуто со следующим сообщением:

СИЛЬНОЕ: Исключение при загрузке приложения: WELD-001417 Enabled перехватчика класса класса com.test.interceptor.LoggingInterceptor не является ни аннотированным @Interceptor ни регистрироваться с помощью портативного расширения

Мои LoggingInterceptor выглядит следующим образом:

@Log 
@Interceptor 
public class LoggingInterceptor { 
    private static final Logger logger = Logger.getLogger(LoggingInterceptor.class.getName()); 

    static { 
     logger.setLevel(Level.ALL); 
    } 

    @AroundInvoke 
    public Object logMethod(InvocationContext ctx) throws Exception { 
     logger.log(Level.FINE, "ENTRY {0} {1}", 
       new Object[]{ ctx.getTarget().getClass().getName(), ctx.getMethod().getName() }); 
     long startTime = System.nanoTime(); 
     try { 
      return ctx.proceed(); 
     } finally { 
      long diffTime = System.nanoTime() - startTime; 
      logger.log(Level.FINE, "RETURN {0} {1}", 
       new Object[]{ ctx.getTarget().getClass().getName(), ctx.getMethod().getName() }); 
      logger.log(Level.FINE, "{0} took {1} ms", new Object[]{ ctx.getMethod(), 
        TimeUnit.MILLISECONDS.convert(diffTime, TimeUnit.NANOSECONDS)}); 
     } 
    } 

} 

И перехватчик связывания:

@InterceptorBinding 
@Retention(RetentionPolicy.RUNTIME) 
@Target({ElementType.METHOD, ElementType.TYPE}) 
public @interface Log {} 

Как использовать перехватчик для обоих модулей?

+0

Вы нашли решение этой проблемы? Было бы интересно увидеть это. – mik

+1

@milk нет, у меня его нет. Я объединил все модули в один боевой модуль, что возможно, так как Java EE 6. – Theo

+0

wow, спасибо, что выложили это так ясно. У меня была одна и та же проблема, и все ее объединение в один модуль решило. Иногда J2EE просто пытается усложнить ya ... – JoshC13

ответ

1

Интересно, не хватает ли вашей ВОЛС-размытости в загрузке ejb-jar? Я думаю, что в идеале 299-перехватчики будут находиться в их собственной банке, видимой как EJB, так и веб-модулям и включаться в оба их beans.xml.

5

Слишком поздно, но если у кого-то еще есть эта проблема. Оба модуля должны быть загружены одним и тем же загрузчиком классов, чтобы использовать перехватчик через различные модули, по крайней мере, в WebSphere 8b2. В WebSphere этот параметр можно переключить в консоли администрирования: Приложения> Типы приложений> Корпоративные приложения WebSphere> [имя вашего приложения]> Обнаружение загрузки и обнаружения обновлений> Политика загрузчика WAR-класса = Загрузка одного класса для приложения.
Перехватчик должен быть включен только ONCE в beans.xml.

+0

Это не поздно для правильного ответа, thx :-) –

+2

Даже если это разрешено (и распространено) в WebSphere, это не рекомендуется для приложения JEE. Погрузчики классов раздельны по какой-либо причине. –

0

У меня такая же проблема на JBoss AS 6.0/6.1 (ночная сборка) и зафиксирована на disabling separate classloaders (вариант 1), но будьте предельно осторожны с этим. Разделение загрузчиков классов не была введена без причины, поэтому, видимо, возникают новые проблемы на пути вперед ...

This является отчет JIRA, пожалуйста, оцените его :-)

8

J2EE 7 спецификации говорит (reference):

перехватчики, указанные в файле beans.xml применяются только к классов в одном архиве. Используйте @Priority аннотацию указать перехватчики глобально для приложения, которое состоит из нескольких модулей

Это решение имеет преимущество в том, не зависящем от производителя.

Пример:

@Logged 
@Interceptor 
@Priority(Interceptor.Priority.APPLICATION) 
public class LoggedInterceptor implements Serializable { ... } 
+0

Я могу подтвердить это работает на WildFly 10.1.0.Final – schnatterer

0

У меня была точно такая же проблема с моим logging interceptor на JBoss 7 и фиксируется его накладывания банку в полном перехватчика в приложение.

<build> 
    <plugins> 
     <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-war-plugin</artifactId> 
      <version>2.4</version> 
      <configuration> 
       <overlays> 
        <overlay> 
         <groupId>com.github.t1</groupId> 
         <artifactId>logging-interceptor</artifactId> 
         <type>jar</type> 
         <targetPath>WEB-INF/classes</targetPath> 
        </overlay> 
       </overlays> 
      </configuration> 
     </plugin> 
    </plugins> 
</build> 

<dependencies> 
    <dependency> 
     <groupId>com.github.t1</groupId> 
     <artifactId>logging-interceptor</artifactId> 
     <version>1.1</version> 
     <optional>true</optional> 
    </dependency> 
</dependencies> 

Вы все равно придется активировать перехватчик в приложения breans.xml.

Не очень, но это работает. В Java EE 7 он работает без активации, аннотируя перехватчик как @Priority.