package org.activiti.designer.util.extension; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.activiti.designer.integration.Activator; /** * Loads classes from jar files in the path provided. * * @author Tiese Barrell * @since 0.5.1 * @version 1 * */ public class JarClassLoader extends ClassLoader { private String jarFilePath; public JarClassLoader(final String jarFilePath) { if (jarFilePath == null) throw new IllegalArgumentException("Null jarFilePath"); this.jarFilePath = jarFilePath; } @SuppressWarnings({ "rawtypes", "unchecked" }) protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { // Since all support classes of loaded class use same class loader // must check subclass cache of classes for things like Object Class c = null; // First check with the parent class loader try { c = super.getParent().loadClass(name); } catch (ClassNotFoundException e) { // fail silently } c = findLoadedClass(name); if (c == null) { // first, delegate to the integration bundle's class loader try { c = Activator.class.getClassLoader().loadClass(name); } catch (ClassNotFoundException e) { // fail silently } } if (c == null) { // Convert class name argument to filename // Convert package names into subdirectories String className = name.replace('.', '/') + ".class"; try { // Load class data from file and save in byte array byte data[] = loadClassData(jarFilePath, className); // Convert byte array to Class c = defineClass(name, data, 0, data.length); // If failed, throw exception if (c == null) throw new ClassNotFoundException(name); } catch (IOException e) { throw new ClassNotFoundException("Error reading file: " + className); } } // Resolve class definition if appropriate if (resolve) resolveClass(c); // Return class just created return c; } private byte[] loadClassData(String jarFilePath, String className) throws IOException { if (className == null) { throw new IOException("Unable to load classes with null className"); } // Get jar file from the provided path JarFile file = new JarFile(jarFilePath); JarEntry entry = file.getJarEntry(className); InputStream is = file.getInputStream(entry); if (is == null) { throw new IOException("Unable to load class with name " + className + " because the inputstream was null"); } // Get size of class file int size = (int) entry.getSize(); // Reserve space to read byte buff[] = new byte[size]; // Get stream to read from DataInputStream dis = new DataInputStream(is); // Read in data dis.readFully(buff); // close stream dis.close(); // return data return buff; } }