Java tutorial
/* * polymap.org * Copyright 2009-2012, Polymap GmbH. All rights reserved. * * 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. */ package org.polymap.service.geoserver; import java.util.Arrays; import java.util.Enumeration; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import javax.imageio.ImageIO; import org.osgi.framework.Bundle; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * This ClassLoader acts like a WebAppClassLoader for the GeoServer instances. * It helps to start several GeoServers in separate (servlet) contexts. * * @see "http://www.devdaily.com/java/jwarehouse/jetty-6.1.9/modules/jetty/src/main/java/org/mortbay/jetty/webapp/WebAppClassLoader.java.shtml" * @author <a href="http://www.polymap.de">Falko Braeutigam</a> * @since 3.0 */ public class GeoServerClassLoader extends URLClassLoader { private static final Log log = LogFactory.getLog(GeoServerClassLoader.class); private ClassLoader parent; private String loaderName = "GeoServerClassLoader"; private boolean isParentLoaderPriority = false; public GeoServerClassLoader(ClassLoader parent) { super(new URL[] {}, parent); this.parent = parent; Bundle bundle = GeoServerPlugin.getDefault().getBundle(); for (Enumeration en = bundle.findEntries("lib/", "*.jar", false); en.hasMoreElements();) { URL entry = (URL) en.nextElement(); log.debug("JAR found: " + entry); addURL(entry); } // allow GeoServer/Spring to access my classes (have to be included in the bundle) addURL(bundle.getResource("build/eclipse/")); // Trigger a call to sun.awt.AppContext.getAppContext(). This will pin // the common class loader in memory but that shouldn't be an issue. ImageIO.getCacheDirectory(); } public void close() throws IOException { try { // super.close() is defined in JDK 1.7 Method m = URLClassLoader.class.getMethod("close", new Class[0]); m.invoke(this, new Object[0]); } catch (Exception e) { log.warn("" + e); } this.parent = null; } public URL getResource(String name) { //log.debug( "getResource(): path= " + name ); return super.getResource(name); } public InputStream getResourceAsStream(String name) { //log.debug( "getResourceAsStream(): path= " + name ); return super.getResourceAsStream(name); } public Enumeration<URL> getResources(String name) throws IOException { //log.debug( "getResources(): path= " + name ); return super.getResources(name); } public synchronized Class loadClass(String name) throws ClassNotFoundException { return loadClass(name, false); } protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { Class c = findLoadedClass(name); ClassNotFoundException ex = null; boolean tried_parent = false; // parent priority? if (c == null && parent != null && (isParentLoaderPriority || isSystemPath(name))) { tried_parent = true; try { c = parent.loadClass(name); } catch (ClassNotFoundException e) { ex = e; } } // find class if (c == null) { try { c = this.findClass(name); //log.debug( "loadClass(): name= " + name ); } catch (ClassNotFoundException e) { ex = e; } } // delegate parent if (c == null && parent != null && !tried_parent && !isServerPath(name)) { c = parent.loadClass(name); } if (c == null) { throw ex; } if (resolve) { resolveClass(c); } return c; } public boolean isSystemPath(String name) { //log.info( "isSystemPath(): name= " + name ); name = name.replace('/', '.'); while (name.startsWith(".")) { name = name.substring(1); } return !name.startsWith("org.geoserver.") && !name.startsWith("org.vfny.") && // !name.startsWith( "org.springframework." ) && // !name.startsWith( "org.geotools." ) && !name.startsWith("org.polymap.service.geoserver.spring"); //!name.startsWith( "sun." ); // String[] system_classes = _context.getSystemClasses(); // if (system_classes != null) { // for (int i = 0; i < system_classes.length; i++) { // boolean result = true; // String c = system_classes[i]; // } // if (c.startsWith( "-" )) { // c = c.substring( 1 ); // TODO cache result=false; } // if (c.endsWith( "." )) { // if (name.startsWith( c )) // return result; // } // else if (name.equals( c )) // return result; // } // } // return false; } public boolean isServerPath(String name) { //log.debug( "isServerPath(): name= " + name ); name = name.replace('/', '.'); while (name.startsWith(".")) { name = name.substring(1); } return false; } public String toString() { if (log.isDebugEnabled()) { return "ContextLoader@" + loaderName + "(" + Arrays.asList(getURLs()) + ") / " + parent; } return "ContextLoader@" + loaderName; } }