Revision 42437
trunk/org.gvsig.desktop/org.gvsig.desktop.framework/org.gvsig.andami/src/main/java/org/gvsig/andami/plugins/PluginClassLoader.java | ||
---|---|---|
3 | 3 |
* |
4 | 4 |
* Copyright (C) 2007-2013 gvSIG Association. |
5 | 5 |
* |
6 |
* This program is free software; you can redistribute it and/or |
|
7 |
* modify it under the terms of the GNU General Public License
|
|
8 |
* as published by the Free Software Foundation; either version 3
|
|
9 |
* of the License, or (at your option) any later version.
|
|
6 |
* This program is free software; you can redistribute it and/or modify it under
|
|
7 |
* the terms of the GNU General Public License as published by the Free Software
|
|
8 |
* Foundation; either version 3 of the License, or (at your option) any later
|
|
9 |
* version. |
|
10 | 10 |
* |
11 |
* This program is distributed in the hope that it will be useful, |
|
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14 |
* GNU General Public License for more details.
|
|
11 |
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
13 |
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
14 |
* details. |
|
15 | 15 |
* |
16 |
* You should have received a copy of the GNU General Public License |
|
17 |
* along with this program; if not, write to the Free Software |
|
18 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
19 |
* MA 02110-1301, USA. |
|
16 |
* You should have received a copy of the GNU General Public License along with |
|
17 |
* this program; if not, write to the Free Software Foundation, Inc., 51 |
|
18 |
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
20 | 19 |
* |
21 |
* For any additional information, do not hesitate to contact us |
|
22 |
* at info AT gvsig.com, or visit our website www.gvsig.com.
|
|
20 |
* For any additional information, do not hesitate to contact us at info AT
|
|
21 |
* gvsig.com, or visit our website www.gvsig.com. |
|
23 | 22 |
*/ |
24 | 23 |
package org.gvsig.andami.plugins; |
25 | 24 |
|
... | ... | |
53 | 52 |
import org.slf4j.Logger; |
54 | 53 |
import org.slf4j.LoggerFactory; |
55 | 54 |
|
56 |
|
|
57 |
|
|
58 | 55 |
/** |
59 |
* <p>Class loader which loads the classes requested by the |
|
60 |
* plugins. It first tries to search in the classpath, then it requests |
|
61 |
* the class to the parent classloader, then it searches in the owns |
|
62 |
* plugins' library dir, and if all these methods fail, it tries to load |
|
63 |
* the class from any of the depended plugins. Finally, if this also |
|
64 |
* fails, the other classloaders provided in the <code>addLoaders</code> method |
|
65 |
* are requested to load the class.</p> |
|
66 |
* |
|
67 |
* <p>The class loader can also be used to load resources from the |
|
68 |
* plugin's directory by using the <code>getResource()</code> method.</p> |
|
56 |
* <p> |
|
57 |
* Class loader which loads the classes requested by the plugins. It first tries |
|
58 |
* to search in the classpath, then it requests the class to the parent |
|
59 |
* classloader, then it searches in the owns plugins' library dir, and if all |
|
60 |
* these methods fail, it tries to load the class from any of the depended |
|
61 |
* plugins. Finally, if this also fails, the other classloaders provided in the |
|
62 |
* <code>addLoaders</code> method are requested to load the class.</p> |
|
69 | 63 |
* |
64 |
* <p> |
|
65 |
* The class loader can also be used to load resources from the plugin's |
|
66 |
* directory by using the <code>getResource()</code> method.</p> |
|
67 |
* |
|
70 | 68 |
* @author Fernando Gonz�lez Cort�s |
71 | 69 |
*/ |
72 | 70 |
public class PluginClassLoader extends URLClassLoader { |
73 |
/** DOCUMENT ME! */ |
|
71 |
|
|
72 |
/** |
|
73 |
* DOCUMENT ME! |
|
74 |
*/ |
|
74 | 75 |
private static Logger logger = LoggerFactory.getLogger(PluginClassLoader.class.getName()); |
75 | 76 |
|
76 |
/** DOCUMENT ME! */ |
|
77 |
/** |
|
78 |
* DOCUMENT ME! |
|
79 |
*/ |
|
77 | 80 |
private Hashtable<String, ZipFile> clasesJar = new Hashtable<String, ZipFile>(); |
78 | 81 |
|
79 |
/** DOCUMENT ME! */ |
|
82 |
/** |
|
83 |
* DOCUMENT ME! |
|
84 |
*/ |
|
80 | 85 |
private File baseDir; |
81 | 86 |
private List<PluginClassLoader> pluginLoaders; |
82 |
private static List<ClassLoader> otherLoaders=new ArrayList<ClassLoader>();
|
|
83 |
private boolean isOtherLoader=false;
|
|
84 |
|
|
87 |
private static List<ClassLoader> otherLoaders = new ArrayList<ClassLoader>();
|
|
88 |
private boolean isOtherLoader = false;
|
|
89 |
|
|
85 | 90 |
/** |
86 | 91 |
* Creates a new PluginClassLoader object. |
87 | 92 |
* |
... | ... | |
95 | 100 |
* @throws IOException |
96 | 101 |
*/ |
97 | 102 |
public PluginClassLoader(URL[] jars, String baseDir, ClassLoader cl, |
98 |
PluginClassLoader[] pluginLoaders) throws IOException { |
|
103 |
PluginClassLoader[] pluginLoaders) throws IOException {
|
|
99 | 104 |
this(jars, baseDir, cl, Arrays.asList(pluginLoaders)); |
100 | 105 |
} |
101 |
|
|
106 |
|
|
102 | 107 |
public PluginClassLoader(URL[] jars, String baseDir, ClassLoader cl, |
103 | 108 |
List<PluginClassLoader> pluginLoaders) throws IOException { |
104 | 109 |
super(jars, cl); |
... | ... | |
107 | 112 |
this.pluginLoaders = new ArrayList(); |
108 | 113 |
this.pluginLoaders.addAll(pluginLoaders); |
109 | 114 |
|
110 |
if( jars==null || jars.length<1 ) {
|
|
111 |
debugDump();
|
|
112 |
return;
|
|
115 |
if (jars == null || jars.length < 1) {
|
|
116 |
debugDump(); |
|
117 |
return;
|
|
113 | 118 |
} |
114 | 119 |
ZipFile[] jarFiles = new ZipFile[jars.length]; |
115 | 120 |
|
... | ... | |
129 | 134 |
} |
130 | 135 |
|
131 | 136 |
fileName = fileName.substring(0, fileName.length() - 6) |
132 |
.replace('/', '.');
|
|
137 |
.replace('/', '.'); |
|
133 | 138 |
|
134 | 139 |
if (clasesJar.get(fileName) != null) { |
135 |
logger.warn("Duplicated class {} in {} and {}", |
|
136 |
new Object[] { |
|
137 |
fileName, |
|
138 |
jarFiles[i].getName(), |
|
139 |
clasesJar.get(fileName).getName() |
|
140 |
} |
|
141 |
); |
|
140 |
logger.warn("Duplicated class {} in {} and {}", |
|
141 |
new Object[]{ |
|
142 |
fileName, |
|
143 |
jarFiles[i].getName(), |
|
144 |
clasesJar.get(fileName).getName() |
|
145 |
} |
|
146 |
); |
|
147 |
} else { |
|
148 |
clasesJar.put(fileName, jarFiles[i]); |
|
142 | 149 |
} |
143 |
else { |
|
144 |
clasesJar.put(fileName, jarFiles[i]); |
|
145 |
} |
|
146 | 150 |
} |
147 | 151 |
} catch (ZipException e) { |
148 |
throw new IOException(e.getMessage() + " Jar: " +
|
|
149 |
jars[i].getPath() + ": " + jarFiles[i]); |
|
152 |
throw new IOException(e.getMessage() + " Jar: " |
|
153 |
+ jars[i].getPath() + ": " + jarFiles[i]);
|
|
150 | 154 |
} catch (IOException e) { |
151 | 155 |
throw e; |
152 | 156 |
} finally { |
153 |
debugDump();
|
|
157 |
debugDump(); |
|
154 | 158 |
} |
155 | 159 |
} |
156 | 160 |
} |
157 | 161 |
|
158 | 162 |
private void debugDump() { |
159 |
if( !logger.isDebugEnabled() ) {
|
|
160 |
return;
|
|
161 |
}
|
|
162 |
logger.debug(this.toString());
|
|
163 |
logger.debug(" baseDir: " + this.baseDir);
|
|
164 |
logger.debug(" parent: " + this.getParent());
|
|
165 |
logger.debug(" depends:");
|
|
166 |
for( int n=0; n<this.pluginLoaders.size(); n++ ) {
|
|
167 |
logger.debug(" {}", this.pluginLoaders.get(n).toString() );
|
|
168 |
}
|
|
169 |
logger.debug(" urls:");
|
|
170 |
URL[] urls = this.getURLs();
|
|
171 |
for( int n=0 ; n<urls.length; n++ ) {
|
|
172 |
logger.debug(" " + urls[n].toString());
|
|
173 |
}
|
|
174 |
logger.debug(" classes:");
|
|
175 |
Iterator<Map.Entry<String, ZipFile>>it = this.clasesJar.entrySet().iterator();
|
|
176 |
while( it.hasNext() ) {
|
|
177 |
Entry<String, ZipFile> entry = it.next();
|
|
178 |
logger.debug(" "+ entry.getKey() + "("+entry.getValue().getName()+")");
|
|
179 |
}
|
|
163 |
if (!logger.isDebugEnabled()) {
|
|
164 |
return;
|
|
165 |
}
|
|
166 |
logger.debug(this.toString());
|
|
167 |
logger.debug(" baseDir: " + this.baseDir);
|
|
168 |
logger.debug(" parent: " + this.getParent());
|
|
169 |
logger.debug(" depends:");
|
|
170 |
for (int n = 0; n < this.pluginLoaders.size(); n++) {
|
|
171 |
logger.debug(" {}", this.pluginLoaders.get(n).toString());
|
|
172 |
}
|
|
173 |
logger.debug(" urls:");
|
|
174 |
URL[] urls = this.getURLs();
|
|
175 |
for (int n = 0; n < urls.length; n++) {
|
|
176 |
logger.debug(" " + urls[n].toString());
|
|
177 |
}
|
|
178 |
logger.debug(" classes:");
|
|
179 |
Iterator<Map.Entry<String, ZipFile>> it = this.clasesJar.entrySet().iterator();
|
|
180 |
while (it.hasNext()) {
|
|
181 |
Entry<String, ZipFile> entry = it.next();
|
|
182 |
logger.debug(" " + entry.getKey() + "(" + entry.getValue().getName() + ")");
|
|
183 |
}
|
|
180 | 184 |
} |
181 |
|
|
185 |
|
|
182 | 186 |
protected Class singleLoadClass(String name) throws ClassNotFoundException { |
183 | 187 |
Class<?> c; |
184 |
Set<String>pluginsVisiteds = new HashSet<String>(); |
|
188 |
Set<String> pluginsVisiteds = new HashSet<String>();
|
|
185 | 189 |
c = this.singleLoadClass(pluginsVisiteds, name); |
186 | 190 |
return c; |
187 | 191 |
} |
... | ... | |
197 | 201 |
* @throws ClassNotFoundException Si no se pudo encontrar la clase |
198 | 202 |
*/ |
199 | 203 |
protected Class loadClass(String name, boolean resolve) |
200 |
throws ClassNotFoundException { |
|
204 |
throws ClassNotFoundException {
|
|
201 | 205 |
Class<?> c = null; |
202 | 206 |
|
203 | 207 |
// Intentamos cargar con el system classloader |
204 | 208 |
try { |
205 |
if (!isOtherLoader) |
|
206 |
c = super.loadClass(name, resolve); |
|
207 |
logger.debug("Found class {} in system-classloader", name); |
|
209 |
if (!isOtherLoader) { |
|
210 |
c = super.loadClass(name, resolve); |
|
211 |
logger.debug("Found class {} in system-classloader", name); |
|
212 |
} |
|
208 | 213 |
} catch (ClassNotFoundException e1) { |
209 |
try { |
|
210 |
c = singleLoadClass(name); |
|
211 |
} catch (ClassNotFoundException e2) { |
|
212 |
try { |
|
213 |
isOtherLoader=true; |
|
214 |
c = loadOtherClass(name); |
|
215 |
}catch (ClassNotFoundException e3) { |
|
216 |
// throw new ClassNotFoundException(Messages.getString( |
|
217 |
// "PluginClassLoader.Error_reading_file") |
|
218 |
// + name, e3); |
|
214 |
try { |
|
215 |
c = singleLoadClass(name); |
|
216 |
} catch (ClassNotFoundException e2) { |
|
217 |
try { |
|
218 |
isOtherLoader = true; |
|
219 |
c = loadOtherClass(name); |
|
220 |
} catch (ClassNotFoundException e3) { |
|
219 | 221 |
throw new ClassNotFoundException("Class " + name |
220 |
+ " not found through the plugin " + baseDir, e3);
|
|
221 |
}finally {
|
|
222 |
isOtherLoader=false;
|
|
223 |
}
|
|
224 |
}
|
|
222 |
+ " not found through the plugin " + baseDir, e3); |
|
223 |
} finally {
|
|
224 |
isOtherLoader = false;
|
|
225 |
}
|
|
226 |
}
|
|
225 | 227 |
} |
226 |
if (c==null) |
|
227 |
throw new ClassNotFoundException(Messages.getString( |
|
228 |
"PluginClassLoader.Error_reading_file") + name); |
|
228 |
if (c == null) { |
|
229 |
throw new ClassNotFoundException(Messages.getString( |
|
230 |
"PluginClassLoader.Error_reading_file") + name); |
|
231 |
} |
|
229 | 232 |
if (resolve) { |
230 | 233 |
resolveClass(c); |
231 | 234 |
} |
232 | 235 |
return c; |
233 | 236 |
} |
234 |
|
|
237 |
|
|
235 | 238 |
private Class<?> loadOtherClass(String name) |
236 | 239 |
throws ClassNotFoundException { |
237 | 240 |
ClassLoader[] ocl = (ClassLoader[]) otherLoaders.toArray(new ClassLoader[0]); |
... | ... | |
252 | 255 |
* obtiene el array de bytes de la clase |
253 | 256 |
* |
254 | 257 |
* @param classFile Entrada dentro del jar contiene los bytecodes de la |
255 |
* clase (el .class)
|
|
258 |
* clase (el .class) |
|
256 | 259 |
* @param is InputStream para leer la entrada del jar |
257 | 260 |
* |
258 | 261 |
* @return Bytes de la clase |
... | ... | |
260 | 263 |
* @throws IOException Si no se puede obtener el .class del jar |
261 | 264 |
*/ |
262 | 265 |
private byte[] loadClassData(ZipEntry classFile, InputStream is) |
263 |
throws IOException { |
|
266 |
throws IOException {
|
|
264 | 267 |
// Get size of class file |
265 | 268 |
int size = (int) classFile.getSize(); |
266 | 269 |
|
... | ... | |
310 | 313 |
int offset = 0; |
311 | 314 |
int numRead = 0; |
312 | 315 |
|
313 |
while ((offset < bytes.length) &&
|
|
314 |
((numRead = is.read(bytes, offset, bytes.length - offset)) >= 0)) { |
|
316 |
while ((offset < bytes.length) |
|
317 |
&& ((numRead = is.read(bytes, offset, bytes.length - offset)) >= 0)) {
|
|
315 | 318 |
offset += numRead; |
316 | 319 |
} |
317 | 320 |
|
... | ... | |
320 | 323 |
|
321 | 324 |
// Ensure all the bytes have been read in |
322 | 325 |
if (offset < bytes.length) { |
323 |
throw new IOException("Could not completely read file " +
|
|
324 |
file.getName()); |
|
326 |
throw new IOException("Could not completely read file " |
|
327 |
+ file.getName());
|
|
325 | 328 |
} |
326 | 329 |
|
327 | 330 |
return bytes; |
... | ... | |
329 | 332 |
|
330 | 333 |
/** |
331 | 334 |
* Gets the requested resource. If the path is relative, its base directory |
332 |
* will be the one provided in the PluginClassLoader's constructor. |
|
333 |
* If the resource is not found, search in dependents plugins, otherwise
|
|
334 |
* the parent classloader will be invoked to try to get it.
|
|
335 |
* If it is not found, it will return null.
|
|
335 |
* will be the one provided in the PluginClassLoader's constructor. If the
|
|
336 |
* resource is not found, search in dependents plugins, otherwise the parent
|
|
337 |
* classloader will be invoked to try to get it. If it is not found, it will
|
|
338 |
* return null. |
|
336 | 339 |
* |
337 | 340 |
* @param res An absolute or relative path to the requested resource. |
338 | 341 |
* |
... | ... | |
341 | 344 |
public URL getResource(String res) { |
342 | 345 |
URL ret = null; |
343 | 346 |
|
344 |
Set<String>pluginsVisiteds = new HashSet<String>(); |
|
347 |
Set<String> pluginsVisiteds = new HashSet<String>();
|
|
345 | 348 |
ret = this.getResource(pluginsVisiteds, res); |
346 | 349 |
return ret; |
347 | 350 |
} |
348 | 351 |
|
349 | 352 |
/** |
350 | 353 |
* Gets the requested resource. If the path is relative, its base directory |
351 |
* will be the one provided in the PluginClassLoader's constructor. |
|
352 |
* If the resource is not found, the parent classloader will be invoked
|
|
353 |
* to try to get it. If it is not found, it will return null.
|
|
354 |
* will be the one provided in the PluginClassLoader's constructor. If the
|
|
355 |
* resource is not found, the parent classloader will be invoked to try to
|
|
356 |
* get it. If it is not found, it will return null. |
|
354 | 357 |
* |
355 | 358 |
* @param res An absolute or relative path to the requested resource. |
356 | 359 |
* |
... | ... | |
379 | 382 |
} |
380 | 383 |
|
381 | 384 |
/** |
382 |
* Returns the name of the plugin (the name of the directory containing |
|
383 |
* the plugin).
|
|
385 |
* Returns the name of the plugin (the name of the directory containing the
|
|
386 |
* plugin). |
|
384 | 387 |
* |
385 | 388 |
* @return An String containing the plugin's name. |
386 | 389 |
*/ |
387 | 390 |
public String getPluginName() { |
388 |
return baseDir.getName();
|
|
391 |
return baseDir.getName();
|
|
389 | 392 |
} |
390 | 393 |
|
391 | 394 |
/* |
... | ... | |
399 | 402 |
} |
400 | 403 |
|
401 | 404 |
/** |
402 |
* Gets the plugin's base Iterator<Map.Entry<Integer, Integer>>dir, the directory which will be used to
|
|
403 |
* search resources. |
|
405 |
* Gets the plugin's base Iterator<Map.Entry<Integer, Integer>>dir, the |
|
406 |
* directory which will be used to search resources.
|
|
404 | 407 |
* |
405 | 408 |
* @return Returns the baseDir. |
406 | 409 |
*/ |
... | ... | |
410 | 413 |
|
411 | 414 |
/** |
412 | 415 |
* Adds other classloader to use when all the normal methods fail. |
413 |
*
|
|
414 |
* @param classLoaders An ArrayList of ClassLoaders which will |
|
415 |
* be used to load classes when all the normal methods fail.
|
|
416 |
* |
|
417 |
* @param classLoaders An ArrayList of ClassLoaders which will be used to
|
|
418 |
* load classes when all the normal methods fail. |
|
416 | 419 |
*/ |
417 |
public static void addLoaders(ArrayList classLoaders) {
|
|
418 |
otherLoaders.addAll(classLoaders);
|
|
419 |
}
|
|
420 |
public static void addLoaders(ArrayList classLoaders) {
|
|
421 |
otherLoaders.addAll(classLoaders);
|
|
422 |
}
|
|
420 | 423 |
|
421 | 424 |
@Override |
422 | 425 |
public String toString() { |
423 | 426 |
return super.toString() + " (" + getPluginName() + ")"; |
424 | 427 |
} |
425 |
|
|
428 |
|
|
426 | 429 |
public void addPluginClassLoader(PluginClassLoader pluginClassLoader) { |
427 |
if( !this.pluginLoaders.contains(pluginClassLoader) ) {
|
|
430 |
if (!this.pluginLoaders.contains(pluginClassLoader)) {
|
|
428 | 431 |
this.pluginLoaders.add(pluginClassLoader); |
429 | 432 |
} |
430 | 433 |
} |
431 |
|
|
434 |
|
|
432 | 435 |
private Class singleLoadClass(Set<String> pluginsVisiteds, String name) throws ClassNotFoundException { |
433 |
|
|
434 |
if ( pluginsVisiteds.contains(this.getPluginName()) ) {
|
|
436 |
|
|
437 |
if (pluginsVisiteds.contains(this.getPluginName())) {
|
|
435 | 438 |
return null; |
436 | 439 |
} |
437 | 440 |
pluginsVisiteds.add(this.getPluginName()); |
... | ... | |
443 | 446 |
return c; |
444 | 447 |
} |
445 | 448 |
|
446 |
logger.debug("Searching class '{}' in {}", new Object[] {name, this.toString()});
|
|
449 |
logger.debug("Searching class '{}' in {}", new Object[]{name, this.toString()}); |
|
447 | 450 |
try { |
448 | 451 |
ZipFile jar = (ZipFile) clasesJar.get(name); |
449 | 452 |
|
450 | 453 |
//No esta en ningun jar |
451 | 454 |
if (jar == null) { |
452 | 455 |
//Buscamos en el directorio de clases |
453 |
String classFileName = baseDir + "/classes/" +
|
|
454 |
name.replace('.', '/') + ".class"; |
|
456 |
String classFileName = baseDir + "/classes/" |
|
457 |
+ name.replace('.', '/') + ".class";
|
|
455 | 458 |
File f = new File(classFileName); |
456 |
if (f.exists()){ |
|
459 |
if (f.exists()) {
|
|
457 | 460 |
byte[] data = loadClassData(f); |
458 | 461 |
c = defineClass(name, data, 0, data.length); |
459 | 462 |
logger.debug("Found class {} in classes-folder of plugin {}", |
460 |
new Object[] {name, baseDir});
|
|
463 |
new Object[]{name, baseDir});
|
|
461 | 464 |
|
462 | 465 |
} else { |
463 | 466 |
//Buscamos en los otros plugins |
464 |
for ( int i = 0; i < pluginLoaders.size(); i++ ) {
|
|
467 |
for (int i = 0; i < pluginLoaders.size(); i++) {
|
|
465 | 468 |
c = null; |
466 |
if ( pluginLoaders.get(i) != null ) {
|
|
469 |
if (pluginLoaders.get(i) != null) {
|
|
467 | 470 |
try { |
468 | 471 |
c = pluginLoaders.get(i).singleLoadClass(pluginsVisiteds, name); |
469 | 472 |
} catch (ClassNotFoundException e) { |
... | ... | |
471 | 474 |
// porque es probable que la encontremos en el resto de plugins. |
472 | 475 |
} |
473 | 476 |
} |
474 |
if ( c != null ) {
|
|
477 |
if (c != null) {
|
|
475 | 478 |
return c; |
476 | 479 |
} |
477 | 480 |
} |
... | ... | |
483 | 486 |
jar.getInputStream(classFile)); |
484 | 487 |
|
485 | 488 |
c = defineClass(name, data, 0, data.length); |
486 |
|
|
489 |
|
|
487 | 490 |
logger.debug("Found class {} in jar {} of plugin {}", |
488 |
new Object[] { name, jar.getName(), baseDir} );
|
|
491 |
new Object[]{name, jar.getName(), baseDir});
|
|
489 | 492 |
} |
490 | 493 |
|
491 | 494 |
if (c == null) { |
... | ... | |
496 | 499 |
} catch (IOException e) { |
497 | 500 |
throw new ClassNotFoundException(Messages.getString( |
498 | 501 |
"PluginClassLoader.Error_reading_file") + name); |
499 |
}
|
|
502 |
} |
|
500 | 503 |
} |
501 | 504 |
|
502 | 505 |
/** |
503 |
* Este metodo busca en este class loader y en el de los plugins |
|
504 |
* de los que depende. Se cerciora de que no se queda
|
|
505 |
* bucleado cuando hay una relacion recursiva entre los plugins.
|
|
506 |
*
|
|
507 |
* @param pluginsVisiteds, set con los plugins que va visitando para evitar
|
|
508 |
* que se quede bucleado cuando hay referencia ciclicas entre plugins.
|
|
506 |
* Este metodo busca en este class loader y en el de los plugins de los que
|
|
507 |
* depende. Se cerciora de que no se queda bucleado cuando hay una relacion
|
|
508 |
* recursiva entre los plugins. |
|
509 |
* |
|
510 |
* @param pluginsVisiteds, set con los plugins que va visitando para evitar |
|
511 |
* que se quede bucleado cuando hay referencia ciclicas entre plugins. |
|
509 | 512 |
* @param res |
510 |
*
|
|
511 |
* @return
|
|
513 |
* |
|
514 |
* @return |
|
512 | 515 |
*/ |
513 |
private URL getResource(Set<String> pluginsVisiteds, String res) {
|
|
516 |
private URL getResource(Set<String> pluginsVisiteds, String res) { |
|
514 | 517 |
URL ret = null; |
515 | 518 |
|
516 |
if ( pluginsVisiteds.contains(this.getPluginName()) ) {
|
|
519 |
if (pluginsVisiteds.contains(this.getPluginName())) {
|
|
517 | 520 |
return null; |
518 | 521 |
} |
519 | 522 |
pluginsVisiteds.add(this.getPluginName()); |
... | ... | |
524 | 527 |
logger.debug("Plugin {}. Searching resource '{}'", res, this.getPluginName()); |
525 | 528 |
List<String> resource = new ArrayList<String>(); |
526 | 529 |
StringTokenizer st = new StringTokenizer(res, "\\/"); |
527 |
while ( st.hasMoreTokens() ) {
|
|
530 |
while (st.hasMoreTokens()) {
|
|
528 | 531 |
String token = st.nextToken(); |
529 | 532 |
resource.add(token); |
530 | 533 |
} |
531 | 534 |
ret = getResource(baseDir, resource); |
532 |
if ( ret != null ) {
|
|
535 |
if (ret != null) {
|
|
533 | 536 |
return ret; |
534 | 537 |
} |
535 | 538 |
} catch (Exception e) { |
... | ... | |
537 | 540 |
} |
538 | 541 |
|
539 | 542 |
logger.debug("Plugin {}. Searching in depends pluginLoaders", this.getPluginName()); |
540 |
for ( int i = 0; i < this.pluginLoaders.size(); i++ ) {
|
|
543 |
for (int i = 0; i < this.pluginLoaders.size(); i++) {
|
|
541 | 544 |
PluginClassLoader pluginClassLoader = pluginLoaders.get(i); |
542 |
if ( pluginClassLoader != null ) {
|
|
545 |
if (pluginClassLoader != null) {
|
|
543 | 546 |
try { |
544 | 547 |
pluginsVisiteds.add(pluginClassLoader.getPluginName()); |
545 | 548 |
ret = pluginClassLoader.getResource(pluginsVisiteds, res); |
546 |
if ( ret != null ) {
|
|
549 |
if (ret != null) {
|
|
547 | 550 |
logger.trace("Plugin {}. Found resource '{}' in plugin '{}'.", |
548 | 551 |
new Object[]{ |
549 | 552 |
this.getPluginName(), pluginClassLoader.getPluginName(), res |
... | ... | |
556 | 559 |
} |
557 | 560 |
} |
558 | 561 |
|
559 |
if ( ret == null ) {
|
|
562 |
if (ret == null) {
|
|
560 | 563 |
// |
561 | 564 |
// Por ultimo en el class loader padre, se supone que es el del sistema. |
562 | 565 |
try { |
... | ... | |
564 | 567 |
} catch (Exception e) { |
565 | 568 |
logger.warn("Plugin {}. Error getting resource '{}' in parent classloader'", new Object[]{this.getPluginName(), res}, e); |
566 | 569 |
} |
567 |
if ( ret == null ) {
|
|
570 |
if (ret == null) {
|
|
568 | 571 |
logger.debug("Plugin {}. Resource '{}' not found.", new Object[]{this.getPluginName(), res}); |
569 | 572 |
} |
570 | 573 |
} |
Also available in: Unified diff