/* * RapidMiner * * Copyright (C) 2001-2009 by Rapid-I and the contributors * * Complete list of developers available at our web site: * * http://rapid-i.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ package de.mpicbg.knime.scripting.groovy.utils; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; /** * The class loader for a plugin (extending URLClassLoader). Since a plugin might depend on other plugins the URLs of * these plugins are also added to the current class loader. * * @author Ingo Mierswa */ public class PluginClassLoader extends URLClassLoader { static { // register the protocol-handler to create urls for jar-embedded jars JarJarURLConnection.register(); } public PluginClassLoader(URL[] urls, ClassLoader classLoader) { super(urls, classLoader); URL pluginJarURL = urls[0]; List<URL> urlList = collectDependcyJarURLs(pluginJarURL); for (URL url : urlList) { addURL(url); } } @Override public void addURL(URL url) { super.addURL(url); } public Class<?> loadClass(String name) throws ClassNotFoundException { Class loadedClass = findLoadedClass(name); if (loadedClass == null) { try { loadedClass = findClass(name); } catch (ClassNotFoundException e) { // Swallow exception //does not exist locally } if (loadedClass == null) { loadedClass = super.loadClass(name); } } return loadedClass; } private List<URL> collectDependcyJarURLs(URL pluginJarURL) { List<URL> dependencyURLs = new ArrayList<URL>(); try { JarFile jar = new JarFile(new File(pluginJarURL.toURI())); Enumeration<JarEntry> jarentries = jar.entries(); while (jarentries.hasMoreElements()) { JarEntry jarEntry = jarentries.nextElement(); String jarEntryName = jarEntry.getName(); if (jarEntryName.endsWith(".jar")) { // create a url for it String pluginInDepUrl = "jar:jarjar:" + pluginJarURL.toString() + "^/" + jarEntryName + "!/"; dependencyURLs.add(new URL(pluginInDepUrl)); // dependencyURLs.add(new URL(null, pluginInDepUrl, new JarJarURLStreamHandler())); } } } catch (Throwable t) { throw new RuntimeException(t); } return dependencyURLs; } @Override public String toString() { return "PluginClassLoader (" + Arrays.asList(getURLs()) + ")"; } public static void main(String[] args) throws MalformedURLException, ClassNotFoundException { URL[] urls = new URL[]{new File("/Volumes/tds/software+tools/KNIME/tdsbuilds/knime_2.1.2_current/plugins/de.mpicbg.tds.knime.hcstools_1.0.0.jar").toURL()}; PluginClassLoader loader = new PluginClassLoader(urls, PluginClassLoader.class.getClassLoader()); for (URL url : loader.getURLs()) { System.err.println("url is " + url); } // find class Class<?> aClass = loader.loadClass("de.mpicbg.tds.knime.hcstools.utils.AttributeStatistics"); // Class<?> aClass = loader.loadClass("de.mpicbg.tds.core.util.ArrayScanHelper"); System.err.println("class is " + aClass); Class<?> anotherClass = loader.loadClass("de.mpicbg.tds.core.util.ArrayScanHelper"); System.err.println("class is " + anotherClass); } }