001/* 002 * (C) Copyright 2006-2012 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * bstefanescu, jcarsique 016 */ 017package org.nuxeo.osgi.application; 018 019import java.lang.reflect.Method; 020import java.net.URL; 021 022/** 023 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 024 * @since 5.4.2 025 */ 026public class MutableClassLoaderDelegate implements MutableClassLoader { 027 028 protected final ClassLoader cl; 029 030 protected Method addURL; 031 032 public MutableClassLoaderDelegate(ClassLoader cl) throws IllegalArgumentException { 033 this.cl = cl; 034 Class<?> clazz = cl.getClass(); 035 do { 036 try { 037 addURL = clazz.getDeclaredMethod("addURL", URL.class); 038 } catch (NoSuchMethodException e) { 039 clazz = clazz.getSuperclass(); 040 } catch (SecurityException e) { 041 throw new IllegalArgumentException("Failed to adapt class loader: " + cl.getClass(), e); 042 } 043 } while (addURL == null && clazz != null); 044 if (addURL == null) { 045 throw new IllegalArgumentException("Incompatible class loader: " + cl.getClass() 046 + ". ClassLoader must provide a method: addURL(URL url)"); 047 } 048 addURL.setAccessible(true); 049 } 050 051 @Override 052 public void addURL(URL url) { 053 try { 054 addURL.invoke(cl, url); 055 } catch (ReflectiveOperationException e) { 056 throw new RuntimeException("Failed to add URL to class loader: " + url, e); 057 } 058 } 059 060 @Override 061 public ClassLoader getClassLoader() { 062 return cl; 063 } 064 065 @Override 066 public Class<?> loadClass(String startupClass) throws ClassNotFoundException { 067 return cl.loadClass(startupClass); 068 } 069 070}