2010-10-29 8 views
14

Mi aplicación Java EE 6 consiste en un módulo war y un módulo ejb empaquetados en el archivo ear. Estoy usando CDI para DI (es decir, tengo un archivo beans.xml en ambos módulos). También quiero usar un interceptor de registro definido en el módulo ejb en el módulo war. He activado el interceptor en beans.xml del EJB:CDI: Uso de interceptores en diferentes módulos/archivos de frijoles

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

Esto está trabajando sólo para las clases que están anotados con el interceptor en el módulo EJB . Las clases en el módulo de guerra no son interceptadas (aunque están anotadas con el interceptor también). Pensé que la solución sería habilitar el interceptor en el interceptor de la guerra también (como arriba). Pero la aplicación no se puede implementar con el siguiente mensaje:

GRAVES: Excepción durante la carga de la aplicación: Weld-001417 Habilitado com.test.interceptor.LoggingInterceptor clase clase de interceptor no es ni anotado @Interceptor ni registrado a través de una extensión portátil

Mi LoggingInterceptor se ve así:

@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)}); 
     } 
    } 

} 

Y la unión del interceptor:

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

¿Cómo puedo usar el interceptor para ambos módulos?

+0

¿Has encontrado la solución a este problema? Sería interesante verlo. – mik

+1

@milk no, no lo he hecho. Consolidé todos los módulos en un módulo de guerra, lo cual es posible desde Java EE 6. – Theo

+0

wow, gracias por explicarlo tan claramente. Estaba teniendo exactamente el mismo problema y la consolidación de todo en un solo módulo lo resolvió. A veces, J2EE solo trata de complicar las cosas en ti ... – JoshC13

Respuesta

1

Me pregunto si su WAR carece de visor de clasificador en su ejb-jar? Creo que idealmente los 299 interceptores estarían en su propio jar, visible tanto para EJB como para los módulos web y habilitados en ambos beans.xml.

5

Es demasiado tarde, pero si alguien todavía tiene este problema. Ambos módulos deben ser cargados por el mismo cargador de clases para hacer posible el uso de interceptor en diferentes módulos, al menos en WebSphere 8b2. En WebSphere, esta configuración puede cambiarse en la consola de administración: Aplicaciones> Tipos de aplicación> Aplicaciones empresariales WebSphere> [nombre de su aplicación]> Carga de clase y detección de actualización> Política de cargador de clase WAR = cargador de clase único para la aplicación.
El interceptor debe habilitarse UNA VEZ en beans.xml.

+0

Nunca es tarde para la respuesta correcta, thx :-) –

+2

Incluso si está permitido (y es común) en WebSphere, esto no se recomienda para la aplicación JEE. Los cargadores de clase están separados por una razón. –

0

Tengo el mismo problema en JBoss AS 6.0/6.1 (construcción nocturna) y lo solucioné en disabling separate classloaders (opción 1), pero tenga mucho cuidado con esto. La separación de los cargadores de clases no ha sido introducida por ninguna razón, por lo que al parecer hay nuevos problemas en el camino por delante ...

This es el informe jira, por favor vote arriba :-)

8

especificación J2EE 7 dice (reference):

los interceptores que se especifican en el archivo beans.xml se aplican sólo a clases en el mismo archivo. Utilice la anotación @Priority para especificar interceptores a nivel mundial para una aplicación que consta de múltiples módulos

Esta solución tiene la ventaja de ser proveedor independiente.

Un ejemplo:

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

Puedo confirmar que esto funciona en WildFly 10.1.0.Final – schnatterer

0

que tenía exactamente el mismo problema con mi logging interceptor en JBoss 7 y se fija por la superposición de frasco del interceptor completa en la aplicación.

<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> 

Usted todavía tiene que activar el interceptor en la aplicación de breans.xml.

No es bueno, pero funciona. En Java EE 7, funciona sin la activación anotando el interceptor como @Priority.

Cuestiones relacionadas