CDI: Использование перехватчиков в разных модулях / архивах компонентов - PullRequest
15 голосов
/ 29 октября 2010

Мое приложение Java EE 6 состоит из модуля war и ejb, упакованных в ear-файл. Я использую CDI для DI (то есть у меня есть файл beans.xml в обоих модулях). Я хочу использовать перехватчик регистрации, который также определен в модуле ejb в модуле war. Я включил перехватчик в файле ejb's beans.xml:

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

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

SEVERE: исключение при загрузке приложения: WELD-001417 Включен класс класса-перехватчика 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 {}

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

Ответы [ 5 ]

10 голосов
/ 10 июля 2013

Спецификация J2EE 7 гласит ( ссылка ):

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

Преимущество этого решения в том, что оно не зависит от поставщика.

Пример:

@Logged
@Interceptor
@Priority(Interceptor.Priority.APPLICATION)
public class LoggedInterceptor implements Serializable { ... }
5 голосов
/ 18 апреля 2011

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

1 голос
/ 08 января 2011

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

0 голосов
/ 28 апреля 2014

У меня была точно такая же проблема с моим протоколирующим перехватчиком на 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.

0 голосов
/ 20 апреля 2011

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

Это - отчет jira, пожалуйста, проголосуйте: -)

...