2010-10-29 95 views
14

我的Java EE 6應用程序由打包在ear文件中的war和ejb模塊組成。我使用CDI進行DI(即,我在兩個模塊中都有一個beans.xml文件)。我想使用war模塊中ejb模塊中定義的日誌攔截器。我已經啓用攔截器在EJB的beans.xml中:CDI:跨不同模塊/ bean檔案使用攔截器

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

這對於被註釋與EJB模塊在攔截器類唯一的工作。戰爭模塊中的類不會被攔截(雖然它們也使用攔截器進行註釋)。我認爲解決方案應該是在戰爭攔截器中啓用攔截器(如上所述)。

嚴重:但是,應用程序不能與下面的消息被部署異常而加載的應用程序: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 {} 

如何爲兩個模塊使用攔截器?

+0

您是否找到解決此問題的解決方案?看到它會很有趣。 – mik 2012-05-28 07:28:19

+1

@milk不,我沒有。我將所有模塊合併到一個war模塊中,這是自Java EE 6. – Theo 2012-05-29 10:17:56

+0

哇,這是可能的,謝謝你清楚地闡明瞭這一點。我遇到了完全相同的問題,並將它整合到一個模塊中解決了它。有時候J2EE只是試圖讓事情變得艱難...... – JoshC13 2015-11-06 02:59:17

回答

1

我想知道你的WAR是否缺乏classloader可視性到你的ejb-jar中?我認爲理想情況下,299個攔截器將在他們自己的jar中,對EJB和web模塊都可見,並在其beans.xml中啓用。

5

爲時已晚,但如果有人仍然有這個問題。 兩個模塊應該由相同的類加載器加載,以便在不同模塊間使用攔截器,至少在WebSphere 8b2中是如此。 在WebSphere中,可以在管理控制檯中切換此設置:應用程序>應用程序類型> WebSphere企業應用程序> [您的應用程序名稱]>類加載和更新檢測> WAR類加載器策略=用於應用程序的單個類加載器。
攔截器必須在beans.xml中僅啓用一次。

+0

正確答案永遠不會遲到,thx :-) – 2012-06-06 09:04:49

+2

即使在WebSphere中允許(並且常見),這也不建議用於JEE應用程序。類裝載機是分開的,這是有原因的。 – 2015-07-27 02:49:12

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 2017-08-08 09:56:31

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而無需激活。