Telepített webalkalmazások lekérdezése JBoss alatt

Múlt héten belefutottam egy olyan problémába, hogy szükségem lett volna egy file-t elérni a telepített web-alkalmazás könyvtárából, de nem tudtam. Alapvetően ez nem olyan nagy probléma, a http request-ből el lehet érni a session objektumot és abból pedig getRealPath(útvonal) metódushívással visszakapjuk a fájlrendszerbeli abszolút útvonalat. Viszont nekem ezt egy időzítő (org.jboss.varia.scheduler.Schedulable) objektumból kellett megtennem, ahol nincs http kérés.

Az útvonalat konstansba nem tehettem, mert egrészt minden gépen (sajátom, tesztgép, éles) máshol van maga a JBoss is, másrészt mindig változó nevű ideiglenes könyvtárba csomagolja ki az alkalmazást.

A ClassLoader megint nem megoldás, mert nem az osztályok útvonalán volt a fájl, ami nekem kell és nagyon sok része az alkalmazásnak ott keresi.

A megoldást végül tegnap délután, 3 nap szívás küzdelem után találtam meg. Itt volt egy utalás rá, hogy JMX-el el lehet érni a JBoss deployer szolgáltatását. Már csak ki kellett találni, hogy ez hogyan használható. Természetesen senkit sem találtam, aki már csinált volna ilyet. Végül a JBoss forrásaiban találtam mintát. Ez lett a végleges megoldás:

/**
 * File: Test.java
 * Project: proba
 * Package:
 *
 * (c) Test - 2009.11.18.
 */

import java.util.Collection;

import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.deployment.MainDeployerMBean;
import org.jboss.deployment.SerializableDeploymentInfo;
import org.jboss.mx.util.MBeanProxyExt;
import org.jboss.mx.util.MBeanServerLocator;

/**
 * Get deployment path of a web application on JBoss AS
 *
 * @author siz
 *
 */
public class Test {

    private static final String MAIN_DEPLOYER_SERVICE_NAME = "jboss.system:service=MainDeployer";
    private static final String WAR_NAME = "testWar.war";

    private static final Log log = LogFactory.getLog(Test.class);

    private String deploymentPath = null;

    @SuppressWarnings("unchecked")
    public Test() {
        // Get the MBean server
        MBeanServer server = MBeanServerLocator.locateJBoss();
        try {
            // Object name to be accessed
            ObjectName on = new ObjectName(MAIN_DEPLOYER_SERVICE_NAME);
            // Proxy for the deployer MBean
            MainDeployerMBean proxy = (MainDeployerMBean) MBeanProxyExt.create(
                    MainDeployerMBean.class, on, server);
            // List deployed modules
            Collection deployments = proxy.listDeployedModules();
            // Search modules for our one
            for (Object deployment : deployments) {
                if (deployment instanceof SerializableDeploymentInfo) {
                    SerializableDeploymentInfo info = (SerializableDeploymentInfo) deployment;
                    // Analyze deployment information
                    if (info.shortName.equals(WAR_NAME)) {
                        log.debug("Found our webapp: " + info.shortName);
                        deploymentPath = info.localUrl.getPath() + ".";
                        log.debug("Deployment path: " + deploymentPath);
                    }
                }
            }
        } catch (MalformedObjectNameException e) {
            log.error("Error retrieving WAR info: ", e);
        } catch (NullPointerException e) {
            log.error("Error retrieving WAR info: ", e);
        }
    }
}

Remélem valakinek egyszer még jól jön...