2012-02-14 26 views
12

Actualmente estamos en el proceso de migrar algunos de nuestros proyectos de JBoss 4.x a JBoss 7. Hasta ahora todo parece funcionar bien, excepto nuestros MBeans, que lo usamos comúnmente para proporcionar operaciones de administración simples.Puerto MBean de JBoss 4.x a JBoss 7

He estado buscando desde hace bastante tiempo, pero o bien soy incapaz de encontrar el término de búsqueda correcto o me falta algo de conocimiento para cerrar la brecha entre la definición de MBean en JBoss 4.x y JBoss 7.

por lo tanto, es de esperar que alguien puede proporcionar una pista sobre lo que podría hacer falta o donde tendría que leer en (tal vez algún tipo de documentación, ejemplos, etc.)

en nuestra Jboss 4.x Los MBeans a menudo se ven así:

@Service(objectName = "Domain:Name=SomeMBean", 
    xmbean="resource:<path-to-xmbean.xml>") 
class SomeMBean 
{ 
    @EJB 
    private SomeService someService;  

    public String someOperation() 
    { 
    someService.doSomething(); 
    return "success"; 
    } 
} 

Utilizamos el @Service anotación para definir el nombre del objeto y el descriptor xmbean y JBoss registraría automáticamente esos mbeans.

Aparentemente, en JBoss 7, la anotación @Service ya no existe y, por lo tanto, se necesita otro enfoque.

Hasta ahora, logré registrar el MBean manualmente con el servidor mbean de la plataforma, pero prefiero que JBoss lo haga automáticamente. Además, no pude proporcionar descripciones de los métodos/parámetros hasta el momento (aunque esas son características más agradables de tener).

Voy a repetir la pregunta para mayor claridad:

¿Cómo voy a definir un MBean en JBoss 7 (Java EE 6) que proporciona las siguientes características?

  • despliegue automático
  • acceso a los EJB
  • o accesibles a través de JConsole JMX Console (Actualmente estoy usando el puerto Dimitris Andreadis')
  • proporcionan descripciones de métodos/parámetros

Actualización

Esto es lo que obtuve hasta ahora:

Primero, encontré esta proyección, que usa CDI para envolver el objetivo de inyección de cualquier bean que está anotado en consecuencia y realiza el registro JMX en el método postConstruct(): http://code.google.com/p/jmx-annotations/. Además, los MBeans encontrados se analizan para anotaciones de clase/atributo/método/parámetro que proporcionan una descripción de la propiedad anotada.

Sin embargo, el método postConstruct() parece no ser llamado para EJB (supongo que es para no chocar con el contenedor EJB). Por lo tanto, los MBeans ahora no deberían ser EJB, sino simples beans CDI.

Por lo tanto, sin embargo, tiene la desventaja de que los MBeans no se instancian automáticamente. Para superar esto, hay un bean singleton que al inicio se desplaza por todos los beans en el BeanManager y crea una instancia de cada MBean encontrado. Debido a que los MBeans todavía tienen su objetivo de inyección, no se llamará a su método postConstruct() y el bean se registrará en el servidor MBean.

Aquí está una descripción aproximada del procedimiento de inicio:

  • una extensión CDI encargo escanea cada grano de CDI para la anotación personalizada @MBean
  • para cada MBean elligible el objetivo de la inyección se envuelve
  • un producto único se iniciará bean que en su método @PostConstruct creará instancias de los MBeans
  • se llamará al método postConstruct() del objetivo de inyección del MBean y, por lo tanto, el MBean se registrará en el servidor MBean

Una desventaja de este método sería el contexto de transacción faltante al ejecutar métodos MBean (cualquier llamada EJB se ejecutará en un contexto de transacción). Sin embargo, esto podría solucionarse utilizando un interceptor CDI que proporcionará el contexto de la transacción, si es necesario. El proyecto Seam parece tener interceptores apropiados para eso.

Todavía no estoy seguro si esto es un enfoque sano y estable, por lo que cualquier comentario constructivo, consejos, etc., son más que bienvenidos.

Respuesta

3
+0

vi que también, pero lo que no me gusta de este enfoque es que tendríamos que poner manualmente el código de registro en cada MBean (no podemos usar súper clases en muchos casos). Por lo tanto, actualmente usamos el método que describí anteriormente. Sin embargo, gracias a la sugerencia :) – Thomas

