com.app.server.EARDeployer.java Source code

Java tutorial

Introduction

Here is the source code for com.app.server.EARDeployer.java

Source

package com.app.server;

/*Copyright 2013 - 2015, Arun_Soundararajan (arun_srajan_2007@yahoo.com).and/or its affiliates.
    
All files in this repository or distribution are licensed under the
Apache License, Version 2.0 (the "License");
you may not use any files in this repository or distribution except
in compliance with the License.
    
You may obtain a copy of the License at
    
http://www.apache.org/licenses/LICENSE-2.0
    
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.*/

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import java.rmi.Remote;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

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

import org.apache.commons.vfs2.FileChangeEvent;
import org.apache.commons.vfs2.FileListener;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileSystemManager;
import org.apache.commons.vfs2.FileType;
import org.apache.commons.vfs2.FileUtil;
import org.apache.commons.vfs2.VFS;
import org.apache.commons.vfs2.cache.LRUFilesCache;
import org.apache.commons.vfs2.cache.SoftRefFilesCache;
import org.apache.commons.vfs2.impl.DefaultFileMonitor;
import org.apache.commons.vfs2.impl.DefaultFileReplicator;
import org.apache.commons.vfs2.impl.DefaultFileSystemManager;
import org.apache.commons.vfs2.impl.PrivilegedFileReplicator;
import org.apache.commons.vfs2.impl.StandardFileSystemManager;
import org.apache.commons.vfs2.impl.VFSClassLoader;
import org.apache.commons.vfs2.provider.TemporaryFileStore;
import org.apache.commons.vfs2.provider.jar.JarFileProvider;
import org.apache.log4j.Logger;
import org.eclipse.jdt.internal.jarinjarloader.RsrcURLStreamHandlerFactory;

import com.app.messaging.MessagingElem;
import com.app.server.util.ClassLoaderUtil;
import com.app.server.util.DirectoryFilterWatcher;
import com.app.services.ExecutorServiceAnnot;
import com.app.services.ExecutorServiceInfo;

public class EARDeployer implements EARDeployerMBean {
    Hashtable executorServiceMap;
    Hashtable urlClassLoaderMap;
    CopyOnWriteArrayList<String> earsDeployed = new CopyOnWriteArrayList();
    Registry registry;
    Logger log = Logger.getLogger(EARDeployer.class);
    int numberOfEarsDeployed = 0;
    Hashtable filesMap = new Hashtable();
    Vector deployerList;
    Vector serviceList;
    ServerConfig serverConfig;
    MBeanServer mbeanServer;
    StandardFileSystemManager fsManager = null;
    ObjectName warObjectName;
    ObjectName ejbObjectName;
    ObjectName sarObjectName;
    ObjectName rarObjectName;
    ObjectName ezbObjectName;
    String isdeployer;
    ObjectName objectName;

    public void init(Vector deployerlist) {
        this.deployerList = deployerlist;
    }

    public void init(Vector serviceList, ServerConfig serverConfig, MBeanServer mbeanServer) {
        this.serviceList = serviceList;
        this.serverConfig = serverConfig;
        this.mbeanServer = mbeanServer;
        this.registry = registry;
        fsManager = new StandardFileSystemManager();
        try {
            warObjectName = new ObjectName("com.app.server:type=deployer,service=WARDeployer");
            ejbObjectName = new ObjectName("com.app.server:type=deployer,service=EJBDeployer");
            sarObjectName = new ObjectName("com.app.server:type=deployer,service=SARDeployer");
            rarObjectName = new ObjectName("com.app.server:type=deployer,service=RARDeployer");
            ezbObjectName = new ObjectName("com.app.server:type=deployer,service=EZBeansDeployer");
            this.executorServiceMap = (Hashtable) mbeanServer.getAttribute(warObjectName, "ExecutorServiceMap");
            this.urlClassLoaderMap = (Hashtable) mbeanServer.getAttribute(warObjectName, "UrlClassLoaderMap");
            System.setProperty("java.io.tmpdir", serverConfig.getCachedir());
            /*DefaultFileReplicator replicator = new DefaultFileReplicator(new File(cacheDir));
            //fsManager.setReplicator(new PrivilegedFileReplicator(replicator));
            fsManager.setTemporaryFileStore(replicator);*/
            fsManager.init();
        } catch (Exception e) {
            log.error("Error in initialization", e);
            // TODO Auto-generated catch block
            //e3.printStackTrace();
        }
    }

