1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielski package com.sun.star.lib.loader; 25*b1cdbd2cSJim Jagielski 26*b1cdbd2cSJim Jagielski import java.io.File; 27*b1cdbd2cSJim Jagielski import java.io.IOException; 28*b1cdbd2cSJim Jagielski import java.io.InputStream; 29*b1cdbd2cSJim Jagielski import java.io.UnsupportedEncodingException; 30*b1cdbd2cSJim Jagielski import java.lang.reflect.InvocationTargetException; 31*b1cdbd2cSJim Jagielski import java.lang.reflect.Method; 32*b1cdbd2cSJim Jagielski import java.net.JarURLConnection; 33*b1cdbd2cSJim Jagielski import java.net.MalformedURLException; 34*b1cdbd2cSJim Jagielski import java.net.URL; 35*b1cdbd2cSJim Jagielski import java.net.URLClassLoader; 36*b1cdbd2cSJim Jagielski import java.util.Enumeration; 37*b1cdbd2cSJim Jagielski import java.util.jar.Attributes; 38*b1cdbd2cSJim Jagielski import java.util.jar.Manifest; 39*b1cdbd2cSJim Jagielski import java.util.StringTokenizer; 40*b1cdbd2cSJim Jagielski import java.util.Vector; 41*b1cdbd2cSJim Jagielski 42*b1cdbd2cSJim Jagielski /** 43*b1cdbd2cSJim Jagielski * This class can be used as a loader for application classes which use UNO. 44*b1cdbd2cSJim Jagielski * 45*b1cdbd2cSJim Jagielski * <p>The Loader class detects a UNO installation on the system and adds the 46*b1cdbd2cSJim Jagielski * UNO jar files to the search path of a customized class loader, which is used 47*b1cdbd2cSJim Jagielski * for loading the application classes.</p> 48*b1cdbd2cSJim Jagielski */ 49*b1cdbd2cSJim Jagielski public final class Loader { 50*b1cdbd2cSJim Jagielski 51*b1cdbd2cSJim Jagielski private static ClassLoader m_Loader = null; 52*b1cdbd2cSJim Jagielski 53*b1cdbd2cSJim Jagielski /** 54*b1cdbd2cSJim Jagielski * do not instantiate 55*b1cdbd2cSJim Jagielski */ Loader()56*b1cdbd2cSJim Jagielski private Loader() {} 57*b1cdbd2cSJim Jagielski 58*b1cdbd2cSJim Jagielski /** 59*b1cdbd2cSJim Jagielski * The main method instantiates a customized class loader with the 60*b1cdbd2cSJim Jagielski * UNO jar files added to the search path and loads the application class, 61*b1cdbd2cSJim Jagielski * which is specified in the Main-Class attribute of the 62*b1cdbd2cSJim Jagielski * com/sun/star/lib/Loader.class entry of the manifest file or 63*b1cdbd2cSJim Jagielski * as first parameter in the argument list. 64*b1cdbd2cSJim Jagielski */ main( String[] arguments )65*b1cdbd2cSJim Jagielski public static void main( String[] arguments ) throws Exception { 66*b1cdbd2cSJim Jagielski 67*b1cdbd2cSJim Jagielski // get the name of the class to be loaded from the manifest 68*b1cdbd2cSJim Jagielski String className = null; 69*b1cdbd2cSJim Jagielski Class clazz = Loader.class; 70*b1cdbd2cSJim Jagielski ClassLoader loader = clazz.getClassLoader(); 71*b1cdbd2cSJim Jagielski Vector res = new Vector(); 72*b1cdbd2cSJim Jagielski try { 73*b1cdbd2cSJim Jagielski Enumeration en = loader.getResources( "META-INF/MANIFEST.MF" ); 74*b1cdbd2cSJim Jagielski while ( en.hasMoreElements() ) { 75*b1cdbd2cSJim Jagielski res.add( (URL) en.nextElement() ); 76*b1cdbd2cSJim Jagielski } 77*b1cdbd2cSJim Jagielski // the jarfile with the com/sun/star/lib/loader/Loader.class 78*b1cdbd2cSJim Jagielski // per-entry attribute is most probably the last resource in the 79*b1cdbd2cSJim Jagielski // list, therefore search backwards 80*b1cdbd2cSJim Jagielski for ( int i = res.size() - 1; i >= 0; i-- ) { 81*b1cdbd2cSJim Jagielski URL jarurl = (URL) res.elementAt( i ); 82*b1cdbd2cSJim Jagielski try { 83*b1cdbd2cSJim Jagielski JarURLConnection jarConnection = 84*b1cdbd2cSJim Jagielski (JarURLConnection) jarurl.openConnection(); 85*b1cdbd2cSJim Jagielski Manifest mf = jarConnection.getManifest(); 86*b1cdbd2cSJim Jagielski Attributes attrs = (Attributes) mf.getAttributes( 87*b1cdbd2cSJim Jagielski "com/sun/star/lib/loader/Loader.class" ); 88*b1cdbd2cSJim Jagielski if ( attrs != null ) { 89*b1cdbd2cSJim Jagielski className = attrs.getValue( "Application-Class" ); 90*b1cdbd2cSJim Jagielski if ( className != null ) 91*b1cdbd2cSJim Jagielski break; 92*b1cdbd2cSJim Jagielski } 93*b1cdbd2cSJim Jagielski } catch ( IOException e ) { 94*b1cdbd2cSJim Jagielski // if an I/O error occurs when opening a new 95*b1cdbd2cSJim Jagielski // JarURLConnection, ignore this manifest file 96*b1cdbd2cSJim Jagielski System.err.println( "com.sun.star.lib.loader.Loader::" + 97*b1cdbd2cSJim Jagielski "main: bad manifest file: " + e ); 98*b1cdbd2cSJim Jagielski } 99*b1cdbd2cSJim Jagielski } 100*b1cdbd2cSJim Jagielski } catch ( IOException e ) { 101*b1cdbd2cSJim Jagielski // if an I/O error occurs when getting the manifest resources, 102*b1cdbd2cSJim Jagielski // try to get the name of the class to be loaded from the argument 103*b1cdbd2cSJim Jagielski // list 104*b1cdbd2cSJim Jagielski System.err.println( "com.sun.star.lib.loader.Loader::" + 105*b1cdbd2cSJim Jagielski "main: cannot get manifest resources: " + e ); 106*b1cdbd2cSJim Jagielski } 107*b1cdbd2cSJim Jagielski 108*b1cdbd2cSJim Jagielski // if no manifest entry was found, get the name of the class 109*b1cdbd2cSJim Jagielski // to be loaded from the argument list 110*b1cdbd2cSJim Jagielski String[] args; 111*b1cdbd2cSJim Jagielski if ( className == null ) { 112*b1cdbd2cSJim Jagielski if ( arguments.length > 0 ) { 113*b1cdbd2cSJim Jagielski className = arguments[0]; 114*b1cdbd2cSJim Jagielski args = new String[arguments.length - 1]; 115*b1cdbd2cSJim Jagielski System.arraycopy( arguments, 1, args, 0, args.length ); 116*b1cdbd2cSJim Jagielski } else { 117*b1cdbd2cSJim Jagielski throw new IllegalArgumentException( 118*b1cdbd2cSJim Jagielski "The name of the class to be loaded must be either " + 119*b1cdbd2cSJim Jagielski "specified in the Main-Class attribute of the " + 120*b1cdbd2cSJim Jagielski "com/sun/star/lib/loader/Loader.class entry " + 121*b1cdbd2cSJim Jagielski "of the manifest file or as a command line argument." ); 122*b1cdbd2cSJim Jagielski } 123*b1cdbd2cSJim Jagielski } else { 124*b1cdbd2cSJim Jagielski args = arguments; 125*b1cdbd2cSJim Jagielski } 126*b1cdbd2cSJim Jagielski 127*b1cdbd2cSJim Jagielski // load the class with the customized class loader and 128*b1cdbd2cSJim Jagielski // invoke the main method 129*b1cdbd2cSJim Jagielski if ( className != null ) { 130*b1cdbd2cSJim Jagielski ClassLoader cl = getCustomLoader(); 131*b1cdbd2cSJim Jagielski Thread.currentThread().setContextClassLoader(cl); 132*b1cdbd2cSJim Jagielski Class c = cl.loadClass( className ); 133*b1cdbd2cSJim Jagielski Method m = c.getMethod( "main", new Class[] { String[].class } ); 134*b1cdbd2cSJim Jagielski m.invoke( null, new Object[] { args } ); 135*b1cdbd2cSJim Jagielski } 136*b1cdbd2cSJim Jagielski } 137*b1cdbd2cSJim Jagielski 138*b1cdbd2cSJim Jagielski /** 139*b1cdbd2cSJim Jagielski * Gets the customized class loader with the UNO jar files added to the 140*b1cdbd2cSJim Jagielski * search path. 141*b1cdbd2cSJim Jagielski * 142*b1cdbd2cSJim Jagielski * @return the customized class loader 143*b1cdbd2cSJim Jagielski */ getCustomLoader()144*b1cdbd2cSJim Jagielski public static synchronized ClassLoader getCustomLoader() { 145*b1cdbd2cSJim Jagielski 146*b1cdbd2cSJim Jagielski final String CLASSESDIR = "classes"; 147*b1cdbd2cSJim Jagielski final String JUHJAR = "juh.jar"; 148*b1cdbd2cSJim Jagielski 149*b1cdbd2cSJim Jagielski if ( m_Loader == null ) { 150*b1cdbd2cSJim Jagielski 151*b1cdbd2cSJim Jagielski // get the urls from which to load classes and resources 152*b1cdbd2cSJim Jagielski // from the class path 153*b1cdbd2cSJim Jagielski Vector vec = new Vector(); 154*b1cdbd2cSJim Jagielski String classpath = null; 155*b1cdbd2cSJim Jagielski try { 156*b1cdbd2cSJim Jagielski classpath = System.getProperty( "java.class.path" ); 157*b1cdbd2cSJim Jagielski } catch ( SecurityException e ) { 158*b1cdbd2cSJim Jagielski // don't add the class path entries to the list of class 159*b1cdbd2cSJim Jagielski // loader URLs 160*b1cdbd2cSJim Jagielski System.err.println( "com.sun.star.lib.loader.Loader::" + 161*b1cdbd2cSJim Jagielski "getCustomLoader: cannot get system property " + 162*b1cdbd2cSJim Jagielski "java.class.path: " + e ); 163*b1cdbd2cSJim Jagielski } 164*b1cdbd2cSJim Jagielski if ( classpath != null ) { 165*b1cdbd2cSJim Jagielski addUrls(vec, classpath, File.pathSeparator); 166*b1cdbd2cSJim Jagielski } 167*b1cdbd2cSJim Jagielski 168*b1cdbd2cSJim Jagielski // get the urls from which to load classes and resources 169*b1cdbd2cSJim Jagielski // from the UNO installation 170*b1cdbd2cSJim Jagielski String path = InstallationFinder.getPath(); 171*b1cdbd2cSJim Jagielski if ( path != null ) { 172*b1cdbd2cSJim Jagielski File fClassesDir = new File( path, CLASSESDIR ); 173*b1cdbd2cSJim Jagielski File fJuh = new File( fClassesDir, JUHJAR ); 174*b1cdbd2cSJim Jagielski if ( fJuh.exists() ) { 175*b1cdbd2cSJim Jagielski URL[] clurls = new URL[1]; 176*b1cdbd2cSJim Jagielski try { 177*b1cdbd2cSJim Jagielski clurls[0] = fJuh.toURL(); 178*b1cdbd2cSJim Jagielski ClassLoader cl = new CustomURLClassLoader( clurls ); 179*b1cdbd2cSJim Jagielski Class c = cl.loadClass( 180*b1cdbd2cSJim Jagielski "com.sun.star.comp.helper.UnoInfo" ); 181*b1cdbd2cSJim Jagielski Method m = c.getMethod( "getJars", (Class[]) null ); 182*b1cdbd2cSJim Jagielski URL[] jarurls = (URL[]) m.invoke( 183*b1cdbd2cSJim Jagielski null, (Object[]) null ); 184*b1cdbd2cSJim Jagielski for ( int i = 0; i < jarurls.length; i++ ) { 185*b1cdbd2cSJim Jagielski vec.add( jarurls[i] ); 186*b1cdbd2cSJim Jagielski } 187*b1cdbd2cSJim Jagielski } catch ( MalformedURLException e ) { 188*b1cdbd2cSJim Jagielski // don't add the UNO jar files to the list of class 189*b1cdbd2cSJim Jagielski // loader URLs 190*b1cdbd2cSJim Jagielski System.err.println( "com.sun.star.lib.loader.Loader::" + 191*b1cdbd2cSJim Jagielski "getCustomLoader: cannot add UNO jar files: " + e ); 192*b1cdbd2cSJim Jagielski } catch ( ClassNotFoundException e ) { 193*b1cdbd2cSJim Jagielski // don't add the UNO jar files to the list of class 194*b1cdbd2cSJim Jagielski // loader URLs 195*b1cdbd2cSJim Jagielski System.err.println( "com.sun.star.lib.loader.Loader::" + 196*b1cdbd2cSJim Jagielski "getCustomLoader: cannot add UNO jar files: " + e ); 197*b1cdbd2cSJim Jagielski } catch ( NoSuchMethodException e ) { 198*b1cdbd2cSJim Jagielski // don't add the UNO jar files to the list of class 199*b1cdbd2cSJim Jagielski // loader URLs 200*b1cdbd2cSJim Jagielski System.err.println( "com.sun.star.lib.loader.Loader::" + 201*b1cdbd2cSJim Jagielski "getCustomLoader: cannot add UNO jar files: " + e ); 202*b1cdbd2cSJim Jagielski } catch ( IllegalAccessException e ) { 203*b1cdbd2cSJim Jagielski // don't add the UNO jar files to the list of class 204*b1cdbd2cSJim Jagielski // loader URLs 205*b1cdbd2cSJim Jagielski System.err.println( "com.sun.star.lib.loader.Loader::" + 206*b1cdbd2cSJim Jagielski "getCustomLoader: cannot add UNO jar files: " + e ); 207*b1cdbd2cSJim Jagielski } catch ( InvocationTargetException e ) { 208*b1cdbd2cSJim Jagielski // don't add the UNO jar files to the list of class 209*b1cdbd2cSJim Jagielski // loader URLs 210*b1cdbd2cSJim Jagielski System.err.println( "com.sun.star.lib.loader.Loader::" + 211*b1cdbd2cSJim Jagielski "getCustomLoader: cannot add UNO jar files: " + e ); 212*b1cdbd2cSJim Jagielski } 213*b1cdbd2cSJim Jagielski } else { 214*b1cdbd2cSJim Jagielski callUnoinfo(path, vec); 215*b1cdbd2cSJim Jagielski } 216*b1cdbd2cSJim Jagielski } else { 217*b1cdbd2cSJim Jagielski System.err.println( "com.sun.star.lib.loader.Loader::" + 218*b1cdbd2cSJim Jagielski "getCustomLoader: no UNO installation found!" ); 219*b1cdbd2cSJim Jagielski } 220*b1cdbd2cSJim Jagielski 221*b1cdbd2cSJim Jagielski // copy urls to array 222*b1cdbd2cSJim Jagielski URL[] urls = new URL[vec.size()]; 223*b1cdbd2cSJim Jagielski vec.toArray( urls ); 224*b1cdbd2cSJim Jagielski 225*b1cdbd2cSJim Jagielski // instantiate class loader 226*b1cdbd2cSJim Jagielski m_Loader = new CustomURLClassLoader( urls ); 227*b1cdbd2cSJim Jagielski } 228*b1cdbd2cSJim Jagielski 229*b1cdbd2cSJim Jagielski return m_Loader; 230*b1cdbd2cSJim Jagielski } 231*b1cdbd2cSJim Jagielski addUrls(Vector urls, String data, String delimiter)232*b1cdbd2cSJim Jagielski private static void addUrls(Vector urls, String data, String delimiter) { 233*b1cdbd2cSJim Jagielski StringTokenizer tokens = new StringTokenizer( data, delimiter ); 234*b1cdbd2cSJim Jagielski while ( tokens.hasMoreTokens() ) { 235*b1cdbd2cSJim Jagielski try { 236*b1cdbd2cSJim Jagielski urls.add( new File( tokens.nextToken() ).toURL() ); 237*b1cdbd2cSJim Jagielski } catch ( MalformedURLException e ) { 238*b1cdbd2cSJim Jagielski // don't add this class path entry to the list of class loader 239*b1cdbd2cSJim Jagielski // URLs 240*b1cdbd2cSJim Jagielski System.err.println( "com.sun.star.lib.loader.Loader::" + 241*b1cdbd2cSJim Jagielski "getCustomLoader: bad pathname: " + e ); 242*b1cdbd2cSJim Jagielski } 243*b1cdbd2cSJim Jagielski } 244*b1cdbd2cSJim Jagielski } 245*b1cdbd2cSJim Jagielski callUnoinfo(String path, Vector urls)246*b1cdbd2cSJim Jagielski private static void callUnoinfo(String path, Vector urls) { 247*b1cdbd2cSJim Jagielski Process p; 248*b1cdbd2cSJim Jagielski try { 249*b1cdbd2cSJim Jagielski p = Runtime.getRuntime().exec( 250*b1cdbd2cSJim Jagielski new String[] { new File(path, "unoinfo").getPath(), "java" }); 251*b1cdbd2cSJim Jagielski } catch (IOException e) { 252*b1cdbd2cSJim Jagielski System.err.println( 253*b1cdbd2cSJim Jagielski "com.sun.star.lib.loader.Loader::getCustomLoader: exec" + 254*b1cdbd2cSJim Jagielski " unoinfo: " + e); 255*b1cdbd2cSJim Jagielski return; 256*b1cdbd2cSJim Jagielski } 257*b1cdbd2cSJim Jagielski new Drain(p.getErrorStream()).start(); 258*b1cdbd2cSJim Jagielski int code; 259*b1cdbd2cSJim Jagielski byte[] buf = new byte[1000]; 260*b1cdbd2cSJim Jagielski int n = 0; 261*b1cdbd2cSJim Jagielski try { 262*b1cdbd2cSJim Jagielski InputStream s = p.getInputStream(); 263*b1cdbd2cSJim Jagielski code = s.read(); 264*b1cdbd2cSJim Jagielski for (;;) { 265*b1cdbd2cSJim Jagielski if (n == buf.length) { 266*b1cdbd2cSJim Jagielski if (n > Integer.MAX_VALUE / 2) { 267*b1cdbd2cSJim Jagielski System.err.println( 268*b1cdbd2cSJim Jagielski "com.sun.star.lib.loader.Loader::getCustomLoader:" + 269*b1cdbd2cSJim Jagielski " too much unoinfo output"); 270*b1cdbd2cSJim Jagielski return; 271*b1cdbd2cSJim Jagielski } 272*b1cdbd2cSJim Jagielski byte[] buf2 = new byte[2 * n]; 273*b1cdbd2cSJim Jagielski for (int i = 0; i < n; ++i) { 274*b1cdbd2cSJim Jagielski buf2[i] = buf[i]; 275*b1cdbd2cSJim Jagielski } 276*b1cdbd2cSJim Jagielski buf = buf2; 277*b1cdbd2cSJim Jagielski } 278*b1cdbd2cSJim Jagielski int k = s.read(buf, n, buf.length - n); 279*b1cdbd2cSJim Jagielski if (k == -1) { 280*b1cdbd2cSJim Jagielski break; 281*b1cdbd2cSJim Jagielski } 282*b1cdbd2cSJim Jagielski n += k; 283*b1cdbd2cSJim Jagielski } 284*b1cdbd2cSJim Jagielski } catch (IOException e) { 285*b1cdbd2cSJim Jagielski System.err.println( 286*b1cdbd2cSJim Jagielski "com.sun.star.lib.loader.Loader::getCustomLoader: reading" + 287*b1cdbd2cSJim Jagielski " unoinfo output: " + e); 288*b1cdbd2cSJim Jagielski return; 289*b1cdbd2cSJim Jagielski } 290*b1cdbd2cSJim Jagielski int ev; 291*b1cdbd2cSJim Jagielski try { 292*b1cdbd2cSJim Jagielski ev = p.waitFor(); 293*b1cdbd2cSJim Jagielski } catch (InterruptedException e) { 294*b1cdbd2cSJim Jagielski Thread.currentThread().interrupt(); 295*b1cdbd2cSJim Jagielski System.err.println( 296*b1cdbd2cSJim Jagielski "com.sun.star.lib.loader.Loader::getCustomLoader: waiting for" + 297*b1cdbd2cSJim Jagielski " unoinfo: " + e); 298*b1cdbd2cSJim Jagielski return; 299*b1cdbd2cSJim Jagielski } 300*b1cdbd2cSJim Jagielski if (ev != 0) { 301*b1cdbd2cSJim Jagielski System.err.println( 302*b1cdbd2cSJim Jagielski "com.sun.star.lib.loader.Loader::getCustomLoader: unoinfo" 303*b1cdbd2cSJim Jagielski + " exit value " + n); 304*b1cdbd2cSJim Jagielski return; 305*b1cdbd2cSJim Jagielski } 306*b1cdbd2cSJim Jagielski String s; 307*b1cdbd2cSJim Jagielski if (code == '0') { 308*b1cdbd2cSJim Jagielski s = new String(buf); 309*b1cdbd2cSJim Jagielski } else if (code == '1') { 310*b1cdbd2cSJim Jagielski try { 311*b1cdbd2cSJim Jagielski s = new String(buf, "UTF-16LE"); 312*b1cdbd2cSJim Jagielski } catch (UnsupportedEncodingException e) { 313*b1cdbd2cSJim Jagielski System.err.println( 314*b1cdbd2cSJim Jagielski "com.sun.star.lib.loader.Loader::getCustomLoader:" + 315*b1cdbd2cSJim Jagielski " transforming unoinfo output: " + e); 316*b1cdbd2cSJim Jagielski return; 317*b1cdbd2cSJim Jagielski } 318*b1cdbd2cSJim Jagielski } else { 319*b1cdbd2cSJim Jagielski System.err.println( 320*b1cdbd2cSJim Jagielski "com.sun.star.lib.loader.Loader::getCustomLoader: bad unoinfo" 321*b1cdbd2cSJim Jagielski + " output"); 322*b1cdbd2cSJim Jagielski return; 323*b1cdbd2cSJim Jagielski } 324*b1cdbd2cSJim Jagielski addUrls(urls, s, "\0"); 325*b1cdbd2cSJim Jagielski } 326*b1cdbd2cSJim Jagielski 327*b1cdbd2cSJim Jagielski private static final class Drain extends Thread { Drain(InputStream stream)328*b1cdbd2cSJim Jagielski public Drain(InputStream stream) { 329*b1cdbd2cSJim Jagielski super("unoinfo stderr drain"); 330*b1cdbd2cSJim Jagielski this.stream = stream; 331*b1cdbd2cSJim Jagielski } 332*b1cdbd2cSJim Jagielski run()333*b1cdbd2cSJim Jagielski public void run() { 334*b1cdbd2cSJim Jagielski try { 335*b1cdbd2cSJim Jagielski while (stream.read() != -1) {} 336*b1cdbd2cSJim Jagielski } catch (IOException e) { /* ignored */ } 337*b1cdbd2cSJim Jagielski } 338*b1cdbd2cSJim Jagielski 339*b1cdbd2cSJim Jagielski private final InputStream stream; 340*b1cdbd2cSJim Jagielski } 341*b1cdbd2cSJim Jagielski 342*b1cdbd2cSJim Jagielski /** 343*b1cdbd2cSJim Jagielski * A customized class loader which is used to load classes and resources 344*b1cdbd2cSJim Jagielski * from a search path of user-defined URLs. 345*b1cdbd2cSJim Jagielski */ 346*b1cdbd2cSJim Jagielski private static final class CustomURLClassLoader extends URLClassLoader { 347*b1cdbd2cSJim Jagielski CustomURLClassLoader( URL[] urls )348*b1cdbd2cSJim Jagielski public CustomURLClassLoader( URL[] urls ) { 349*b1cdbd2cSJim Jagielski super( urls ); 350*b1cdbd2cSJim Jagielski } 351*b1cdbd2cSJim Jagielski findClass( String name )352*b1cdbd2cSJim Jagielski protected Class findClass( String name ) throws ClassNotFoundException { 353*b1cdbd2cSJim Jagielski // This is only called via this.loadClass -> super.loadClass -> 354*b1cdbd2cSJim Jagielski // this.findClass, after this.loadClass has already called 355*b1cdbd2cSJim Jagielski // super.findClass, so no need to call super.findClass again: 356*b1cdbd2cSJim Jagielski throw new ClassNotFoundException( name ); 357*b1cdbd2cSJim Jagielski } 358*b1cdbd2cSJim Jagielski loadClass( String name, boolean resolve )359*b1cdbd2cSJim Jagielski protected Class loadClass( String name, boolean resolve ) 360*b1cdbd2cSJim Jagielski throws ClassNotFoundException 361*b1cdbd2cSJim Jagielski { 362*b1cdbd2cSJim Jagielski Class c = findLoadedClass( name ); 363*b1cdbd2cSJim Jagielski if ( c == null ) { 364*b1cdbd2cSJim Jagielski try { 365*b1cdbd2cSJim Jagielski c = super.findClass( name ); 366*b1cdbd2cSJim Jagielski } catch ( ClassNotFoundException e ) { 367*b1cdbd2cSJim Jagielski return super.loadClass( name, resolve ); 368*b1cdbd2cSJim Jagielski } catch ( SecurityException e ) { 369*b1cdbd2cSJim Jagielski // A SecurityException "Prohibited package name: java.lang" 370*b1cdbd2cSJim Jagielski // may occur when the user added the JVM's rt.jar to the 371*b1cdbd2cSJim Jagielski // java.class.path: 372*b1cdbd2cSJim Jagielski return super.loadClass( name, resolve ); 373*b1cdbd2cSJim Jagielski } 374*b1cdbd2cSJim Jagielski } 375*b1cdbd2cSJim Jagielski if ( resolve ) { 376*b1cdbd2cSJim Jagielski resolveClass( c ); 377*b1cdbd2cSJim Jagielski } 378*b1cdbd2cSJim Jagielski return c; 379*b1cdbd2cSJim Jagielski } 380*b1cdbd2cSJim Jagielski } 381*b1cdbd2cSJim Jagielski } 382