Ok, i found a work around to this problem, changing the class loader every time 
i need add new code to my application.

BackGround:

A class i the JVM is identified by de ClassLoader and the full name of the 
class, so everytime you make a new instance, this object is identified by the 
class loader that loaded the class and the class name.  The problem is when you 
have to make several modules of your application to interact generating dynamic 
code on the fly.

Whe you create a new ClassLoader object you are just pulling away the od 
objects and loading new ones; the old ones are going to be garvage collected 
and the new ones are going to be there for your use.  This is not really 
HotSwapping at all !! because you are just creating a new loader.  Any way, 
here is the class that do the trick inside JBOSS, using javassist and the 
Javassist Loader.

Note:  See the delagation of class loaders and the delegation of ClassPools.

public class AdministradorClassPath {
                /**
                 * Ruta de las librerias que deben ser cargadas dinamicamente
                 */
                //TODO obtener del archivo de propiedades de configuracion de 
la aplicacion.
                public static final String RUTA_BODEGA = 
"../server/default/deploy/bodega.jar/";
                
                //public static final String 
                protected final Log logger = LogFactory.getLog(getClass());
                //Class loader padre de la aplicacion
                private ClassPool parentClassPool;
                private static AdministradorClassPath instance;
                private ClassPool childClassPool;
                private ArrayList pathRegister;
                private LinkedHashMap<String,Class> clasesCargadas;             
                private Loader loader;
                /**
                 * instancia Singleton
                 */
                private AdministradorClassPath(){
                        setParentClassPool();   
                        setChildClassPool();
                        //setSwapper();
                        setLoader();
                        pathRegister = new ArrayList();
                        clasesCargadas = new LinkedHashMap<String,Class>();     
                
                }
                /**
                 * Inicializa un ClassLoader unico para la instancia del  
AdministradorClasspath.
                 * 
                 */
                public void setLoader(){
                        if(this.childClassPool!=null){
                                loader = new 
Loader(Thread.currentThread().getContextClassLoader(),this.childClassPool);
                                
loader.delegateLoadingOf("com.its.estructuras.");                       
                                logger.info("Cargador de creado correctamente 
con el pool: "+this.childClassPool);
                        }
                }
                
                /**
                 * 
                 * @return instace La instancia singleton de 
AdministradorClassPath
                 */
                public static AdministradorClassPath getInstance() {
                        if (instance == null) {
                                instance = new AdministradorClassPath();        
                
                        }
                        return instance;
                }       
                /**
                 * Asigna el pool de cargadores de clase de JBoss, o de 
cualuier contenedor
                 *    como el cargador padre, donde debe buscar las clases si 
no las encuentra en
                 *    uno de los cargadores hijo.
                 *
                 */
                private void setParentClassPool() {
                        //Crea un nuevo class pool y adiciona el search path 
del sistema
                        //Inicializa y adiciona el classpath del sistema a este 
pool de clases.
                        this.parentClassPool = new ClassPool(true);             
        
                }
                /**
                 * Asigna un classPool hijo al ClassPool que representa el pool 
de clases
                 *    del sistema.  Este pool hijo es el pricipal de la 
aplicacion. 
                 *
                 */
                private void setChildClassPool() {
                        childClassPool = new ClassPool(this.parentClassPool);
                        childClassPool.childFirstLookup=true;
                        
                }
                /**
                 *  Adiciona un nuevo Pool de clases  al repositorio
                 *     incluyendo el pool de clases padre del ambiente
                 *     en el servidor de aplicaciones
                 *
                 */
                public void adicionarClassPath(String rutaClassPath){   
                                
                        try{                            
                                if(!pathRegister.contains(rutaClassPath)){      
                        
                                        
childClassPool.appendClassPath(rutaClassPath);                                  
                                        pathRegister.add(rutaClassPath);        
                                        logger.debug("Se acaba de adicionar un 
nuevo class path al administrador: "+rutaClassPath);
                                }
                                
                                
                        }catch(NotFoundException e){
                                e.printStackTrace();
                        }               
                }       
                /**
                 * Imprime los classpath que contiene el administrador de class 
paths.
                 *
                 */
                public void printClassPaths(){          
                        for(String path:this.pathRegister){
                                logger.info(path);                      
                        }               
                }       
                /**
                 * Este metodo elimina el pool de clases utilizado y crea uno
                 *    totalmente nuevo.  
                 * 
                 */
                public void limpiarClassPoolYCrearUnoNuevo(){           
                        //Class Pool del sistema                        
                        this.setParentClassPool();
                        //Class Pool utilizado                  
                        this.setChildClassPool();
                        //Crear un nuevo cargador de clases
                        this.setLoader();
                        
                        //Limpiar la lista de class paths almacenados
                        this.pathRegister.clear();      
                        //Limpiar el buffer de clases que han sido cargadas 
utilizando el ClassPool del sistema
                        this.clasesCargadas.clear();
                        
                        //Forzar recoleccion de las instancias creadas 
previamente
                        System.gc();
                        
logger.info("*******************************************************************");
                        
logger.info("*******************************************************************");
                        logger.info("*********  Se ha limpiado el pool de 
clases por completo  *********");
                        
logger.info("*******************************************************************");
                        
logger.info("*******************************************************************");
                        //Adicioanar la ruta de la bodega de almacenamiento, 
siempre que se inicializa
                        //el pool de clases.
                        this.adicionarClassPath(this.RUTA_BODEGA);
                }
                /**
                 * Carga la clase del PoolClases de esta clase. Para ello 
obtiene un CtClass que
                 *    luego es pasado a un objeto de tipo Class.
                 * 
                 * @param fullClassName nombre de la clase completo
                 * @return class Objeto de tipo Clase requerido
                 */
                public Class cargarClase(String fullClassName){
                        Class clazz=null;
                        try{
                                if(clasesCargadas.containsKey(fullClassName)){
                                        clazz = 
clasesCargadas.get(fullClassName);
                                }else{
                                        clazz = 
loader.loadClass(fullClassName);//this.childClassPool.get(fullClassName).toClass();
                             
                                        
this.clasesCargadas.put(fullClassName,clazz);
                                }
                        }catch(ClassNotFoundException e){
                                e.printStackTrace();
                        }
                        return clazz;
                }
                /**
                 * Saca una CtClass del pool de clases.
                 * @param fullClassName nombre e la clase completo.
                 */
                public void sacarClaseDelPool(String fullClassName){
                        try {
                                CtClass cTClazz = 
this.childClassPool.get(fullClassName);
                                cTClazz.detach();               
                                //ls clase se deber eliminar del buffer de 
clases cargadas
                                
                        } catch (NotFoundException e) {
                                System.err.println("No se ha encontrado la 
clase solicitada.");
                                e.printStackTrace();
                        }       
                        
logger.info("*********************************************************************");
                        logger.info("*La clase: "+fullClassName+" ha sido 
sacada del pool de clases.  ****");
                        
logger.info("*********************************************************************");
                }
                /**
                 * Imprime las clases que se tienen almacenadas en el buffer de 
almacenamiento.
                 * 
                 */
                public void imprimirClasesDelBuffer(){
                        for(Class c:this.clasesCargadas.values()){
                                logger.info(c.getName());
                        }                       
                }
                
        }


View the original post : 
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3973977#3973977

Reply to the post : 
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3973977
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user

Reply via email to