001: /*
002: * $Id: ClassLoaderUtils.java 471756 2006-11-06 15:01:43Z husted $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts2.util;
022:
023: import java.io.IOException;
024: import java.io.InputStream;
025: import java.net.URL;
026:
027: /**
028: * This class is extremely useful for loading resources and classes in a fault tolerant manner
029: * that works across different applications servers.
030: * <p/>
031: * It has come out of many months of frustrating use of multiple application servers at Atlassian,
032: * please don't change things unless you're sure they're not going to break in one server or another!
033: *
034: */
035: public class ClassLoaderUtils {
036:
037: /**
038: * Load a given resource.
039: * <p/>
040: * This method will try to load the resource using the following methods (in order):
041: * <ul>
042: * <li>From {@link Thread#getContextClassLoader() Thread.currentThread().getContextClassLoader()}
043: * <li>From {@link Class#getClassLoader() ClassLoaderUtil.class.getClassLoader()}
044: * <li>From the {@link Class#getClassLoader() callingClass.getClassLoader() }
045: * </ul>
046: *
047: * @param resourceName The name of the resource to load
048: * @param callingClass The Class object of the calling object
049: */
050: public static URL getResource(String resourceName,
051: Class callingClass) {
052: URL url = null;
053:
054: url = Thread.currentThread().getContextClassLoader()
055: .getResource(resourceName);
056:
057: if (url == null) {
058: url = ClassLoaderUtils.class.getClassLoader().getResource(
059: resourceName);
060: }
061:
062: if (url == null) {
063: url = callingClass.getClassLoader().getResource(
064: resourceName);
065: }
066:
067: return url;
068: }
069:
070: /**
071: * This is a convenience method to load a resource as a stream.
072: * <p/>
073: * The algorithm used to find the resource is given in getResource()
074: *
075: * @param resourceName The name of the resource to load
076: * @param callingClass The Class object of the calling object
077: */
078: public static InputStream getResourceAsStream(String resourceName,
079: Class callingClass) {
080: URL url = getResource(resourceName, callingClass);
081:
082: try {
083: return (url != null) ? url.openStream() : null;
084: } catch (IOException e) {
085: return null;
086: }
087: }
088:
089: /**
090: * Load a class with a given name.
091: * <p/>
092: * It will try to load the class in the following order:
093: * <ul>
094: * <li>From {@link Thread#getContextClassLoader() Thread.currentThread().getContextClassLoader()}
095: * <li>Using the basic {@link Class#forName(java.lang.String) }
096: * <li>From {@link Class#getClassLoader() ClassLoaderUtil.class.getClassLoader()}
097: * <li>From the {@link Class#getClassLoader() callingClass.getClassLoader() }
098: * </ul>
099: *
100: * @param className The name of the class to load
101: * @param callingClass The Class object of the calling object
102: * @throws ClassNotFoundException If the class cannot be found anywhere.
103: */
104: public static Class loadClass(String className, Class callingClass)
105: throws ClassNotFoundException {
106: try {
107: return Thread.currentThread().getContextClassLoader()
108: .loadClass(className);
109: } catch (ClassNotFoundException e) {
110: try {
111: return Class.forName(className);
112: } catch (ClassNotFoundException ex) {
113: try {
114: return ClassLoaderUtils.class.getClassLoader()
115: .loadClass(className);
116: } catch (ClassNotFoundException exc) {
117: return callingClass.getClassLoader().loadClass(
118: className);
119: }
120: }
121: }
122: }
123:
124: /**
125: * Prints the current classloader hierarchy - useful for debugging.
126: */
127: public static void printClassLoader() {
128: System.out.println("ClassLoaderUtils.printClassLoader");
129: printClassLoader(Thread.currentThread().getContextClassLoader());
130: }
131:
132: /**
133: * Prints the classloader hierarchy from a given classloader - useful for debugging.
134: */
135: public static void printClassLoader(ClassLoader cl) {
136: System.out.println("ClassLoaderUtils.printClassLoader(cl = "
137: + cl + ")");
138:
139: if (cl != null) {
140: printClassLoader(cl.getParent());
141: }
142: }
143: }
|