View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17
    18  package org.apache.log4j.helpers;
    19
    20  import java.net.URL;
    21  import java.lang.IllegalAccessException;
    22  import java.lang.reflect.Method;
    23  import java.lang.reflect.InvocationTargetException;
    24
    25
    26  /***
    27     Load resources (or images) from various sources.
    28
    29    @author Ceki G&uuml;lc&uuml;
    30   */
    31
    32  public class Loader  {
    33
    34    static final String TSTR = "Caught Exception while in Loader.getResource. This may be innocuous.";
    35
    36    // We conservatively assume that we are running under Java 1.x
    37    static private boolean java1 = true;
    38
    39    static private boolean ignoreTCL = false;
    40
    41    static {
    42      String prop = OptionConverter.getSystemProperty("java.version", null);
    43
    44      if(prop != null) {
    45        int i = prop.indexOf('.');
    46        if(i != -1) {
    47  	if(prop.charAt(i+1) != '1')
    48  	  java1 = false;
    49        }
    50      }
    51      String ignoreTCLProp = OptionConverter.getSystemProperty("log4j.ignoreTCL", null);
    52      if(ignoreTCLProp != null) {
    53        ignoreTCL = OptionConverter.toBoolean(ignoreTCLProp, true);
    54      }
    55    }
    56
    57    /***
    58     *  Get a resource by delegating to getResource(String).
    59     *  @param resource resource name
    60     *  @param clazz class, ignored.
    61     *  @return URL to resource or null.
    62     *  @deprecated as of 1.2.
    63     */
    64    public static URL getResource(String resource, Class clazz) {
    65        return getResource(resource);
    66    }
    67
    68    /***
    69       This method will search for <code>resource</code> in different
    70       places. The search order is as follows:
    71
    72       <ol>
    73
    74       <p><li>Search for <code>resource</code> using the thread context
    75       class loader under Java2. If that fails, search for
    76       <code>resource</code> using the class loader that loaded this
    77       class (<code>Loader</code>). Under JDK 1.1, only the the class
    78       loader that loaded this class (<code>Loader</code>) is used.
    79
    80       <p><li>Try one last time with
    81       <code>ClassLoader.getSystemResource(resource)</code>, that is is
    82       using the system class loader in JDK 1.2 and virtual machine's
    83       built-in class loader in JDK 1.1.
    84
    85       </ol>
    86    */
    87    static public URL getResource(String resource) {
    88      ClassLoader classLoader = null;
    89      URL url = null;
    90
    91      try {
    92    	if(!java1) {
    93    	  classLoader = getTCL();
    94    	  if(classLoader != null) {
    95    	    LogLog.debug("Trying to find ["+resource+"] using context classloader "
    96    			 +classLoader+".");
    97    	    url = classLoader.getResource(resource);
    98    	    if(url != null) {
    99    	      return url;
    100   	    }
    101   	  }
    102   	}
    103
    104   	// We could not find resource. Ler us now try with the
    105   	// classloader that loaded this class.
    106   	classLoader = Loader.class.getClassLoader();
    107   	if(classLoader != null) {
    108   	  LogLog.debug("Trying to find ["+resource+"] using "+classLoader
    109   		       +" class loader.");
    110   	  url = classLoader.getResource(resource);
    111   	  if(url != null) {
    112   	    return url;
    113   	  }
    114   	}
    115     } catch(Throwable t) {
    116   	LogLog.warn(TSTR, t);
    117     }
    118
    119     // Last ditch attempt: get the resource from the class path. It
    120     // may be the case that clazz was loaded by the Extentsion class
    121     // loader which the parent of the system class loader. Hence the
    122     // code below.
    123     LogLog.debug("Trying to find ["+resource+
    124   		   "] using ClassLoader.getSystemResource().");
    125     return ClassLoader.getSystemResource(resource);
    126   }
    127
    128   /***
    129      Are we running under JDK 1.x?
    130   */
    131   public
    132   static
    133   boolean isJava1() {
    134     return java1;
    135   }
    136
    137   /***
    138     * Get the Thread Context Loader which is a JDK 1.2 feature. If we
    139     * are running under JDK 1.1 or anything else goes wrong the method
    140     * returns <code>null<code>.
    141     *
    142     *  */
    143   private static ClassLoader getTCL() throws IllegalAccessException,
    144     InvocationTargetException {
    145
    146     // Are we running on a JDK 1.2 or later system?
    147     Method method = null;
    148     try {
    149       method = Thread.class.getMethod("getContextClassLoader", null);
    150     } catch (NoSuchMethodException e) {
    151       // We are running on JDK 1.1
    152       return null;
    153     }
    154
    155     return (ClassLoader) method.invoke(Thread.currentThread(), null);
    156   }
    157
    158
    159
    160   /***
    161    * If running under JDK 1.2 load the specified class using the
    162    *  <code>Thread</code> <code>contextClassLoader</code> if that
    163    *  fails try Class.forname. Under JDK 1.1 only Class.forName is
    164    *  used.
    165    *
    166    */
    167   static public Class loadClass (String clazz) throws ClassNotFoundException {
    168     // Just call Class.forName(clazz) if we are running under JDK 1.1
    169     // or if we are instructed to ignore the TCL.
    170     if(java1 || ignoreTCL) {
    171       return Class.forName(clazz);
    172     } else {
    173       try {
    174 	return getTCL().loadClass(clazz);
    175       } catch(Throwable e) {
    176 	// we reached here because tcl was null or because of a
    177 	// security exception, or because clazz could not be loaded...
    178 	// In any case we now try one more time
    179 	return Class.forName(clazz);
    180       }
    181     }
    182   }
    183 }