/* * Copyright 2012 The Solmix Project * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.gnu.org/licenses/ * or see the FSF site: http://www.fsf.org. */ package org.solmix.launch.base.shared; import java.beans.Introspector; import java.io.File; import java.io.FileFilter; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.JarURLConnection; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.net.URLConnection; import java.util.jar.JarFile; /** * * @author ffz * @version 0.0.1 2012-3-16 * @since 0.0.4 */ public class Loader { private final File launchLibs; public Loader(final File launchLibs) { if (launchLibs == null) { throw new IllegalArgumentException("Solmix Home must not be null or empty"); } this.launchLibs = checkLaunchLibsDir(launchLibs); removeOldLoadedJars(); } public void cleanupVM() { // ensure the JavaBeans introspector lets go of any classes it // may haved cached after introspection Introspector.flushCaches(); // if solmix home is set, check whether we have to close the // launcher JAR JarFile, which might be cached in the platform closeLoadedJarFile(getLaunchJarFile()); } /** * @param launcherJarFile */ private void closeLoadedJarFile(final File[] loadedJarFiles) { for (File loadedJarFile : loadedJarFiles) { try { final URI launcherJarUri = loadedJarFile.toURI(); final URL launcherJarRoot = new URL("jar:" + launcherJarUri + "!/"); final URLConnection conn = launcherJarRoot.openConnection(); if (conn instanceof JarURLConnection) { final JarFile jarFile = ((JarURLConnection) conn).getJarFile(); jarFile.close(); } } catch (Exception e) { // better logging here } } } /** * get launch jar file. * * @return */ private File[] getLaunchJarFile() { File result = null; final File[] launcherJars = getLaunchJarFiles(); if (launcherJars == null || launcherJars.length == 0) { // return a non-existing file naming the desired primary name result = new File(launchLibs.getAbsolutePath() + LaunchConstants.LOADER_JAR_REL_PATH); if (!result.exists()) { result = new File(launchLibs, "org.solmix.launch.base.jar"); } return new File[] { result }; } return launcherJars; } /** * */ private void removeOldLoadedJars() { final File[] loadedJars = getLaunchJarFiles(); // TODO } /** * 从solmixBase中加载所有可能为启动文件的JAR包。 * * @return */ private File[] getLaunchJarFiles() { final File[] rawList = launchLibs.listFiles(new FileFilter() { public boolean accept(File pathname) { if (pathname.isFile()) { if (pathname.getName().startsWith(LaunchConstants.LOADERS_PATH) || pathname.getName().contains(LaunchConstants.JAAS_PATH_LOADER)) return true; } return false; } }); return rawList; } /** * @param loadersHome * @return */ private static File checkLaunchLibsDir(File loadersHome) { if (loadersHome.exists()) { if (!loadersHome.isDirectory()) { throw new IllegalArgumentException("Solmix launch libs directory " + loadersHome + "exists but is not a directory"); } } else if (!loadersHome.mkdirs()) { throw new IllegalArgumentException("Solmix launch libs directory" + loadersHome + "exists but cannot be created as a directory"); } return loadersHome; } /** * Load class form launch libs. * * @param loaderClassName * @return */ public Object loadLaucher(String loaderClassName) { File[] launchJars = getLaunchJarFile(); final ClassLoader loader; try { URL[] urls = new URL[launchJars.length]; for (int i = 0; i < launchJars.length; i++) { urls[i] = launchJars[i].toURI().toURL(); } loader = new SolmixClassLoader(urls); // loader = this.getClass().getClassLoader(); } catch (MalformedURLException e) { throw new IllegalArgumentException("Cannot create an URL from the JAR path name", e); } try { final Class<?> launcherClass = loader.loadClass(loaderClassName); return launcherClass.newInstance(); } catch (ClassNotFoundException e) { throw new IllegalArgumentException("Cannot find class " + loaderClassName, e); } catch (InstantiationException e) { throw new IllegalArgumentException("Cannot instantiate launcher class " + loaderClassName, e); } catch (IllegalAccessException e) { throw new IllegalArgumentException("Cannot access constructor of class " + loaderClassName, e); } } /** * Spools the contents of the input stream to the given file replacing the contents of the file with the contents of * the input stream. When this method returns, the input stream is guaranteed to be closed. * * @throws IOException If an error occurrs reading or writing the input stream contents. */ public static void spool(InputStream ins, File destFile) throws IOException { OutputStream out = null; try { out = new FileOutputStream(destFile); byte[] buf = new byte[8192]; int rd; while ((rd = ins.read(buf)) >= 0) { out.write(buf, 0, rd); } } finally { if (ins != null) { try { ins.close(); } catch (IOException ignore) { } } if (out != null) { try { out.close(); } catch (IOException ignore) { } } } } /** Meant to be overridden to display or log info */ protected void info(String msg) { } }