Java tutorial
/* * Copyright 2015 Crosstree Labs. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file 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. */ package com.crosstreelabs.cognitio.common; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.net.URLStreamHandlerFactory; import java.security.AccessControlContext; import java.util.StringTokenizer; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ExtensionLoader extends URLClassLoader { private static final Logger LOGGER = LoggerFactory.getLogger(ExtensionLoader.class); public ExtensionLoader(URL[] urls) { super(urls); } public ExtensionLoader(URL[] urls, ClassLoader cl) { super(urls, cl); } public ExtensionLoader(URL[] urls, ClassLoader cl, URLStreamHandlerFactory urlshf) { super(urls, cl, urlshf); } /** * Add given path(s) to the loader's classpath. * * The single argument may optionally be a semi-colon (;) delimited list of * paths in much the same way a normal class definition would be. * * Paths may either point to a jar, or a directory containing jars. * Directories should end with a slash (/), otherwise they will be * interpreted as jar paths. * // * A path may contain a wildcard name. // * // * Add classPath to this loader's classpath. // * <p> // * The classpath may contain elements that include a generic file base name. // * A generic basename is a filename without the extension that may begin // * and/or end with an asterisk. Use of the asterisk denotes a partial match. // * Any files with an extension of ".jar" whose base name match the specified // * basename will be added to this class loaders classpath. The case of the // * filename is ignored. For example "/somedir/*abc" means all files in // * somedir that end with "abc.jar", "/somedir/abc*" means all files that // * start with "abc" and end with ".jar", and "/somedir/*abc*" means all // * files that contain "abc" and end with ".jar". * */ public void add(final String raw) throws MalformedURLException { LOGGER.error("Adding classpath: {}", raw); final String[] paths = raw.split(";"); for (String path : paths) { handlePath(path); } // String separators = File.pathSeparator; // if (!separators.equals(";")) { // separators += ";"; // } // String XXXXpathElement = ""; // for (StringTokenizer tokenizer = new StringTokenizer(raw, separators, false); // tokenizer.hasMoreTokens(); // XXXXpathElement = tokenizer.nextToken()) { // File XXXXfileElement; // String bn = null; // // if (XXXXpathElement.isEmpty()) { // continue; // } // // XXXXfileElement = new File(XXXXpathElement); // if (XXXXfileElement.getName().indexOf('*') != -1) { // bn = XXXXfileElement.getName(); // XXXXfileElement = XXXXfileElement.getParentFile(); // } // // if (!XXXXfileElement.isAbsolute() && XXXXpathElement.charAt(0) != '/' && XXXXpathElement.charAt(0) != '\\') { // XXXXfileElement = new File(rootPath, XXXXfileElement.getPath()); // } // try { // XXXXfileElement = XXXXfileElement.getCanonicalFile(); // } catch (IOException thr) { // LOGGER.warn("Skipping non-existent classpath element '" + XXXXfileElement + "' (" + thr + ")."); // continue; // } // if (!StringUtils.isBlank(bn)) { // XXXXfileElement = new File(XXXXfileElement, bn); // } // if (classPathElements.contains(XXXXfileElement.getPath())) { // LOGGER.warn("Skipping duplicate classpath element '" + XXXXfileElement + "'."); // continue; // } else { // this. // classPathElements.add(XXXXfileElement.getPath()); // } // // if (!StringUtils.isBlank(bn)) { // addJars(XXXXfileElement.getParentFile(), bn); // } else if (!XXXXfileElement.exists()) { // s/never be due getCanonicalFile() above // LOGGER.warn("Could not find classpath element '" + XXXXfileElement + "'"); // } else if (XXXXfileElement.isDirectory()) { // addURL(createUrl(XXXXfileElement)); // } else if (XXXXfileElement.getName().toLowerCase().endsWith(".zip") || XXXXfileElement.getName().toLowerCase().endsWith(".jar")) { // addURL(createUrl(XXXXfileElement)); // } else { // LOGGER.warn("ClassPath element '" + XXXXfileElement + "' is not an existing directory and is not a file ending with '.zip' or '.jar'"); // } // } // LOGGER.info("Class loader is using classpath: \"" + classPath + "\"."); } protected void handlePath(final String path) throws MalformedURLException { if (path == null || path.isEmpty()) { return; } if (!path.trim().toLowerCase().endsWith(File.separator)) { addJar(path); return; } // We're dealing with a directory, so let's find all jars File dir = new File(path); File[] files = dir.listFiles(new FilenameFilter() { @Override public boolean accept(File file, String name) { return name.endsWith(".jar"); } }); for (File file : files) { addJar(file.getAbsolutePath()); } } public void addJar(String path) throws MalformedURLException { File file; if (!path.endsWith(".jar")) { file = new File(path + ".jar"); } else { file = new File(path); } if (!file.exists()) { LOGGER.warn("Could not find jar at {}", file); return; } if (!file.canRead()) { LOGGER.warn("Could not read jar at {}", file); return; } addURL(file.toURL()); } // private URL createUrl(File fe) { // try { // URL url = fe.toURI().toURL(); // LOGGER.diagln("Added URL: '" + url.toString() + "'"); // if (classPath.length() > 0) { // classPath += File.pathSeparator; // } // this.classPath += fe.getPath(); // return url; // } catch (MalformedURLException thr) { // LOGGER.diagln("Classpath element '" + fe + "' could not be used to create a valid file system URL"); // return null; // } // } }