+1

No hay muchas opciones. En JBoss 7 usted registra programáticamente o usa jboss-service.xml. Si desea transacciones, entonces el uso de Singleton EJBs será probablemente el enfoque más fácil. Se podía mover el código de registro de los mbeans y crear un StartupRegistrationBean que registró todo lo que los mbeans de una manera similar a la extensión de CDI. – Chase

1

Creo forma más concisa de hacerlo es utilizar la extensión CDI. favor, eche un vistazo a la solución que utilizamos:

@Documented 
@Retention(value=RUNTIME) 
@Target(value=TYPE) 
@Inherited 
public @interface MBean { 
    String value() default ""; 
} 

...

Este código está trabajando de extensión CDI:

public class ManagementExtension implements Extension { 

    private static Logger log = LoggerFactory 
      .getLogger(ManagementExtension.class); 

    public <T> void processInjectionTarget(@Observes ProcessInjectionTarget<T> pit) { 

     // check if the MBean annotation is present 
     AnnotatedType<T> at = pit.getAnnotatedType(); 
     if (at.isAnnotationPresent(MBean.class)) { 
      // it makes sense to register JMX interfaces only for singletons 
      if (!at.isAnnotationPresent(Singleton.class)) { 
       log.warn("Ignoring attemt to register JMX interface for a non-singleton EJB: " 
         + at.getJavaClass().getName()); 
       return; 
      } 

      try { 
       // decorate the InjectionTarget 
       InjectionTarget<T> delegate = pit.getInjectionTarget(); 
       InjectionTarget<T> wrapper = new JmxInjectionTarget<T>(delegate, getObjectName(at)); 

       // change the InjectionTarget with the decorated one 
       pit.setInjectionTarget(wrapper); 
      } catch (Exception e) { 
       log.warn("Cannot get JMX object name for: " + at.getJavaClass().getName(), e); 
      } 

     } 
    } 

    private <T> ObjectName getObjectName(AnnotatedType<T> at) throws MalformedObjectNameException { 

     String name = at.getAnnotation(MBean.class).value(); 

     if (name.isEmpty()) { 
      name = at.getJavaClass().getPackage().getName() + ":type=" 
        + at.getJavaClass().getSimpleName(); 
     } 

     return new ObjectName(name); 
    } 

    private class JmxInjectionTarget<T> implements InjectionTarget<T> { 

     private final InjectionTarget<T> d; 
     private final ObjectName objectName; 

     public JmxInjectionTarget(InjectionTarget<T> delegate, ObjectName objectName) { 
      this.d = delegate; 
      this.objectName = objectName; 
     } 
     @Override 
     public void dispose(T instance) { 
      d.dispose(instance); 
     } 

     @Override 
     public Set<InjectionPoint> getInjectionPoints() { 
      return d.getInjectionPoints(); 
     } 

     @Override 
     public T produce(CreationalContext<T> ctx) { 
      return d.produce(ctx); 
     } 

     @Override 
     public void inject(T instance, CreationalContext<T> ctx) { 
      d.inject(instance, ctx); 
      //the next piece of code better be done in postConstruct but... 
      //got no idea why but postConstruct never gets called 
      //for Singleton EJB bean 
      MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); 
      try { 
       if(mBeanServer.isRegistered(objectName)) 
       mBeanServer.unregisterMBean(objectName); 
       mBeanServer.registerMBean(instance, objectName); 
      } catch (Exception e) { 
       log.warn("Cannot register "+objectName, e); 
       return; 
      } 
      log.info("added JMX registration for: " + objectName); 
     } 

     @Override 
     public void postConstruct(T instance) { 
      d.postConstruct(instance); 
     } 

     @Override 
     public void preDestroy(T instance) { 
      d.preDestroy(instance); 
     } 

    } 
} 

A continuación, sólo marcan la clase de anotación y @Mbean se registrará automáticamente en el servidor Mbean:

@Startup 
@Singleton 
@MBean("com.synapsense:type=JmxBindName") 
public class SomeService 

Funciona como una encanto)

Cuestiones relacionadas