    /**
     * This method configures the executor services from the jar file.
     * 
     * @param jarFile
     * @param classList
     * @throws FileSystemException
     */
    public void deployExecutorServicesEar(String earFileName, FileObject earFile) throws FileSystemException {
        try {
            log.info("EARFILE NAMEs=" + earFileName);
            CopyOnWriteArrayList<URL> libs = new CopyOnWriteArrayList<URL>();
            CopyOnWriteArrayList<FileObject> warObjects = new CopyOnWriteArrayList<FileObject>();
            CopyOnWriteArrayList<FileObject> jarObjects = new CopyOnWriteArrayList<FileObject>();
            CopyOnWriteArrayList<FileObject> sarObjects = new CopyOnWriteArrayList<FileObject>();
            CopyOnWriteArrayList<FileObject> rarObjects = new CopyOnWriteArrayList<FileObject>();
            CopyOnWriteArrayList<FileObject> ezbObjects = new CopyOnWriteArrayList<FileObject>();
            WebClassLoader customClassLoaderBaseLib = new WebClassLoader(new URL[] { earFile.getURL() },
                    Thread.currentThread().getContextClassLoader());
            final Field factoryField = URL.class.getDeclaredField("factory");
            factoryField.setAccessible(true);
            factoryField.set(null, new RsrcURLStreamHandlerFactory(customClassLoaderBaseLib));
            //URL.setURLStreamHandlerFactory(new RsrcURLStreamHandlerFactory(customClassLoaderBaseLib));
            obtainUrls(earFile, earFile, libs, warObjects, jarObjects, sarObjects, rarObjects, ezbObjects,
                    fsManager);
            VFSClassLoader customClassLoader = null;
            for (URL earLib : libs) {
                customClassLoaderBaseLib.addURL(earLib);
            }
            FileObject jarFileObject;
            ConcurrentHashMap classLoaderPath = new ConcurrentHashMap();
            filesMap.put(earFileName, classLoaderPath);
            for (FileObject rarFileObj : rarObjects) {

                //log.info(classLoader);
                //warDeployer.deleteDir(new File(serverConfig.getDeploydirectory()+"/"+fileName.substring(0,fileName.lastIndexOf(".war"))));
                mbeanServer.invoke(rarObjectName, "deploy", new Object[] { rarFileObj },
                        new String[] { FileObject.class.getName() });
                //}
            }
            for (FileObject sarFileObj : sarObjects) {

                //log.info(classLoader);
                //warDeployer.deleteDir(new File(serverConfig.getDeploydirectory()+"/"+fileName.substring(0,fileName.lastIndexOf(".war"))));
                mbeanServer.invoke(sarObjectName, "deploy",
                        new Object[] { sarFileObj, fsManager, customClassLoaderBaseLib },
                        new String[] { FileObject.class.getName(), StandardFileSystemManager.class.getName(),
                                ClassLoader.class.getName() });
                //}
            }

            for (FileObject ezbFileObj : ezbObjects) {

                //log.info(classLoader);
                //warDeployer.deleteDir(new File(serverConfig.getDeploydirectory()+"/"+fileName.substring(0,fileName.lastIndexOf(".war"))));
                mbeanServer.invoke(ezbObjectName, "deploy", new Object[] { ezbFileObj, customClassLoaderBaseLib },
                        new String[] { FileObject.class.getName(), VFSClassLoader.class.getName() });
                //}
            }

            for (FileObject warFileObj : warObjects) {
                //if(warFileObj.getName().getBaseName().endsWith(".war")){
                //logger.info("filePath"+filePath);
                String filePath = serverConfig.getDeploydirectory() + "/" + warFileObj.getName().getBaseName();
                log.info(filePath);
                String fileName = warFileObj.getName().getBaseName();
                String directoryName = fileName.substring(0, fileName.indexOf('.'));

                log.info(customClassLoaderBaseLib);
                //warDeployer.deleteDir(new File(serverConfig.getDeploydirectory()+"/"+fileName.substring(0,fileName.lastIndexOf(".war"))));
                new File(serverConfig.getDeploydirectory() + "/"
                        + fileName.substring(0, fileName.lastIndexOf(".war"))).mkdirs();
                log.info(serverConfig.getDeploydirectory() + "/"
                        + fileName.substring(0, fileName.lastIndexOf(".war")));
                classLoaderPath.put(warFileObj.getName().getBaseName(), serverConfig.getDeploydirectory() + "/"
                        + fileName.substring(0, fileName.lastIndexOf(".war")));
                mbeanServer.invoke(warObjectName, "extractWar",
                        new Object[] { warFileObj, customClassLoaderBaseLib, fsManager },
                        new String[] { FileObject.class.getName(), WebClassLoader.class.getName(),
                                StandardFileSystemManager.class.getName() });
                //}
            }
            //URL.setURLStreamHandlerFactory(new RsrcURLStreamHandlerFactory(null));
            for (FileObject jarFileObj : jarObjects) {

                //log.info(classLoader);
                //warDeployer.deleteDir(new File(serverConfig.getDeploydirectory()+"/"+fileName.substring(0,fileName.lastIndexOf(".war"))));
                mbeanServer.invoke(ejbObjectName, "deploy",
                        new Object[] { new URL(jarFileObj.getURL().toURI().toString()), fsManager,
                                customClassLoaderBaseLib },
                        new String[] { URL.class.getName(), StandardFileSystemManager.class.getName(),
                                ClassLoader.class.getName() });
                //}
            }
            //for (int keyCount = 0; keyCount < keys.size(); keyCount++) {}
            /*for (FileObject fobject : fileObjects) {
               fobject.close();
            }*/
            //log.info("Channel unlocked");
            earsDeployed.add(earFile.getName().getURI());
            earFile.close();
            fsManager.closeFileSystem(earFile.getFileSystem());
            // ClassLoaderUtil.closeClassLoader(customClassLoader);
        } catch (Exception ex) {
            log.error("Error in deploying the ear ", ex);
            //ex.printStackTrace();
        }
    }

