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 }