1
2
3
4
5
6 package org.backsource.utils.lang;
7
8 import java.net.URL;
9 import java.net.URLClassLoader;
10 import java.util.Enumeration;
11 import java.util.Vector;
12 /***
13 * <p>A URLClassLoader wrapper that loads classes and resouces first from the
14 leafs of the classloader tree, and not from the root as is the case with
15 the sun classloader.
16
17 <p>It is important to understand that all classes are loaded into the classloader wrapper and the new wrapper it created around its parent.
18
19 <p>It is also important to know that if a URLClassLoader has a parent that is not a URLClassLoader, the normal classloading and resource finding mechanisms will be used.
20
21 <p>May be really handy if you want to override a resource (or class) in
22 a component loaded in leaf classloader, as is often the case in JBoss and Tomcat for example.
23 *
24 *
25 * @author Peter Antman
26 * @version $Revision: 1.1.1.1 $
27 */
28
29 public class ReverseClassLoader extends URLClassLoader{
30 ClassLoader wrappedClassLoader= null;
31
32 /***
33 * <p>Wrap a URLClassLoader.
34 *
35 * <p>The all URLs the classloader wikk be search first, and lodaded
36 * in this classloader, and not in the wrapped one.
37 */
38 public ReverseClassLoader(URLClassLoader wrappedClassLoader) {
39 super(wrappedClassLoader.getURLs(), wrappedClassLoader.getParent());
40 this.wrappedClassLoader = wrappedClassLoader;
41 }
42
43 public ClassLoader getWrappedClassLoader() {
44 return wrappedClassLoader;
45 }
46
47 /***
48 * Get resource through a bottom up search. I.e try find the resource
49 * in the wrapped loader before proceding to the parent.
50 */
51 public URL getResource(String name) {
52 return getResource(this,name);
53 }
54
55 /***
56 * Try find the resource in the classloader, if not proced to parent.
57 * If parent is null, call getResource on the cl.
58 */
59 private URL getResource(ReverseClassLoader cl, String name) {
60 URL url = cl.findResource(name);
61 if (url != null)
62 return url;
63 else {
64
65 ClassLoader parent = cl.getParent();
66
67 if (parent !=null) {
68 if(parent instanceof URLClassLoader) {
69
70 ReverseClassLoader wrap = new ReverseClassLoader((URLClassLoader)parent);
71 return getResource(wrap,name);
72 }else {
73
74 return parent.getResource(name);
75 }
76 } else {
77
78
79 return cl.getWrappedClassLoader().getResource(name);
80 }
81 }
82 }
83
84 public URL findResource(String name) {
85 return super.findResource(name);
86 }
87
88
89
90
91
92
93
94
95
96 /***
97 * Try find the resurce in the classloader, if not proced to parent.
98 * If parent is null, call getResource on the cl.
99 *
100 */
101 private Enumeration reverseEnumeration(Enumeration enum) {
102 Vector v = new Vector();
103 while(enum.hasMoreElements()) {
104 v.add(enum.nextElement());
105 }
106 Vector rev = new Vector();
107 for(int i = v.size(); i > 0; i--) {
108 rev.add(v.elementAt(i-1));
109 }
110 return rev.elements();
111 }
112
113 /***
114 * <p>Load a class by looking in this classloader and searching upwards as
115 * long as the parent classloaders are URLClassloader.
116 *
117 * <p>It is important to notice that the classes will be loaded in this
118 * classloader or in any of its contsucted parents (also ReverseClassLoader) and not in the wrapped classloader.
119 */
120 public Class loadClass(String name) throws ClassNotFoundException {
121 return loadClass(this,name);
122 }
123
124
125
126
127
128
129
130
131 protected Class loadClass(ReverseClassLoader cl, String name)
132 throws ClassNotFoundException
133 {
134
135 Class c = cl.findLoadedClass(name);
136 if (c == null) {
137
138 try {
139 c = cl.findClass(name);
140 }catch(ClassNotFoundException e) {
141
142 ClassLoader parent = cl.getParent();
143 if (parent !=null) {
144 if (parent instanceof URLClassLoader) {
145 ReverseClassLoader wrap = new ReverseClassLoader((URLClassLoader)parent);
146 return loadClass(wrap,name);
147 }else {
148 return parent.loadClass(name);
149 }
150 } else {
151
152
153 return cl.getWrappedClassLoader().loadClass(name);
154
155 }
156 }
157
158 }
159 return c;
160 }
161
162
163
164
165
166 }
167
168
169
170
171
172
173
174
175