All Downloads are FREE. Search and download functionalities are using the official Maven repository.

otstrap.bootstrap-java.1.0.source-code.Bootstrap Maven / Gradle / Ivy

The newest version!
/*
 * File: JarClassLoader.java
 * 
 * Copyright (C) 2008-2011 JDotSoft. All Rights Reserved.
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301  USA
 * 
 * Visit jdotsoft.com for commercial license.
 * 
 * $Id: JarClassLoader.java,v 1.30 2011/02/04 20:12:19 mg Exp $
 */

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.Attributes.Name;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

/**
 * This class loader loads classes, native libraries and resources from the top
 * JAR and from JARs inside top JAR. The loading process looks through JARs
 * hierarchy and allows their tree structure, i.e. nested JARs.
 * 

* The top JAR and nested JARs are included in the classpath and searched for * the class or resource to load. The nested JARs could be located in any * directories or subdirectories in a parent JAR. *

* All directories or subdirectories in the top JAR and nested JARs are included * in the library path and searched for a native library. For example, the * library "Native.dll" could be in the JAR root directory as "Native.dll" or in * any directory as "lib/Native.dll" or "abc/xyz/Native.dll". *

* This class delegates class loading to the parent class loader and * successfully loads classes, native libraries and resources when it works not * in a JAR environment. *

* Create a Launcher class to use this class loader and start its * main() method to start your application com.mycompany.MyApp *

public class MyAppLauncher {

    public static void main(String[] args) {
        JarClassLoader jcl = new JarClassLoader();
        try {
            jcl.invokeMain("com.mycompany.MyApp", args);
        } catch (Throwable e) {
            e.printStackTrace();
        }
    } // main()
    
} // class MyAppLauncher
* *

* An application could be started in two different environments:
* 1. Application is started from an exploded JAR with dependent resources * locations defined in a classpath. Command line to start the application could * point to the main class e.g. MyApp.main() or to the * MyAppLauncher.main() class (see example above). The application * behavior in both cases is identical. Application started with * MyApp.main() uses system class loader and resources loaded from * a file system. Application started with MyAppLauncher.main() * uses JarClassLoader which transparently passes class loading to * the system class loader. * *
* 2. Application is started from a JAR with dependent JARs and other resources * inside the main JAR. Application must be started with * MyAppLauncher.main() and JarClassLoader will load * MyApp.main() and required resources from the main JAR. * *

* Use VM parameters in the command line for debugging: * -DJarClassLoader.logger=[filename] for logging into the file or * -DJarClassLoader.logger=console for logging into the console. * *

* Known issues: temporary files with loaded native libraries are not deleted on * application exit because JVM does not close handles to them. The loader * attempts to delete them on next launch. The list of these temporary files is * preserved in the "[user.home]/.JarClassLoader" file. *

* See also discussion "How load library from jar file?" * http://discuss.develop.com * /archives/wa.exe?A2=ind0302&L=advanced-java&D=0&P=4549 Unfortunately, the * native method java.lang.ClassLoader$NativeLibrary.unload() is package * accessed in a package accessed inner class. Moreover, it's called from * finalizer. This does not allow releasing the native library handle and delete * the temporary library file. Option to explore: use JNI function * UnregisterNatives(). See also native code in * ...\jdk\src\share\native\java\lang\ClassLoader.c * * @version $Revision: 1.30 $ */ public class Bootstrap extends ClassLoader { /** VM parameter key to turn on debug logging to file or console. */ public static final String KEY_LOGGER = "JarClassLoader.logger"; public static final String CONSOLE = "console"; private PrintStream logger; protected List lstJarFile; private Set hsNativeFile; private Map> hmClass; private ProtectionDomain pd; private static final Name BOOTSTRAP_MAIN_CLASS = new Name( "Bootstrap-MainClass"); private static final Name BOOTSTRAP_CLASSPATH = new Name( "Bootstrap-Classpath"); public static void main(String[] args) { Bootstrap main = new Bootstrap(); try { main.invokeMain(args); } catch (Throwable e) { e.printStackTrace(); } } public void invokeMain(String[] args) throws Throwable { String realMainClass = getManifestBootstrapMainClass(); if (realMainClass == null) { System.out.println("main not found in manifest entry : " + BOOTSTRAP_MAIN_CLASS); System.exit(1); } invokeMain(realMainClass, args); } private String getManifestBootstrapMainClass() { Attributes attr = null; if (isLaunchedFromJar()) { try { // The first element in array is the top level JAR Manifest m = lstJarFile.get(0).getManifest(); attr = m.getMainAttributes(); } catch (IOException e) { } } return (attr == null ? null : attr.getValue(BOOTSTRAP_MAIN_CLASS)); } private String[] getManifestBoostrapClassPath() { try { Attributes attr = null; // The first element in array is the top level JAR Manifest m = lstJarFile.get(0).getManifest(); attr = m.getMainAttributes(); String value = attr.getValue(BOOTSTRAP_CLASSPATH); String[] classPath = value.split(";"); return classPath; } catch (Exception e) { return new String[] { "META-INF/lib", "WEB-INF/lib" }; } } /** * Default constructor. Defines system class loader as a parent class * loader. */ public Bootstrap() { this(ClassLoader.getSystemClassLoader()); } /** * Constructor. * * @param parent * class loader parent. */ public Bootstrap(ClassLoader parent) { super(parent); String sLogger = System.getProperty(KEY_LOGGER); if (sLogger != null) { if (sLogger.equals(CONSOLE)) { this.logger = System.out; } else { try { this.logger = new PrintStream(sLogger); } catch (FileNotFoundException e) { throw new RuntimeException( "JarClassLoader: cannot create log file: " + e); } } } hmClass = new HashMap>(); lstJarFile = new ArrayList(); hsNativeFile = new HashSet(); String sUrlTopJAR = null; try { pd = getClass().getProtectionDomain(); CodeSource cs = pd.getCodeSource(); URL urlTopJAR = cs.getLocation(); // URL.getFile() returns "/C:/my%20dir/MyApp.jar" sUrlTopJAR = URLDecoder.decode(urlTopJAR.getFile(), "UTF-8"); log("Loading from top JAR: %s", sUrlTopJAR); loadJar(new JarFile(sUrlTopJAR)); // throws if not JAR } catch (IOException e) { // Expected exception: loading NOT from JAR. log("Not a JAR: %s %s", sUrlTopJAR, e.toString()); return; } // Runtime.getRuntime().addShutdownHook(new Thread() { // public void run() { // log("shutdown hook started"); // shutdown(); // } // }); } // JarClassLoader() // --------------------------------separator-------------------------------- static int ______INIT; /** * Using temp files (one per inner JAR/DLL) solves many issues: 1. There are * no ways to load JAR defined in a JarEntry directly into the JarFile * object. 2. Cannot use memory-mapped files because they are using nio * channels, which are not supported by JarFile ctor. 3. JarFile object * keeps opened JAR files handlers for fast access. 4. Resource in a * jar-in-jar does not have well defined URL. Making temp file with JAR * solves this problem. 5. Similar issues with native libraries: * ClassLoader.findLibrary() accepts ONLY string with absolute * path to the file with native library. 6. Option * "java.protocol.handler.pkgs" does not allow access to nested JARs(?). * * @param inf * JAR entry information * @return temporary file object presenting JAR entry * @throws Exception */ private File createTempFile(Map inf) throws Exception { byte[] a_by = FIgetJarBytes(inf); try { File file = File.createTempFile(FIgetName(inf) + ".", null); file.deleteOnExit(); BufferedOutputStream os = new BufferedOutputStream( new FileOutputStream(file)); os.write(a_by); os.close(); return file; } catch (IOException e) { throw new Exception("Cannot create temp file for " + inf.get("jarEntry"), e); } } // createTempFile() private boolean jarEntryStartWith(String[] classpaths, JarEntry je) { String name = je.getName(); for (String classpath : classpaths) { if (name.startsWith(classpath)) { return true; } } return false; } /** * Loads specified JAR * * @param jarFile * JAR file */ private void loadJar(JarFile jarFile) { lstJarFile.add(jarFile); try { Enumeration en = jarFile.entries(); final String EXT_JAR = ".jar"; String[] classpaths = getManifestBoostrapClassPath(); while (en.hasMoreElements()) { JarEntry je = en.nextElement(); if (je.isDirectory() || !jarEntryStartWith(classpaths, je)) { continue; } // System.out.println("load :" + je.getName()); String s = je.getName().toLowerCase(); // JarEntry name if (s.lastIndexOf(EXT_JAR) == s.length() - EXT_JAR.length()) { Map inf = FIbuildJarFileInfo(jarFile, je); File file = createTempFile(inf); log("Loading inner JAR %s from temp file %s", inf.get("jarEntry"), getFilename4Log(file)); try { loadJar(new JarFile(file)); } catch (IOException e) { throw new Exception("Cannot load inner JAR " + inf.get("jarEntry"), e); } } } } catch (Exception e) { throw new RuntimeException("ERROR on loading InnerJAR", e); } } // loadJar() private Map findJarEntry(String sName) { for (JarFile jarFile : lstJarFile) { JarEntry jarEntry = jarFile.getJarEntry(sName); if (jarEntry != null) { return FIbuildJarFileInfo(jarFile, jarEntry); } } return null; } // findJarEntry() private List> findJarEntries(String sName) { List> lst = new ArrayList>(); for (JarFile jarFile : lstJarFile) { JarEntry jarEntry = jarFile.getJarEntry(sName); if (jarEntry != null) { lst.add(FIbuildJarFileInfo(jarFile, jarEntry)); } } return lst; } // findJarEntries() /** * Finds native library entry. * * @param sLib * Library name. For example for the library name "Native" the * Windows returns entry "Native.dll", the Linux returns entry * "libNative.so", the Mac returns entry "libNative.jnilib". * * @return Native library entry */ private Map findJarNativeEntry(String sLib) { String sName = System.mapLibraryName(sLib); for (JarFile jarFile : lstJarFile) { Enumeration en = jarFile.entries(); while (en.hasMoreElements()) { JarEntry je = en.nextElement(); if (je.isDirectory()) { continue; // directory is a ZipEntry which name ends with // "/" } // Example: sName is "Native.dll" String sEntry = je.getName(); // "Native.dll" or // "abc/xyz/Native.dll" // sName "Native.dll" could be found, for example // - in the path: abc/Native.dll/xyz/my.dll <-- do not load this // one! // - in the partial name: abc/aNative.dll <-- do not load this // one! String[] token = sEntry.split("/"); // the last token is library // name if (token.length > 0 && token[token.length - 1].equals(sName)) { log("Loading native library '%s' found as '%s' in JAR %s", sLib, sEntry, jarFile.getName()); return FIbuildJarFileInfo(jarFile, je); } } } return null; } // findJarNativeEntry() /** * Loads class from a JAR and searches for all jar-in-jar. * * @param sClassName * class to load * @return loaded class * @throws Exception */ private Class findJarClass(String sClassName) throws Exception { // http://java.sun.com/developer/onlineTraining/Security/Fundamentals // /magercises/ClassLoader/solution/FileClassLoader.java Class c = hmClass.get(sClassName); if (c != null) { return c; } // Char '/' works for Win32 and Unix. String sName = sClassName.replace('.', '/') + ".class"; Map inf = findJarEntry(sName); if (inf != null) { definePackage(sClassName, inf); byte[] a_by = FIgetJarBytes(inf); try { c = defineClass(sClassName, a_by, 0, a_by.length, pd); } catch (ClassFormatError e) { throw new Exception(null, e); } } if (c == null) { throw new Exception(sClassName); } hmClass.put(sClassName, c); return c; } // findJarClass() /** * The default ClassLoader.defineClass() does not create * package for the loaded class and leaves it null. Each package referenced * by this class loader must be created only once before the * ClassLoader.defineClass() call. The base class * ClassLoader keeps cache with created packages for reuse. * * @param sClassName * class to load * @throws IllegalArgumentException * If package name duplicates an existing package either in this * class loader or one of its ancestors */ private void definePackage(String sClassName, Map inf) throws IllegalArgumentException { int pos = sClassName.lastIndexOf('.'); String sPackageName = pos > 0 ? sClassName.substring(0, pos) : ""; if (getPackage(sPackageName) == null) { definePackage(sPackageName, FIgetSpecificationTitle(inf), FIgetSpecificationVersion(inf), FIgetSpecificationVendor(inf), FIgetImplementationTitle(inf), FIgetImplementationVersion(inf), FIgetImplementationVendor(inf), FIgetSealURL(inf)); } } // --------------------------------separator-------------------------------- static int ______SHUTDOWN; /** * Called on shutdown for temporary files cleanup */ private void shutdown() { // All inner JAR temporary files are marked at the time of creation // as deleteOnExit(). These files are not deleted if they are not // closed. for (JarFile jarFile : lstJarFile) { try { jarFile.close(); } catch (IOException e) { // Ignore. In the worst case temp files will accumulate. } } // JVM does not close handles to native libraries files // and temp files even marked closeOnExit() are not deleted. // Use special file with list of native libraries temp files // to delete them on next application run. String sPersistentFile = System.getProperty("user.home") + File.separator + ".JarClassLoader"; deleteOldNative(sPersistentFile); persistNewNative(sPersistentFile); } // shutdown() /** * Deletes temporary files listed in the file. The method is called on * shutdown(). * * @param sPersistentFile * file name with temporary files list */ private void deleteOldNative(String sPersistentFile) { BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(sPersistentFile)); String sLine; while ((sLine = reader.readLine()) != null) { File file = new File(sLine); if (!file.exists()) { continue; // already deleted; from command line? } if (!file.delete()) { // Cannot delete, will try next time. hsNativeFile.add(file); } } } catch (IOException e) { // Ignore. In the worst case temp files will accumulate. } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { } } } } // deleteOldNative() /** * Creates file with temporary files list. This list will be used to delete * temporary files on the next application launch. The method is called from * shutdown(). * * @param sPersistentFile * file name with temporary files list */ private void persistNewNative(String sPersistentFile) { BufferedWriter writer = null; try { writer = new BufferedWriter(new FileWriter(sPersistentFile)); for (File fileNative : hsNativeFile) { writer.write(fileNative.getCanonicalPath()); writer.newLine(); // The temporary file with native library is marked // as deleteOnExit() but VM does not close it and it remains // open. // Attempt to explicitly delete the file fails with "false" // because VM does not release the file handle. fileNative.delete(); // returns "false" } } catch (IOException e) { // Ignore. In the worst case temp files will accumulate. } finally { if (writer != null) { try { writer.close(); } catch (IOException e) { } } } } // persistNewNative() // --------------------------------separator-------------------------------- static int ______ACCESS; /** * Checks how the application was loaded: from JAR or file system. * * @return true if application was started from JAR */ public boolean isLaunchedFromJar() { return (lstJarFile.size() > 0); } // isLaunchedFromJar() /** * Returns the name of the jar file main class, or null if no "Main-Class" * manifest attributes was defined. * * @return main class declared in JAR's manifest */ public String getManifestMainClass() { Attributes attr = null; if (isLaunchedFromJar()) { try { // The first element in array is the top level JAR Manifest m = lstJarFile.get(0).getManifest(); attr = m.getMainAttributes(); } catch (IOException e) { } } return (attr == null ? null : attr.getValue(Attributes.Name.MAIN_CLASS)); } /** * Invokes main() method on class with provided parameters. * * @param sClass * class name in form "MyClass" for default package or * "com.abc.MyClass" for class in some package * * @param args * arguments for the main() method or null * * @throws Throwable * wrapper for many exceptions thrown while *

* (1) main() method lookup: ClassNotFoundException, * SecurityException, NoSuchMethodException *

* (2) main() method launch: IllegalArgumentException, * IllegalAccessException (disabled) *

* (3) Actual cause of InvocationTargetException * * See * http://java.sun.com/developer/Books/javaprogramming/JAR/api * /jarclassloader.html and * http://java.sun.com/developer/Books/javaprogramming * /JAR/api/example-1dot2/JarClassLoader.java */ public void invokeMain(String sClass, String[] args) throws Throwable { // The default is sun.misc.Launcher$AppClassLoader (run from file system // or JAR) Thread.currentThread().setContextClassLoader(this); Class clazz = loadClass(sClass); log("Launch: %s.main(); Loader: %s", sClass, clazz.getClassLoader()); Method method = clazz.getMethod("main", new Class[] { String[].class }); boolean bValidModifiers = false; boolean bValidVoid = false; if (method != null) { method.setAccessible(true); // Disable IllegalAccessException int nModifiers = method.getModifiers(); // main() must be // "public static" bValidModifiers = Modifier.isPublic(nModifiers) && Modifier.isStatic(nModifiers); Class clazzRet = method.getReturnType(); // main() must be "void" bValidVoid = (clazzRet == void.class); } if (method == null || !bValidModifiers || !bValidVoid) { throw new NoSuchMethodException("The main() method in class \"" + sClass + "\" not found."); } // Invoke method. // Crazy cast "(Object)args" because param is: "Object... args" try { method.invoke(null, (Object) args); } catch (InvocationTargetException e) { throw e.getTargetException(); } } // invokeMain() // --------------------------------separator-------------------------------- static int ______OVERRIDE; /** * Class loader JavaDoc encourages overriding findClass(String) in derived * class rather than overriding this method. This does not work for loading * classes from a JAR. Default implementation of loadClass() is able to load * a class from a JAR without calling findClass(). This will "infect" the * loaded class with a system class loader. The system class loader will be * used to load all dependent classes and will fail for jar-in-jar classes. * * See also: http://www.cs.purdue.edu/homes/jv/smc/pubs/liang-oopsla98.pdf */ @Override protected synchronized Class loadClass(String sClassName, boolean bResolve) throws ClassNotFoundException { log("LOADING %s (resolve=%b)", sClassName, bResolve); Class c = null; try { // Step 1. Load from JAR. if (isLaunchedFromJar()) { try { c = findJarClass(sClassName); log("Loaded %s from JAR by %s", sClassName, getClass() .getName()); return c; } catch (Exception e) { if (e.getCause() == null) { log("Not found %s in JAR by %s: %s", sClassName, getClass().getName(), e.getMessage()); } else { log("Error loading %s in JAR by %s: %s", sClassName, getClass().getName(), e.getCause()); } // keep looking... } } // Step 2. Load by parent (usually system) class loader. // Call findSystemClass() AFTER attempt to find in a JAR. // If it called BEFORE it will load class-in-jar using // SystemClassLoader and "infect" it with SystemClassLoader. // The SystemClassLoader will be used to load all dependent // classes. SystemClassLoader will fail to load a class from // jar-in-jar and to load dll-in-jar. try { // No need to call findLoadedClass(sClassName) because it's // called inside: ClassLoader cl = getParent(); c = cl.loadClass(sClassName); log("Loaded %s by %s", sClassName, cl.getClass().getName()); return c; } catch (ClassNotFoundException e) { } // What else? throw new ClassNotFoundException("Failure to load: " + sClassName); } finally { if (c != null && bResolve) { resolveClass(c); } } } // loadClass() /** * @see java.lang.ClassLoader#findResource(java.lang.String) */ @Override protected URL findResource(String sName) { log("findResource: %s", sName); if (isLaunchedFromJar()) { Map inf = findJarEntry(sName); return inf == null ? null : FIgetURL(inf); } return super.findResource(sName); } /** * @see java.lang.ClassLoader#findResources(java.lang.String) */ @Override public Enumeration findResources(String sName) throws IOException { log("getResources: %s", sName); if (isLaunchedFromJar()) { List> lstJarEntry = findJarEntries(sName); List lstURL = new ArrayList(); for (Map inf : lstJarEntry) { URL url = FIgetURL(inf); if (url != null) { lstURL.add(url); } } return Collections.enumeration(lstURL); } return super.findResources(sName); } // getResources() /** * @see java.lang.ClassLoader#findLibrary(java.lang.String) */ @Override protected String findLibrary(String sLib) { log("findLibrary: %s", sLib); Map inf = findJarNativeEntry(sLib); if (inf != null) { try { File fileNative = createTempFile(inf); log("Loading native library %s from temp file %s", inf.get("jarEntry"), getFilename4Log(fileNative)); hsNativeFile.add(fileNative); return fileNative.getAbsolutePath(); } catch (Exception e) { log("Failure to load native library %s: %s", sLib, e.toString()); } } return null; } // findLibrary() // --------------------------------separator-------------------------------- static int ______HELPERS; private String getFilename4Log(File file) { if (logger != null) { try { // In form "C:\Documents and Settings\..." return file.getCanonicalPath(); } catch (IOException e) { // In form "C:\DOCUME~1\..." return file.getAbsolutePath(); } } return null; } // getFilename4Log() private void log(String sMsg, Object... obj) { if (logger != null) { logger.printf("JarClassLoader: " + sMsg + "\n", obj); } } // log() Map FIbuildJarFileInfo(JarFile jarFile, JarEntry jarEntry) { Map fi = new HashMap(); fi.put("jarFile", jarFile); fi.put("jarEntry", jarEntry); try { fi.put("mf", jarFile.getManifest()); } catch (IOException e) { fi.put("mf", new Manifest()); } return fi; } URL FIgetURL(Map jarFileInfo) { try { return new URL("jar:file:" + ((JarFile) jarFileInfo.get("jarFile")).getName() + "!/" + ((JarEntry) jarFileInfo.get("jarEntry"))); } catch (MalformedURLException e) { return null; } } String FIgetName(Map jarFileInfo) { return ((JarEntry) jarFileInfo.get("jarEntry")).getName().replace('/', '_'); } String FIgetSpecificationTitle(Map jarFileInfo) { return ((Manifest) jarFileInfo.get("mf")).getMainAttributes().getValue( Name.SPECIFICATION_TITLE); } String FIgetSpecificationVersion(Map jarFileInfo) { return ((Manifest) jarFileInfo.get("mf")).getMainAttributes().getValue( Name.SPECIFICATION_VERSION); } String FIgetSpecificationVendor(Map jarFileInfo) { return ((Manifest) jarFileInfo.get("mf")).getMainAttributes().getValue( Name.SPECIFICATION_VENDOR); } String FIgetImplementationTitle(Map jarFileInfo) { return ((Manifest) jarFileInfo.get("mf")).getMainAttributes().getValue( Name.IMPLEMENTATION_TITLE); } String FIgetImplementationVersion(Map jarFileInfo) { return ((Manifest) jarFileInfo.get("mf")).getMainAttributes().getValue( Name.IMPLEMENTATION_VERSION); } String FIgetImplementationVendor(Map jarFileInfo) { return ((Manifest) jarFileInfo.get("mf")).getMainAttributes().getValue( Name.IMPLEMENTATION_VENDOR); } URL FIgetSealURL(Map jarFileInfo) { String seal = ((Manifest) jarFileInfo.get("mf")).getMainAttributes() .getValue(Name.SEALED); if (seal != null) try { return new URL(seal); } catch (MalformedURLException e) { // Ignore, will return null } return null; } byte[] FIgetJarBytes(Map jarFileInfo) throws Exception { DataInputStream dis = null; byte[] a_by = null; try { long lSize = ((JarEntry) jarFileInfo.get("jarEntry")).getSize(); if (lSize <= 0 || lSize >= Integer.MAX_VALUE) { throw new Exception("Invalid size " + lSize + " for entry " + ((JarEntry) jarFileInfo.get("jarEntry"))); } a_by = new byte[(int) lSize]; InputStream is = ((JarFile) jarFileInfo.get("jarFile")) .getInputStream(((JarEntry) jarFileInfo.get("jarEntry"))); dis = new DataInputStream(is); dis.readFully(a_by); } catch (IOException e) { throw new Exception(null, e); } finally { if (dis != null) { try { dis.close(); } catch (IOException e) { } } } return a_by; } // getJarBytes() // /** // * Inner class with JAR entry information. Keeps JAR file and entry // object. // */ // private static class Map { // JarFile jarFile; // JarEntry jarEntry; // Manifest mf; // required for package creation // // Map(JarFile jarFile, JarEntry jarEntry) { // this.jarFile = jarFile; // this.jarEntry = jarEntry; // try { // this.mf = jarFile.getManifest(); // } catch (IOException e) { // // Manifest does not exist or not available // this.mf = new Manifest(); // } // } // // URL getURL() { // try { // return new URL("jar:file:" + jarFile.getName() + "!/" // + jarEntry); // } catch (MalformedURLException e) { // return null; // } // } // // String getName() { // return jarEntry.getName().replace('/', '_'); // } // // String getSpecificationTitle() { // return mf.getMainAttributes().getValue(Name.SPECIFICATION_TITLE); // } // // String getSpecificationVersion() { // return mf.getMainAttributes().getValue(Name.SPECIFICATION_VERSION); // } // // String getSpecificationVendor() { // return mf.getMainAttributes().getValue(Name.SPECIFICATION_VENDOR); // } // // String getImplementationTitle() { // return mf.getMainAttributes().getValue(Name.IMPLEMENTATION_TITLE); // } // // String getImplementationVersion() { // return mf.getMainAttributes().getValue(Name.IMPLEMENTATION_VERSION); // } // // String getImplementationVendor() { // return mf.getMainAttributes().getValue(Name.IMPLEMENTATION_VENDOR); // } // // URL getSealURL() { // String seal = mf.getMainAttributes().getValue(Name.SEALED); // if (seal != null) // try { // return new URL(seal); // } catch (MalformedURLException e) { // // Ignore, will return null // } // return null; // } // // @Override // public String toString() { // return "JAR: " + jarFile.getName() + " ENTRY: " + jarEntry; // } // // /** // * Read JAR entry and returns byte array of this JAR entry. This is a // * helper method to load JAR entry into temporary file. // * // * @param inf // * JAR entry information object // * @return byte array for the specified JAR entry // * @throws Exception // */ // byte[] getJarBytes() throws Exception { // DataInputStream dis = null; // byte[] a_by = null; // try { // long lSize = jarEntry.getSize(); // if (lSize <= 0 || lSize >= Integer.MAX_VALUE) { // throw new Exception("Invalid size " + lSize // + " for entry " + jarEntry); // } // a_by = new byte[(int) lSize]; // InputStream is = jarFile.getInputStream(jarEntry); // dis = new DataInputStream(is); // dis.readFully(a_by); // } catch (IOException e) { // throw new Exception(null, e); // } finally { // if (dis != null) { // try { // dis.close(); // } catch (IOException e) { // } // } // } // return a_by; // } // getJarBytes() // // } // inner class Map } // class JarClassLoader





© 2015 - 2024 Weber Informatics LLC | Privacy Policy