View Javadoc

    1   /*
    2    * $Id: ClassLoaderUtils.java 471756 2006-11-06 15:01:43Z husted $
    3    *
    4    * Licensed to the Apache Software Foundation (ASF) under one
    5    * or more contributor license agreements.  See the NOTICE file
    6    * distributed with this work for additional information
    7    * regarding copyright ownership.  The ASF licenses this file
    8    * to you under the Apache License, Version 2.0 (the
    9    * "License"); you may not use this file except in compliance
    10   * with the License.  You may obtain a copy of the License at
    11   *
    12   *  http://www.apache.org/licenses/LICENSE-2.0
    13   *
    14   * Unless required by applicable law or agreed to in writing,
    15   * software distributed under the License is distributed on an
    16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    17   * KIND, either express or implied.  See the License for the
    18   * specific language governing permissions and limitations
    19   * under the License.
    20   */
    21  package org.apache.struts2.util;
    22
    23  import java.io.IOException;
    24  import java.io.InputStream;
    25  import java.net.URL;
    26
    27
    28  /***
    29   * This class is extremely useful for loading resources and classes in a fault tolerant manner
    30   * that works across different applications servers.
    31   * <p/>
    32   * It has come out of many months of frustrating use of multiple application servers at Atlassian,
    33   * please don't change things unless you're sure they're not going to break in one server or another!
    34   *
    35   */
    36  public class ClassLoaderUtils {
    37
    38      /***
    39       * Load a given resource.
    40       * <p/>
    41       * This method will try to load the resource using the following methods (in order):
    42       * <ul>
    43       * <li>From {@link Thread#getContextClassLoader() Thread.currentThread().getContextClassLoader()}
    44       * <li>From {@link Class#getClassLoader() ClassLoaderUtil.class.getClassLoader()}
    45       * <li>From the {@link Class#getClassLoader() callingClass.getClassLoader() }
    46       * </ul>
    47       *
    48       * @param resourceName The name of the resource to load
    49       * @param callingClass The Class object of the calling object
    50       */
    51      public static URL getResource(String resourceName, Class callingClass) {
    52          URL url = null;
    53
    54          url = Thread.currentThread().getContextClassLoader().getResource(resourceName);
    55
    56          if (url == null) {
    57              url = ClassLoaderUtils.class.getClassLoader().getResource(resourceName);
    58          }
    59
    60          if (url == null) {
    61              url = callingClass.getClassLoader().getResource(resourceName);
    62          }
    63
    64          return url;
    65      }
    66
    67      /***
    68       * This is a convenience method to load a resource as a stream.
    69       * <p/>
    70       * The algorithm used to find the resource is given in getResource()
    71       *
    72       * @param resourceName The name of the resource to load
    73       * @param callingClass The Class object of the calling object
    74       */
    75      public static InputStream getResourceAsStream(String resourceName, Class callingClass) {
    76          URL url = getResource(resourceName, callingClass);
    77
    78          try {
    79              return (url != null) ? url.openStream() : null;
    80          } catch (IOException e) {
    81              return null;
    82          }
    83      }
    84
    85      /***
    86       * Load a class with a given name.
    87       * <p/>
    88       * It will try to load the class in the following order:
    89       * <ul>
    90       * <li>From {@link Thread#getContextClassLoader() Thread.currentThread().getContextClassLoader()}
    91       * <li>Using the basic {@link Class#forName(java.lang.String) }
    92       * <li>From {@link Class#getClassLoader() ClassLoaderUtil.class.getClassLoader()}
    93       * <li>From the {@link Class#getClassLoader() callingClass.getClassLoader() }
    94       * </ul>
    95       *
    96       * @param className    The name of the class to load
    97       * @param callingClass The Class object of the calling object
    98       * @throws ClassNotFoundException If the class cannot be found anywhere.
    99       */
    100     public static Class loadClass(String className, Class callingClass) throws ClassNotFoundException {
    101         try {
    102             return Thread.currentThread().getContextClassLoader().loadClass(className);
    103         } catch (ClassNotFoundException e) {
    104             try {
    105                 return Class.forName(className);
    106             } catch (ClassNotFoundException ex) {
    107                 try {
    108                     return ClassLoaderUtils.class.getClassLoader().loadClass(className);
    109                 } catch (ClassNotFoundException exc) {
    110                     return callingClass.getClassLoader().loadClass(className);
    111                 }
    112             }
    113         }
    114     }
    115
    116     /***
    117      * Prints the current classloader hierarchy - useful for debugging.
    118      */
    119     public static void printClassLoader() {
    120         System.out.println("ClassLoaderUtils.printClassLoader");
    121         printClassLoader(Thread.currentThread().getContextClassLoader());
    122     }
    123
    124     /***
    125      * Prints the classloader hierarchy from a given classloader - useful for debugging.
    126      */
    127     public static void printClassLoader(ClassLoader cl) {
    128         System.out.println("ClassLoaderUtils.printClassLoader(cl = " + cl + ")");
    129
    130         if (cl != null) {
    131             printClassLoader(cl.getParent());
    132         }
    133     }
    134 }