    public static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            for (int i = 0; i < children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }

        // The directory is now empty so delete it
        return dir.delete();
    }

    /**
     * This method removes the executor services from the executor services
     * map.
     * 
     * @param jarFile
     * @param classList
     * @throws FileSystemException
     */
    public void deleteExecutorServicesEar(URL url) throws FileSystemException {
        try {
            File file = new File(url.toURI());
            String fileName = file.getName();
            synchronized (urlClassLoaderMap) {
                ConcurrentHashMap map = (ConcurrentHashMap) filesMap.get(fileName);
                if (map != null) {
                    //log.info("ClassLoader Map=\n\n\n\n"+urlClassLoaderMap);
                    Set keysinclassloadermap = map.keySet();
                    log.info(keysinclassloadermap.size());
                    Iterator classloaders = keysinclassloadermap.iterator();
                    while (classloaders.hasNext()) {
                        String classloader = (String) classloaders.next();
                        log.info("ClassLoader=" + classloader);
                        ClassLoader webClassLoader = (ClassLoader) this.urlClassLoaderMap.get(map.get(classloader));
                        this.urlClassLoaderMap.remove(map.get(classloader));
                        ClassLoaderUtil.cleanupJarFileFactory(ClassLoaderUtil.closeClassLoader(webClassLoader));
                        urlClassLoaderMap.remove(map.get(classloader));
                        try {
                            if (webClassLoader instanceof WebClassLoader)
                                ((WebClassLoader) webClassLoader).close();
                            else if (webClassLoader instanceof VFSClassLoader) {
                                FileObject[] fObj = ((VFSClassLoader) webClassLoader).getFileObjects();
                                for (FileObject obj : fObj) {
                                    obj.close();
                                }
                            }
                        } catch (Throwable e) {
                            log.error("Error in closing the classLoader", e);
                            // TODO Auto-generated catch block
                            //e.printStackTrace();
                        }
                        /*if (classloader.contains(deployDirectory +"/"+ fileName)) {
                           log.info("removing classloader" + deployDirectory
                          + classloader);
                              File warDir=new File(fileName);
                              if(warDir.exists()){                                    
                          warDeployer.deleteDir(warDir);
                              }
                              //log.info("Before Remove class loader\n\n\n\n"+this.urlClassLoaderMap);                           
                              //log.info("Remove class loader\n\n\n\n"+this.urlClassLoaderMap);
                        }*/
                    }
                    System.gc();
                    classloaders = keysinclassloadermap.iterator();
                    while (classloaders.hasNext()) {
                        String classloader = (String) classloaders.next();
                        if (classloader.endsWith(".war")) {
                            mbeanServer.invoke(warObjectName, "removeServlets",
                                    new Object[] { (String) map.get(classloader), classloader },
                                    new String[] { String.class.getName(), String.class.getName() });
                            File warDir = new File((String) map.get(classloader));
                            if (warDir.exists()) {
                                deleteDir(warDir);
                            }
                        }
                    }
                    log.info(this.urlClassLoaderMap);
                }
                filesMap.remove(fileName);
            }
        } catch (Exception ex) {
            try {
                log.error("Error in removing the executor services configuration for the file name "
                        + url.toURI().toString(), ex);
            } catch (URISyntaxException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            //ex.printStackTrace();
        }
    }

    public void obtainUrls(FileObject rootEar, FileObject ear, CopyOnWriteArrayList<URL> fileObjects,
            CopyOnWriteArrayList<FileObject> warObjects, CopyOnWriteArrayList<FileObject> jarObjects,
            CopyOnWriteArrayList<FileObject> sarObjects, CopyOnWriteArrayList<FileObject> rarObjects,
            CopyOnWriteArrayList<FileObject> ezbObjects, StandardFileSystemManager fsManager) throws IOException {
        FileObject[] childrenJars = ear.getChildren();
        for (int childcount = 0; childcount < childrenJars.length; childcount++) {
            if (childrenJars[childcount].getType() == FileType.FOLDER) {
                obtainUrls(rootEar, childrenJars[childcount], fileObjects, warObjects, jarObjects, sarObjects,
                        rarObjects, ezbObjects, fsManager);
            }
            // log.info(childrenJars[childcount]);
            // log.info(childrenJars[childcount].getName().getBaseName());
            // log.info(ear.getURL());
            if (childrenJars[childcount].getType() == FileType.FILE
                    && (childrenJars[childcount].getName().getBaseName().endsWith(".jar")
                            || childrenJars[childcount].getName().getBaseName().endsWith(".war")
                            || childrenJars[childcount].getName().getBaseName().toLowerCase().endsWith(".rar")
                            || childrenJars[childcount].getName().getBaseName().toLowerCase().endsWith(".sar"))) {
                // log.info(childrenJars[childcount].getURL());
                if ((childrenJars[childcount].getName().getBaseName().toLowerCase().endsWith(".war")
                        || childrenJars[childcount].getName().getBaseName().toLowerCase().endsWith(".jar")
                        || childrenJars[childcount].getName().getBaseName().toLowerCase().endsWith(".rar")
                        || childrenJars[childcount].getName().getBaseName().toLowerCase().endsWith(".sar")
                        || childrenJars[childcount].getName().getBaseName().toLowerCase().endsWith(".ezb"))
                        && !childrenJars[childcount].getURL().toString().trim()
                                .startsWith(rootEar.getURL().toString() + "lib/")) {
                    //File file=new File(serverConfig.getDeploydirectory()+"/"+childrenJars[childcount].getName().getBaseName());
                    /*if(!file.exists()||(file.exists()&&file.lastModified()!=childrenJars[childcount].getContent().getLastModifiedTime())){
                       //InputStream fistr=childrenJars[childcount].getContent().getInputStream();
                       byte[] filyByt=new byte[4096];
                       FileOutputStream warFile=new FileOutputStream(serverConfig.getDeploydirectory()+"/"+childrenJars[childcount].getName().getBaseName()+".part");
                       int len=0;
                       while((len=fistr.read(filyByt))!=-1){
                          warFile.write(filyByt,0,len);
                       }
                       warFile.close();
                       fistr.close();
                       new File(serverConfig.getDeploydirectory()+"/"+childrenJars[childcount].getName().getBaseName()+".part").renameTo(file);
                       warObjects.add(childrenJars[childcount]);
                    }*/
                    if (childrenJars[childcount].getName().getBaseName().toLowerCase().endsWith(".war")) {
                        warObjects.add(childrenJars[childcount]);
                    } else if (childrenJars[childcount].getName().getBaseName().toLowerCase().endsWith(".jar")) {
                        jarObjects.add(childrenJars[childcount]);
                    } else if (childrenJars[childcount].getName().getBaseName().toLowerCase().endsWith(".sar")) {
                        sarObjects.add(childrenJars[childcount]);
                    } else if (childrenJars[childcount].getName().getBaseName().toLowerCase().endsWith(".rar")) {
                        rarObjects.add(childrenJars[childcount]);
                    } else if (childrenJars[childcount].getName().getBaseName().toLowerCase().endsWith(".ezb")) {
                        ezbObjects.add(childrenJars[childcount]);
                    }
                } else {
                    log.info("ear libs/" + childrenJars[childcount]);
                    fileObjects.add(new URL(childrenJars[childcount].getURL().toString()
                            .replace(rootEar.getURL().toString(), "rsrc:")));
                }
                // log.info(childrenJars[childcount].getURL().toString()+" "+rootEar.getURL());

            } else {
                childrenJars[childcount].close();
            }
        }
    }

    public static void getClassList(FileObject jarFile, CopyOnWriteArrayList classList,
            StandardFileSystemManager fsManager) throws FileSystemException {
        // log.info(jarFile);
        FileObject nestedFS = null;
        FileObject[] children = null;
        if (jarFile.getURL().toString().trim().endsWith(".jar")) {
            nestedFS = fsManager.createFileSystem(jarFile);
            children = nestedFS.resolveFile("/").getChildren();
        } else if (jarFile.getType() == FileType.FOLDER) {
            children = jarFile.getChildren();
        }
        // log.info();
        // log.info( "Children of " + jarFile.getName().getURI() );
        if (children == null)
            return;
        for (int i = 0; i < children.length; i++) {
            // log.info(children[i].+" "+
            // children[i].getName().getBaseName() );
            if (children[i].getType() == FileType.FILE && children[i].getName().getBaseName().endsWith(".class"))
                classList.add(children[i].toString().substring(children[i].toString().lastIndexOf('!') + 2));
            getClassList(children[i], classList, fsManager);
        }
    }

    public int getNumberOfEarDeployed() {

        return numberOfEarsDeployed;
    }

    public boolean accept(URL url) {
        File file;
        try {
            file = new File(url.toURI());
            return file.getName().toLowerCase().endsWith(".ear");
        } catch (Exception e) {
            log.error("Error in creating file for the uri " + url, e);
            // TODO Auto-generated catch block
            //e.printStackTrace();
        }
        return false;
    }

    public void deploy(URL url) {

        File file;
        try {
            file = new File(url.toURI());
            FileObject earFile = fsManager
                    .resolveFile("jar:file:///" + serverConfig.getDeploydirectory() + "/" + file.getName());
            deployExecutorServicesEar(file.getName(), earFile);
            log.info("Ear " + url.toURI() + " Deployed successfully");
        } catch (Exception e) {
            log.error("Error in deploying the package" + url, e);
            // TODO Auto-generated catch block
            //e.printStackTrace();
        }

    }

    public void undeploy(URL url) {

        //File file;
        try {
            //file = new File(url.toURI());
            /*FileObject earFile = fsManager.resolveFile("jar:file:///"
                  + serverConfig.getDeploydirectory() + "/" + file.getName());*/
            deleteExecutorServicesEar(url);
        } catch (Exception e) {
            log.error("Error in undeploying the package" + url, e);
            e.printStackTrace();
        }
    }

    public String getDeployer() {
        return this.isdeployer;
    }

    public void setDeployer(String isdeployer) {
        this.isdeployer = isdeployer;

    }

    public void setObjectName(ObjectName objName) {
        this.objectName = objName;

    }

    public ObjectName getObjectName() {

        return this.objectName;
    }

    public void start() {
        this.deployerList.add(this.objectName.getCanonicalName());
        log.info("started");
    }

    public void stop() {
        log.info("stopped");
    }

    public void destroy() {
        this.deployerList.remove(this.objectName.getCanonicalName());
        log.info("destroyed");
    }

    @Override
    public CopyOnWriteArrayList<String> getEarsDeployed() {

        return this.earsDeployed;
    }
}