Archivo de la etiqueta: MBean

JBoss + Spring + MBeans 3/4

JBossImage

Bueno, ahora ya tenemos cómo acceder a los MBeans desde código, pero ¿cómo crearlos desde código?

Lo primero que tenemos que tener en cuenta es que las clases que queremos crear como MBeans, obligatoriamente tienen que estar en el servidor. O sea, tenemos que exportarlo como un .jar y ponerlo en la carpeta lib del servidor (así me funcionó a mi, si tenemos una aplicación web será un .war y en deploy, aunque no lo probé)

Ya tenemos eso, ahora creamos un MBean cualquiera:

Interfaz TesterMBean

package org.acriter.testJBoss;public interface TesterMBean {public String getNombre();public void setNombre(String nombre);public void init();

}

Clase Tester

package org.acriter.testJBoss;public class Tester implements TesterMBean{public void init() {// TODO Auto-generated method stub}
private String nombre;
public String getNombre() {
return nombre;
}

public void setNombre(String nombre) {
this.nombre=nombre;
}
}

JMXProBrowser


package org.acriter.testJBoss;import javax.management.MBeanInfo;import javax.management.MBeanOperationInfo;import javax.management.MBeanParameterInfo;import javax.management.ObjectName;

import javax.naming.InitialContext;

import org.jboss.jmx.adaptor.rmi.RMIAdaptor;

/**

* Esta clase puede conectarse con JBOSS!!

* Y llamar a sus MBeans...

* Queda para la historia.

* @author hmassaroli

*

*/

public class JMXProBrowser

{

/**

* @param args the command line arguments

*/

public static void main(String[] args) throws Exception

{

//ponemos las propiedades (?)
System.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
System.setProperty("java.naming.provider.url", "localhost:1099");
InitialContext ic = new InitialContext();
RMIAdaptor server = (RMIAdaptor) ic.lookup("jmx/invoker/RMIAdaptor");
//Intentaremos crear un MBean
ObjectName name2 = new ObjectName("jboss:service=BeanLoco");
//server.createMBean("java.lang.String", name2); //Esta clase si la toma
server.createMBean("org.acriter.testJBoss.Tester", name2);
//Esta no
// Get the MBeanInfo for the JNDIView MBean
ObjectName name = new ObjectName("jboss:service=JNDIView");
MBeanInfo info = server.getMBeanInfo(name);
System.out.println("JNDIView Class: " + info.getClassName());

MBeanOperationInfo[] opInfo = info.getOperations();
System.out.println("JNDIView Operations: ");
for(int o = 0; o < opInfo.length; o ++) {
MBeanOperationInfo op = opInfo[o];

String returnType = op.getReturnType();
String opName = op.getName();
System.out.print(" + " + returnType + " " + opName + "(");

MBeanParameterInfo[] params = op.getSignature();
for(int p = 0; p < params.length; p++) {
MBeanParameterInfo paramInfo = params[p];

String pname = paramInfo.getName();
String type = paramInfo.getType();

if (pname.equals(type)) {
System.out.print(type);
} else {
System.out.print(type + " " + name);
}

if (p < params.length-1) {
System.out.print(',');
}
}
System.out.println(")");
}
// Invoke the list(boolean) op
String[] sig = {"boolean"};
Object[] opArgs = {Boolean.TRUE};
Object result = server.invoke(name, "list", opArgs, sig);

System.out.println("JNDIView.list(true) output:n"+result);
}
}

Anuncios

JBoss + Spring + MBeans 2/4

JBossImage

Bueno, ahora veremos cómo obtener info de un MBean existente en el servidor mediante código. La conexión del servidor es lo que se me complicó mucho, todavía no me explico demasiado cómo funciona. Éste es el código:

org.acriter.testJBoss.JMXBrowser:


package org.acriter.testJBoss;import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.ObjectName;
import javax.naming.InitialContext;import org.jboss.jmx.adaptor.rmi.RMIAdaptor;

/**
* Esta clase puede conectarse con JBOSS!!
* Y llamar a sus MBeans…
* Queda para la historia.
* @author hmassaroli
*
*/
public class JMXBrowser
{
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws Exception
{

//ponemos las propiedades (?)
System.setProperty(“java.naming.factory.initial”, “org.jnp.interfaces.NamingContextFactory”);
System.setProperty(“java.naming.provider.url”, “localhost:1099”);

InitialContext ic = new InitialContext();
RMIAdaptor server = (RMIAdaptor) ic.lookup(“jmx/invoker/RMIAdaptor”);

// Get the MBeanInfo for the JNDIView MBean
ObjectName name = new ObjectName(“jboss:service=JNDIView”);
MBeanInfo info = server.getMBeanInfo(name);
System.out.println(“JNDIView Class: ” + info.getClassName());

MBeanOperationInfo[] opInfo = info.getOperations();
System.out.println(“JNDIView Operations: “);
for(int o = 0; o < opInfo.length; o ++) {
MBeanOperationInfo op = opInfo[o];

String returnType = op.getReturnType();
String opName = op.getName();
System.out.print(” + ” + returnType + ” ” + opName + “(“);

MBeanParameterInfo[] params = op.getSignature();
for(int p = 0; p < params.length; p++) {
MBeanParameterInfo paramInfo = params[p];

String pname = paramInfo.getName();
String type = paramInfo.getType();

if (pname.equals(type)) {
System.out.print(type);
} else {
System.out.print(type + ” ” + name);
}

if (p < params.length-1) {
System.out.print(‘,’);
}
}
System.out.println(“)”);
}

// Invoke the list(boolean) op
String[] sig = {“boolean”};
Object[] opArgs = {Boolean.TRUE};
Object result = server.invoke(name, “list”, opArgs, sig);

System.out.println(“JNDIView.list(true) output:n”+result);
}
}

 

Spring + JBoss + MBeans: FAQ

JBossImage

FAQ:

java.lang.NoSuchMethodException <init>

Estás poniendo la interfase en el jboss-service.xml, no la clase. Obviamente, una interfaz no tiene constructores 😉

 ClassNotFoundException

Hay que poner en el servidor un archivo .jar (en lib, por ejemplo), con las clases, ¡JBoss no puede instanciar una clase que no tiene!

(Si, te preguntarás (y entonces por qué no lo hago como servicio en un .SAR y listo! Bueno,
capaz quieras tener todas las clases en un sólo .jar, ¡y no repartidas por ahí en muchos archivos!)

Jboss + Spring + Mbeans 1/3

Hace poco me encomendaron la desconocida tarea de registrar desde una aplicación stand alone con Spring un MBean en un servidor JBoss. Me costó mucho al principio enteder, lo primero que logré fue declarar un servicio en JBoss desde un archivo .SAR. No me acuerdo mucho del asunto, es algo así:

http://forum.springframework.org/showthread.php?t=11479

Se define una carpeta META-INF en un Proyecto Java, y adentro se le pone un jboss-service.xml, se lo exporta como .jar, y le cambiás la extensión a .SAR, y JBoss te lo toma como servicio.

Acá está el ejemplo:

META-INF/jboss-service.xml:

<?xml version="1.0" encoding="UTF-8"?>
<server>
<mbean code="com.acme.HelloWorldService" name="acme.com:service=HelloWorld">
<attribute name="Message">Hello World</attribute>
</mbean>
</server>com.acme.HelloWorldServiceMBean


com.acme.HelloWorldService

package com.acme; import org.jboss.system.ServiceMBeanSupport;public class HelloWorldService extends ServiceMBeanSupport implements HelloWorldServiceMBean
{
// Our message attribute
private String message = "Sorry no message today";// Getters and Setters
public String getMessage()
{
return message;
}
public void setMessage(String message)
{
this.message = message;
}// The printMessage operation
public void printMessage()
{
log.info(message);
}// The lifecycle
protected void startService() throws Exception
{
log.info("Starting with message=" + message);
}
protected void stopService() throws Exception
{
log.info("Stopping with message=" + message);
}
}

com.acme.HelloWorldServiceMBean:

package com.acme;import org.jboss.system.ServiceMBean;public interface HelloWorldServiceMBean extends ServiceMBean
{
// Configure getters and setters for the message attribute
String getMessage();
void setMessage(String message);// The print message operation
void printMessage();
}Si esto les funciona, ya están listos para la siguiente y terrorífica etapa... obtener la info de un MBean del servidor!  

Misterioso archivo .SAR

Un archivo SAR es un archivo de servicio de JBoss. Si quieren probar cómo se muestra un MBean en la consola de JBoss, es decir, instanciar un nuevo servicio, deben:

Crear un nuevo proyecto web dinámico en Eclipse

Hacer este tutorial.

Crear una carpeta META-INF y ahí poner el archivo jboss-services.xml

Exportar el archivo como .JAR

Cambiarle la extensión a .SAR, y pegarlo en la carpeta deploy, del servidor default (o e que usen) de JBoss x)

En definitiva, la diferencia entre un JAR y un SAR es el nombre, y que este último tiene en META-INF la descripción del servicio.