Java tutorial
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.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.rmi.Remote; import java.rmi.registry.Registry; import java.rmi.server.UnicastRemoteObject; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.jar.JarEntry; import java.util.jar.JarFile; 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.FileSystemOptions; import org.apache.commons.vfs2.FileType; import org.apache.commons.vfs2.VFS; import org.apache.commons.vfs2.impl.DefaultFileMonitor; import org.apache.commons.vfs2.impl.DefaultFileReplicator; 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.ftp.FtpFileSystemConfigBuilder; import org.apache.log4j.Logger; import com.app.server.util.ClassLoaderUtil; import com.app.services.ExecutorServiceAnnot; import com.app.services.ExecutorServiceInfo; /** * This class is implementation of the jar deployer which also configures the Executor services * @author arun * */ public class JarDeployer extends Thread implements Runnable, JarDeployerMBean { String scanDirectory; String libDir; Hashtable executorServiceMap; Hashtable urlClassLoaderMap; CopyOnWriteArrayList<String> jarsDeployed = new CopyOnWriteArrayList(); Registry registry; String cacheDir; static Logger log = Logger.getLogger(JarDeployer.class); public JarDeployer(Registry registry, String scanDirectory, String libDirectory, String cacheDir, Hashtable executorServiceMap, Hashtable urlClassLoaderMap) { this.scanDirectory = scanDirectory.replace("\\", "/"); this.executorServiceMap = executorServiceMap; this.urlClassLoaderMap = urlClassLoaderMap; this.libDir = libDirectory; this.cacheDir = cacheDir; this.registry = registry; } /** * This method implements the jar deployer which configures the executor services. * Frequently monitors the deploy directory and configures the executor services map * once the jar is deployed in deploy directory and reconfigures if the jar is modified and * placed in the deploy directory. */ public void run() { StandardFileSystemManager fsManager = new StandardFileSystemManager(); try { fsManager.init(); DefaultFileReplicator replicator = new DefaultFileReplicator(new File(cacheDir)); //fsManager.setReplicator(new PrivilegedFileReplicator(replicator)); fsManager.setTemporaryFileStore(replicator); } catch (FileSystemException e2) { // TODO Auto-generated catch block e2.printStackTrace(); } File file = new File(scanDirectory.split(";")[0]); File[] files = file.listFiles(); CopyOnWriteArrayList<String> classList = new CopyOnWriteArrayList<String>(); for (int i = 0; i < files.length; i++) { if (files[i].isDirectory()) continue; //Long lastModified=(Long) fileMap.get(files[i].getName()); if (files[i].getName().endsWith(".jar")) { String filePath = files[i].getAbsolutePath(); FileObject jarFile = null; try { jarFile = fsManager.resolveFile("jar:" + filePath); } catch (FileSystemException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } //logger.info("filePath"+filePath); filePath = filePath.substring(0, filePath.toLowerCase().lastIndexOf(".jar")); WebClassLoader customClassLoader = null; try { URLClassLoader loader = (URLClassLoader) ClassLoader.getSystemClassLoader(); URL[] urls = loader.getURLs(); try { customClassLoader = new WebClassLoader(urls); log.info(customClassLoader.geturlS()); customClassLoader.addURL(new URL("file:/" + files[i].getAbsolutePath())); CopyOnWriteArrayList<String> jarList = new CopyOnWriteArrayList(); getUsersJars(new File(libDir), jarList); for (String jarFilePath : jarList) customClassLoader.addURL(new URL("file:/" + jarFilePath.replace("\\", "/"))); log.info("deploy=" + customClassLoader.geturlS()); this.urlClassLoaderMap.put(scanDirectory + "/" + files[i].getName(), customClassLoader); jarsDeployed.add(files[i].getName()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } log.info(urlClassLoaderMap); getChildren(jarFile, classList); } catch (FileSystemException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } for (int classCount = 0; classCount < classList.size(); classCount++) { String classwithpackage = classList.get(classCount).substring(0, classList.get(classCount).indexOf(".class")); classwithpackage = classwithpackage.replace("/", "."); log.info("classList:" + classwithpackage.replace("/", ".")); try { if (!classwithpackage.contains("$")) { Class executorServiceClass = customClassLoader.loadClass(classwithpackage); //log.info("executor class in ExecutorServicesConstruct"+executorServiceClass); //log.info(); if (!executorServiceClass.isInterface()) { Annotation[] classServicesAnnot = executorServiceClass.getDeclaredAnnotations(); if (classServicesAnnot != null) { for (int annotcount = 0; annotcount < classServicesAnnot.length; annotcount++) { if (classServicesAnnot[annotcount] instanceof RemoteCall) { RemoteCall remoteCall = (RemoteCall) classServicesAnnot[annotcount]; //registry.unbind(remoteCall.servicename()); log.info(remoteCall.servicename().trim()); try { //for(int count=0;count<500;count++){ RemoteInterface reminterface = (RemoteInterface) UnicastRemoteObject .exportObject((Remote) executorServiceClass.newInstance(), 2004); registry.rebind(remoteCall.servicename().trim(), reminterface); //} } catch (Exception ex) { ex.printStackTrace(); } } } } } Method[] methods = executorServiceClass.getDeclaredMethods(); for (Method method : methods) { Annotation[] annotations = method.getDeclaredAnnotations(); for (Annotation annotation : annotations) { if (annotation instanceof ExecutorServiceAnnot) { ExecutorServiceAnnot executorServiceAnnot = (ExecutorServiceAnnot) annotation; ExecutorServiceInfo executorServiceInfo = new ExecutorServiceInfo(); executorServiceInfo.setExecutorServicesClass(executorServiceClass); executorServiceInfo.setMethod(method); executorServiceInfo.setMethodParams(method.getParameterTypes()); //log.info("method="+executorServiceAnnot.servicename()); //log.info("method info="+executorServiceInfo); //if(servicesMap.get(executorServiceAnnot.servicename())==null)throw new Exception(); executorServiceMap.put(executorServiceAnnot.servicename(), executorServiceInfo); } } } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } ClassLoaderUtil.closeClassLoader(customClassLoader); try { jarFile.close(); } catch (FileSystemException e) { // TODO Auto-generated catch block e.printStackTrace(); } fsManager.closeFileSystem(jarFile.getFileSystem()); } } fsManager.close(); fsManager = new StandardFileSystemManager(); try { DefaultFileReplicator replicator = new DefaultFileReplicator(new File(cacheDir)); //fsManager.setReplicator(new PrivilegedFileReplicator(replicator)); fsManager.setTemporaryFileStore(replicator); } catch (FileSystemException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } JarFileListener jarFileListener = new JarFileListener(executorServiceMap, libDir, urlClassLoaderMap, jarsDeployed); DefaultFileMonitor fm = new DefaultFileMonitor(jarFileListener); jarFileListener.setFm(fm); FileObject listendir = null; String[] dirsToScan = scanDirectory.split(";"); try { FileSystemOptions opts = new FileSystemOptions(); FtpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, true); fsManager.init(); for (String dir : dirsToScan) { if (dir.startsWith("ftp://")) { listendir = fsManager.resolveFile(dir, opts); } else { listendir = fsManager.resolveFile(dir); } fm.addFile(listendir); } } catch (FileSystemException e) { // TODO Auto-generated catch block e.printStackTrace(); } fm.setRecursive(true); fm.setDelay(3000); fm.start(); //fsManager.close(); } public static void main(String[] args) throws FileSystemException { //new JarDeployer("D:\\lib",new HashMap(),new HashMap()).start(); } /** * This method obtains the jar file in the deploy directory. * @param dir * @param jarList */ public void getUsersJars(File dir, CopyOnWriteArrayList jarList) { if (dir.isDirectory()) { File[] children = dir.listFiles(); for (int i = 0; i < children.length; i++) { log.info(children[i]); getUsersJars(children[i], jarList); if (children[i].isFile() && children[i].getName().endsWith(".jar")) jarList.add(children[i].getAbsolutePath()); } } } /** * This method obtains the class name for each of the executor services * @param jarFile * @param classList * @throws FileSystemException */ public void getChildren(FileObject jarFile, CopyOnWriteArrayList classList) throws FileSystemException { if (jarFile.getType() == FileType.FILE) return; FileObject[] children = jarFile.getChildren(); //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().indexOf('!') + 2)); getChildren(children[i], classList); children[i].close(); //fsManager.closeFileSystem(children[i].getFileSystem()); } } /** * This method obtains the class name inside the jar * @param jarPath * @param content * @throws IOException */ public static void getJarContent(String jarPath, CopyOnWriteArrayList content) throws IOException { try { log.info("enumer=" + jarPath); JarFile jarFile = new JarFile(jarPath); Enumeration enumer = (Enumeration) jarFile.entries(); while (enumer.hasMoreElements()) { JarEntry entry = (JarEntry) enumer.nextElement(); String name = entry.getName(); if (name.endsWith(".class")) content.add(name.replace("/", ".")); } log.info(content); jarFile.close(); } catch (Exception ex) { ex.printStackTrace(); } } /** * This class is the implementation of the Jar file listener deployed in the jar deploy directory. * When deployed in the services directory which configures for the executor services map. * @author arun * */ private class JarFileListener implements FileListener { Hashtable executorServiceMap, urlClassLoaderMap; CopyOnWriteArrayList jarsDeployed; DefaultFileMonitor fileMonitor; String libDir; public JarFileListener(Hashtable executorServiceMap, String libDir, Hashtable urlClassLoaderMap, CopyOnWriteArrayList jarsDeployed) { this.executorServiceMap = executorServiceMap; this.urlClassLoaderMap = urlClassLoaderMap; this.jarsDeployed = jarsDeployed; this.libDir = libDir; } public void setFm(DefaultFileMonitor fm) { fileMonitor = fm; } /** * This method is the implementation of jar file has been modified in the jar deploy directory * @param arg0 */ @Override public void fileChanged(FileChangeEvent arg0) throws Exception { try { CopyOnWriteArrayList classList = new CopyOnWriteArrayList(); //StandardFileSystemManager fsManager = new StandardFileSystemManager(); FileObject baseFile = arg0.getFile(); if (baseFile.getName().getURI().endsWith(".jar")) { log.info(baseFile.getName().getURI().replace("file:///", "jar:")); //FileObject jarFile = fsManager.resolveFile(baseFile.getName().getURI().replace("file:///", "jar:")); getJarContent(baseFile.getName().getURI().replace("file:///", ""), classList); deployExecutorServicesJar(baseFile, classList, baseFile.getName().getURI()); this.jarsDeployed.add(baseFile.getName().getURI().replace("file:///", "")); baseFile.close(); //fsManager.closeFileSystem(baseFile.getFileSystem()); //fsManager.close(); log.info(baseFile.getName().getURI() + " deployed successfully"); } } catch (Exception ex) { ex.printStackTrace(); } } /** * This method is the implementation of jar file has been put in the jar deploy directory * @param arg0 */ @Override public void fileCreated(FileChangeEvent arg0) throws Exception { try { CopyOnWriteArrayList classList = new CopyOnWriteArrayList(); //StandardFileSystemManager fsManager = new StandardFileSystemManager(); FileObject baseFile = arg0.getFile(); if (baseFile.getName().getURI().endsWith(".jar")) { log.info(baseFile.getName().getURI().replace("file:///", "jar:")); //FileObject jarFile = fsManager.resolveFile( baseFile.getName().getURI().replace("file:///", "jar:")); getJarContent(baseFile.getName().getURI().replace("file:///", ""), classList); deployExecutorServicesJar(arg0.getFile(), classList, baseFile.getName().getURI()); this.jarsDeployed.add(baseFile.getName().getURI().replace("file:///", "")); baseFile.close(); //fsManager.closeFileSystem(baseFile.getFileSystem()); //fsManager.close(); log.info(baseFile.getName().getURI() + " deployed successfully"); } } catch (Exception ex) { ex.printStackTrace(); } } /** * This method is the implementation of jar file has been deleted in the jar deploy directory * @param arg0 */ @Override public void fileDeleted(FileChangeEvent arg0) throws Exception { try { CopyOnWriteArrayList classList = new CopyOnWriteArrayList(); //StandardFileSystemManager fsManager = new StandardFileSystemManager(); FileObject baseFile = arg0.getFile(); log.info(baseFile.getName().getURI()); if (baseFile.getName().getURI().endsWith(".jar")) { log.info(baseFile.getName().getURI().replace("file:///", "jar:")); //FileObject jarFile = fsManager.resolveFile( baseFile.getName().getURI().replace("file:///", "jar:")); getJarContent(baseFile.getName().getURI().replace("file:///", ""), classList); deleteExecutorServicesJar(arg0.getFile(), classList); this.jarsDeployed.remove(baseFile.getName().getURI().replace("file:///", "")); baseFile.close(); //fsManager.closeFileSystem(baseFile.getFileSystem()); //fsManager.close(); log.info(baseFile.getName().getURI() + " undeployed successfully"); } } catch (Exception ex) { ex.printStackTrace(); } } /** * This method configures the executor services from the jar file. * @param jarFile * @param classList * @param fileURI * @throws FileSystemException */ public void deployExecutorServicesJar(FileObject jarFile, CopyOnWriteArrayList<String> classList, String fileURI) throws FileSystemException { FileSystemManager fsManager = VFS.getManager(); WebClassLoader customClassLoader = null; URLClassLoader loader = (URLClassLoader) ClassLoader.getSystemClassLoader(); URL[] urls = loader.getURLs(); try { customClassLoader = new WebClassLoader(urls); customClassLoader.addURL(new URL(fileURI)); CopyOnWriteArrayList<String> jarList = new CopyOnWriteArrayList(); getUsersJars(new File(libDir), jarList); for (String jarFilePath : jarList) customClassLoader.addURL(new URL("file:/" + jarFilePath.replace("\\", "/"))); log.info("deploy=" + customClassLoader.geturlS()); this.urlClassLoaderMap.put(scanDirectory + "/" + jarFile.getName().getBaseName(), customClassLoader); jarsDeployed.add(jarFile.getName().getBaseName()); log.info(this.urlClassLoaderMap); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } log.info(urlClassLoaderMap); for (int classCount = 0; classCount < classList.size(); classCount++) { String classwithpackage = classList.get(classCount).substring(0, classList.get(classCount).indexOf(".class")); classwithpackage = classwithpackage.replace("/", "."); log.info("classList:" + classwithpackage.replace("/", ".")); try { if (!classwithpackage.contains("$")) { Class executorServiceClass = customClassLoader.loadClass(classwithpackage); //log.info(executorServiceClass.newInstance()); //log.info("executor class in ExecutorServicesConstruct"+executorServiceClass); if (!executorServiceClass.isInterface()) { Annotation[] classServicesAnnot = executorServiceClass.getDeclaredAnnotations(); if (classServicesAnnot != null) { for (int annotcount = 0; annotcount < classServicesAnnot.length; annotcount++) { if (classServicesAnnot[annotcount] instanceof RemoteCall) { RemoteCall remoteCall = (RemoteCall) classServicesAnnot[annotcount]; //registry.unbind(remoteCall.servicename()); log.info(remoteCall.servicename().trim()); try { RemoteInterface reminterface = (RemoteInterface) UnicastRemoteObject .exportObject((Remote) executorServiceClass.newInstance(), 2004); registry.rebind(remoteCall.servicename().trim(), reminterface); } catch (Exception ex) { ex.printStackTrace(); } } } } } Method[] methods = executorServiceClass.getDeclaredMethods(); for (Method method : methods) { Annotation[] annotations = method.getDeclaredAnnotations(); for (Annotation annotation : annotations) { if (annotation instanceof ExecutorServiceAnnot) { ExecutorServiceAnnot executorServiceAnnot = (ExecutorServiceAnnot) annotation; ExecutorServiceInfo executorServiceInfo = new ExecutorServiceInfo(); executorServiceInfo.setExecutorServicesClass(executorServiceClass); executorServiceInfo.setMethod(method); executorServiceInfo.setMethodParams(method.getParameterTypes()); //log.info("method="+executorServiceAnnot.servicename()); //log.info("method info="+executorServiceInfo); //if(servicesMap.get(executorServiceAnnot.servicename())==null)throw new Exception(); executorServiceMap.put(executorServiceAnnot.servicename(), executorServiceInfo); } } } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } fileMonitor.addFile(jarFile); ClassLoaderUtil.closeClassLoader(customClassLoader); try { customClassLoader.close(); } catch (Exception ex) { //ex.printStackTrace(); } } /** * This method removes the executor services from the executor services map. * @param jarFile * @param classList * @throws FileSystemException */ public void deleteExecutorServicesJar(FileObject jarFile, CopyOnWriteArrayList<String> classList) throws FileSystemException { //FileSystemManager fsManager = VFS.getManager(); WebClassLoader customClassLoader = null; customClassLoader = (WebClassLoader) this.urlClassLoaderMap .get(scanDirectory + "/" + jarFile.getName().getBaseName()); log.info("delete=" + customClassLoader.geturlS()); ClassLoaderUtil.closeClassLoader(customClassLoader); this.urlClassLoaderMap.remove(scanDirectory + "/" + jarFile.getName().getBaseName()); jarsDeployed.remove(jarFile.getName().getBaseName()); log.info(urlClassLoaderMap); for (int classCount = 0; classCount < classList.size(); classCount++) { String classwithpackage = classList.get(classCount).substring(0, classList.get(classCount).indexOf(".class")); classwithpackage = classwithpackage.replace("/", "."); log.info("classList:" + classwithpackage.replace("/", ".")); try { if (!classwithpackage.contains("$")) { Class executorServiceClass = customClassLoader.loadClass(classwithpackage); log.info(executorServiceClass.newInstance()); //log.info("executor class in ExecutorServicesConstruct"+executorServiceClass); //log.info(); Method[] methods = executorServiceClass.getDeclaredMethods(); for (Method method : methods) { Annotation[] annotations = method.getDeclaredAnnotations(); for (Annotation annotation : annotations) { if (annotation instanceof ExecutorServiceAnnot) { ExecutorServiceAnnot executorServiceAnnot = (ExecutorServiceAnnot) annotation; ExecutorServiceInfo executorServiceInfo = new ExecutorServiceInfo(); executorServiceInfo.setExecutorServicesClass(executorServiceClass); executorServiceInfo.setMethod(method); //log.info("method="+executorServiceAnnot.servicename()); //log.info("method info="+executorServiceInfo); //if(servicesMap.get(executorServiceAnnot.servicename())==null)throw new Exception(); executorServiceMap.remove(executorServiceAnnot.servicename()); } } } } } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } fileMonitor.removeFile(jarFile); } } @Override public CopyOnWriteArrayList<String> getDeployedJars() { return jarsDeployed; } }