author | malenkov |
Fri, 01 Nov 2013 21:45:02 +0400 | |
changeset 21591 | 35320b590d9b |
parent 14342 | 8435a30053c1 |
child 23010 | 6dadb192ad81 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
14342
8435a30053c1
7197491: update copyright year to match last edit in jdk8 jdk repository
alanb
parents:
11119
diff
changeset
|
2 |
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
||
26 |
package sun.misc; |
|
27 |
||
28 |
import java.io.File; |
|
29 |
import java.io.FilenameFilter; |
|
30 |
import java.io.IOException; |
|
31 |
import java.io.FileNotFoundException; |
|
32 |
import java.util.StringTokenizer; |
|
33 |
import java.util.Vector; |
|
34 |
import java.util.Enumeration; |
|
35 |
import java.util.jar.JarFile; |
|
36 |
import java.util.jar.Manifest; |
|
37 |
import java.util.jar.Attributes; |
|
38 |
import java.util.jar.Attributes.Name; |
|
39 |
import java.security.AccessController; |
|
40 |
import java.security.PrivilegedAction; |
|
41 |
import java.security.PrivilegedExceptionAction; |
|
42 |
import java.security.PrivilegedActionException; |
|
43 |
import java.net.URL; |
|
44 |
import java.net.MalformedURLException; |
|
45 |
import sun.net.www.ParseUtil; |
|
46 |
||
47 |
/** |
|
48 |
* <p> |
|
49 |
* This class checks dependent extensions a particular jar file may have |
|
50 |
* declared through its manifest attributes. |
|
51 |
* </p> |
|
52 |
* Jar file declared dependent extensions through the extension-list |
|
53 |
* attribute. The extension-list contains a list of keys used to |
|
54 |
* fetch the other attributes describing the required extension. |
|
55 |
* If key is the extension key declared in the extension-list |
|
56 |
* attribute, the following describing attribute can be found in |
|
57 |
* the manifest : |
|
58 |
* key-Extension-Name: (Specification package name) |
|
59 |
* key-Specification-Version: (Specification-Version) |
|
60 |
* key-Implementation-Version: (Implementation-Version) |
|
61 |
* key-Implementation-Vendor-Id: (Imlementation-Vendor-Id) |
|
62 |
* key-Implementation-Version: (Implementation version) |
|
63 |
* key-Implementation-URL: (URL to download the requested extension) |
|
64 |
* <p> |
|
65 |
* This class also maintain versioning consistency of installed |
|
66 |
* extensions dependencies declared in jar file manifest. |
|
67 |
* </p> |
|
68 |
* @author Jerome Dochez |
|
69 |
*/ |
|
70 |
public class ExtensionDependency { |
|
71 |
||
72 |
/* Callbak interfaces to delegate installation of missing extensions */ |
|
11119
6ff03c1202ce
7116722: Miscellaneous warnings sun.misc ( and related classes )
chegar
parents:
5506
diff
changeset
|
73 |
private static Vector<ExtensionInstallationProvider> providers; |
2 | 74 |
|
75 |
/** |
|
76 |
* <p> |
|
77 |
* Register an ExtensionInstallationProvider. The provider is responsible |
|
78 |
* for handling the installation (upgrade) of any missing extensions. |
|
79 |
* </p> |
|
80 |
* @param eip ExtensionInstallationProvider implementation |
|
81 |
*/ |
|
82 |
public synchronized static void addExtensionInstallationProvider |
|
83 |
(ExtensionInstallationProvider eip) |
|
84 |
{ |
|
85 |
if (providers == null) { |
|
11119
6ff03c1202ce
7116722: Miscellaneous warnings sun.misc ( and related classes )
chegar
parents:
5506
diff
changeset
|
86 |
providers = new Vector<>(); |
2 | 87 |
} |
88 |
providers.add(eip); |
|
89 |
} |
|
90 |
||
91 |
/** |
|
92 |
* <p> |
|
93 |
* Unregister a previously installed installation provider |
|
94 |
* </p> |
|
95 |
*/ |
|
11119
6ff03c1202ce
7116722: Miscellaneous warnings sun.misc ( and related classes )
chegar
parents:
5506
diff
changeset
|
96 |
public synchronized static void removeExtensionInstallationProvider |
2 | 97 |
(ExtensionInstallationProvider eip) |
98 |
{ |
|
99 |
providers.remove(eip); |
|
100 |
} |
|
101 |
||
102 |
/** |
|
103 |
* <p> |
|
104 |
* Checks the dependencies of the jar file on installed extension. |
|
105 |
* </p> |
|
106 |
* @param jarFile containing the attriutes declaring the dependencies |
|
107 |
*/ |
|
108 |
public static boolean checkExtensionsDependencies(JarFile jar) |
|
109 |
{ |
|
110 |
if (providers == null) { |
|
111 |
// no need to bother, nobody is registered to install missing |
|
112 |
// extensions |
|
113 |
return true; |
|
114 |
} |
|
115 |
||
116 |
try { |
|
117 |
ExtensionDependency extDep = new ExtensionDependency(); |
|
118 |
return extDep.checkExtensions(jar); |
|
119 |
} catch (ExtensionInstallationException e) { |
|
120 |
debug(e.getMessage()); |
|
121 |
} |
|
122 |
return false; |
|
123 |
} |
|
124 |
||
125 |
/* |
|
126 |
* Check for all declared required extensions in the jar file |
|
127 |
* manifest. |
|
128 |
*/ |
|
129 |
protected boolean checkExtensions(JarFile jar) |
|
130 |
throws ExtensionInstallationException |
|
131 |
{ |
|
132 |
Manifest man; |
|
133 |
try { |
|
134 |
man = jar.getManifest(); |
|
135 |
} catch (IOException e) { |
|
136 |
return false; |
|
137 |
} |
|
138 |
||
139 |
if (man == null) { |
|
140 |
// The applet does not define a manifest file, so |
|
141 |
// we just assume all dependencies are satisfied. |
|
142 |
return true; |
|
143 |
} |
|
144 |
||
145 |
boolean result = true; |
|
146 |
Attributes attr = man.getMainAttributes(); |
|
147 |
if (attr != null) { |
|
148 |
// Let's get the list of declared dependencies |
|
149 |
String value = attr.getValue(Name.EXTENSION_LIST); |
|
150 |
if (value != null) { |
|
151 |
StringTokenizer st = new StringTokenizer(value); |
|
152 |
// Iterate over all declared dependencies |
|
153 |
while (st.hasMoreTokens()) { |
|
154 |
String extensionName = st.nextToken(); |
|
155 |
debug("The file " + jar.getName() + |
|
156 |
" appears to depend on " + extensionName); |
|
157 |
// Sanity Check |
|
158 |
String extName = extensionName + "-" + |
|
159 |
Name.EXTENSION_NAME.toString(); |
|
160 |
if (attr.getValue(extName) == null) { |
|
161 |
debug("The jar file " + jar.getName() + |
|
162 |
" appers to depend on " |
|
163 |
+ extensionName + " but does not define the " + |
|
164 |
extName + " attribute in its manifest "); |
|
165 |
||
166 |
} else { |
|
167 |
if (!checkExtension(extensionName, attr)) { |
|
168 |
debug("Failed installing " + extensionName); |
|
169 |
result = false; |
|
170 |
} |
|
171 |
} |
|
172 |
} |
|
173 |
} else { |
|
174 |
debug("No dependencies for " + jar.getName()); |
|
175 |
} |
|
176 |
} |
|
177 |
return result; |
|
178 |
} |
|
179 |
||
180 |
||
181 |
/* |
|
182 |
* <p> |
|
183 |
* Check that a particular dependency on an extension is satisfied. |
|
184 |
* </p> |
|
185 |
* @param extensionName is the key used for the attributes in the manifest |
|
186 |
* @param attr is the attributes of the manifest file |
|
187 |
* |
|
188 |
* @return true if the dependency is satisfied by the installed extensions |
|
189 |
*/ |
|
190 |
protected synchronized boolean checkExtension(final String extensionName, |
|
191 |
final Attributes attr) |
|
192 |
throws ExtensionInstallationException |
|
193 |
{ |
|
194 |
debug("Checking extension " + extensionName); |
|
195 |
if (checkExtensionAgainstInstalled(extensionName, attr)) |
|
196 |
return true; |
|
197 |
||
198 |
debug("Extension not currently installed "); |
|
199 |
ExtensionInfo reqInfo = new ExtensionInfo(extensionName, attr); |
|
200 |
return installExtension(reqInfo, null); |
|
201 |
} |
|
202 |
||
203 |
/* |
|
204 |
* <p> |
|
205 |
* Check if a particular extension is part of the currently installed |
|
206 |
* extensions. |
|
207 |
* </p> |
|
208 |
* @param extensionName is the key for the attributes in the manifest |
|
209 |
* @param attr is the attributes of the manifest |
|
210 |
* |
|
211 |
* @return true if the requested extension is already installed |
|
212 |
*/ |
|
213 |
boolean checkExtensionAgainstInstalled(String extensionName, |
|
214 |
Attributes attr) |
|
215 |
throws ExtensionInstallationException |
|
216 |
{ |
|
217 |
File fExtension = checkExtensionExists(extensionName); |
|
218 |
||
219 |
if (fExtension != null) { |
|
220 |
// Extension already installed, just check against this one |
|
221 |
try { |
|
222 |
if (checkExtensionAgainst(extensionName, attr, fExtension)) |
|
223 |
return true; |
|
224 |
} catch (FileNotFoundException e) { |
|
225 |
debugException(e); |
|
226 |
} catch (IOException e) { |
|
227 |
debugException(e); |
|
228 |
} |
|
229 |
return false; |
|
230 |
||
231 |
} else { |
|
232 |
// Not sure if extension is already installed, so check all the |
|
233 |
// installed extension jar files to see if we get a match |
|
234 |
||
235 |
File[] installedExts; |
|
236 |
||
237 |
try { |
|
238 |
// Get the list of installed extension jar files so we can |
|
239 |
// compare the installed versus the requested extension |
|
240 |
installedExts = getInstalledExtensions(); |
|
241 |
} catch(IOException e) { |
|
242 |
debugException(e); |
|
243 |
return false; |
|
244 |
} |
|
245 |
||
246 |
for (int i=0;i<installedExts.length;i++) { |
|
247 |
try { |
|
248 |
if (checkExtensionAgainst(extensionName, attr, installedExts[i])) |
|
249 |
return true; |
|
250 |
} catch (FileNotFoundException e) { |
|
251 |
debugException(e); |
|
252 |
} catch (IOException e) { |
|
253 |
debugException(e); |
|
254 |
// let's continue with the next installed extension |
|
255 |
} |
|
256 |
} |
|
257 |
} |
|
258 |
return false; |
|
259 |
} |
|
260 |
||
261 |
/* |
|
262 |
* <p> |
|
263 |
* Check if the requested extension described by the attributes |
|
264 |
* in the manifest under the key extensionName is compatible with |
|
265 |
* the jar file. |
|
266 |
* </p> |
|
267 |
* |
|
21591 | 268 |
* @param extensionName key in the attribute list |
2 | 269 |
* @param attr manifest file attributes |
270 |
* @param file installed extension jar file to compare the requested |
|
271 |
* extension against. |
|
272 |
*/ |
|
273 |
protected boolean checkExtensionAgainst(String extensionName, |
|
274 |
Attributes attr, |
|
275 |
final File file) |
|
276 |
throws IOException, |
|
277 |
FileNotFoundException, |
|
278 |
ExtensionInstallationException |
|
279 |
{ |
|
280 |
||
281 |
debug("Checking extension " + extensionName + |
|
282 |
" against " + file.getName()); |
|
283 |
||
284 |
// Load the jar file ... |
|
285 |
Manifest man; |
|
286 |
try { |
|
51 | 287 |
man = AccessController.doPrivileged( |
288 |
new PrivilegedExceptionAction<Manifest>() { |
|
289 |
public Manifest run() |
|
2 | 290 |
throws IOException, FileNotFoundException { |
291 |
if (!file.exists()) |
|
292 |
throw new FileNotFoundException(file.getName()); |
|
293 |
JarFile jarFile = new JarFile(file); |
|
294 |
return jarFile.getManifest(); |
|
295 |
} |
|
296 |
}); |
|
297 |
} catch(PrivilegedActionException e) { |
|
298 |
if (e.getException() instanceof FileNotFoundException) |
|
299 |
throw (FileNotFoundException) e.getException(); |
|
300 |
throw (IOException) e.getException(); |
|
301 |
} |
|
302 |
||
303 |
// Construct the extension information object |
|
304 |
ExtensionInfo reqInfo = new ExtensionInfo(extensionName, attr); |
|
305 |
debug("Requested Extension : " + reqInfo); |
|
306 |
||
307 |
int isCompatible = ExtensionInfo.INCOMPATIBLE; |
|
308 |
ExtensionInfo instInfo = null; |
|
309 |
||
310 |
if (man != null) { |
|
311 |
Attributes instAttr = man.getMainAttributes(); |
|
312 |
if (instAttr != null) { |
|
313 |
instInfo = new ExtensionInfo(null, instAttr); |
|
314 |
debug("Extension Installed " + instInfo); |
|
315 |
isCompatible = instInfo.isCompatibleWith(reqInfo); |
|
316 |
switch(isCompatible) { |
|
317 |
case ExtensionInfo.COMPATIBLE: |
|
318 |
debug("Extensions are compatible"); |
|
319 |
return true; |
|
320 |
||
321 |
case ExtensionInfo.INCOMPATIBLE: |
|
322 |
debug("Extensions are incompatible"); |
|
323 |
return false; |
|
324 |
||
325 |
default: |
|
326 |
// everything else |
|
327 |
debug("Extensions require an upgrade or vendor switch"); |
|
328 |
return installExtension(reqInfo, instInfo); |
|
329 |
||
330 |
} |
|
331 |
} |
|
332 |
} |
|
333 |
return false; |
|
334 |
} |
|
335 |
||
336 |
/* |
|
337 |
* <p> |
|
338 |
* An required extension is missing, if an ExtensionInstallationProvider is |
|
339 |
* registered, delegate the installation of that particular extension to it. |
|
340 |
* </p> |
|
341 |
* |
|
342 |
* @param reqInfo Missing extension information |
|
343 |
* @param instInfo Older installed version information |
|
344 |
* |
|
345 |
* @return true if the installation is successful |
|
346 |
*/ |
|
347 |
protected boolean installExtension(ExtensionInfo reqInfo, |
|
348 |
ExtensionInfo instInfo) |
|
349 |
throws ExtensionInstallationException |
|
350 |
{ |
|
11119
6ff03c1202ce
7116722: Miscellaneous warnings sun.misc ( and related classes )
chegar
parents:
5506
diff
changeset
|
351 |
Vector<ExtensionInstallationProvider> currentProviders; |
2 | 352 |
synchronized(providers) { |
11119
6ff03c1202ce
7116722: Miscellaneous warnings sun.misc ( and related classes )
chegar
parents:
5506
diff
changeset
|
353 |
@SuppressWarnings("unchecked") |
6ff03c1202ce
7116722: Miscellaneous warnings sun.misc ( and related classes )
chegar
parents:
5506
diff
changeset
|
354 |
Vector<ExtensionInstallationProvider> tmp = |
6ff03c1202ce
7116722: Miscellaneous warnings sun.misc ( and related classes )
chegar
parents:
5506
diff
changeset
|
355 |
(Vector<ExtensionInstallationProvider>) providers.clone(); |
6ff03c1202ce
7116722: Miscellaneous warnings sun.misc ( and related classes )
chegar
parents:
5506
diff
changeset
|
356 |
currentProviders = tmp; |
2 | 357 |
} |
11119
6ff03c1202ce
7116722: Miscellaneous warnings sun.misc ( and related classes )
chegar
parents:
5506
diff
changeset
|
358 |
for (Enumeration<ExtensionInstallationProvider> e = currentProviders.elements(); |
6ff03c1202ce
7116722: Miscellaneous warnings sun.misc ( and related classes )
chegar
parents:
5506
diff
changeset
|
359 |
e.hasMoreElements();) { |
6ff03c1202ce
7116722: Miscellaneous warnings sun.misc ( and related classes )
chegar
parents:
5506
diff
changeset
|
360 |
ExtensionInstallationProvider eip = e.nextElement(); |
2 | 361 |
|
362 |
if (eip!=null) { |
|
363 |
// delegate the installation to the provider |
|
364 |
if (eip.installExtension(reqInfo, instInfo)) { |
|
365 |
debug(reqInfo.name + " installation successful"); |
|
366 |
Launcher.ExtClassLoader cl = (Launcher.ExtClassLoader) |
|
367 |
Launcher.getLauncher().getClassLoader().getParent(); |
|
368 |
addNewExtensionsToClassLoader(cl); |
|
369 |
return true; |
|
370 |
} |
|
371 |
} |
|
372 |
} |
|
373 |
// We have tried all of our providers, noone could install this |
|
374 |
// extension, we just return failure at this point |
|
375 |
debug(reqInfo.name + " installation failed"); |
|
376 |
return false; |
|
377 |
} |
|
378 |
||
379 |
/** |
|
380 |
* <p> |
|
381 |
* Checks if the extension, that is specified in the extension-list in |
|
382 |
* the applet jar manifest, is already installed (i.e. exists in the |
|
383 |
* extension directory). |
|
384 |
* </p> |
|
385 |
* |
|
386 |
* @param extensionName extension name in the extension-list |
|
387 |
* |
|
388 |
* @return the extension if it exists in the extension directory |
|
389 |
*/ |
|
390 |
private File checkExtensionExists(String extensionName) { |
|
391 |
// Function added to fix bug 4504166 |
|
392 |
final String extName = extensionName; |
|
393 |
final String[] fileExt = {".jar", ".zip"}; |
|
394 |
||
51 | 395 |
return AccessController.doPrivileged( |
396 |
new PrivilegedAction<File>() { |
|
397 |
public File run() { |
|
2 | 398 |
try { |
399 |
File fExtension; |
|
400 |
File[] dirs = getExtDirs(); |
|
401 |
||
402 |
// Search the extension directories for the extension that is specified |
|
403 |
// in the attribute extension-list in the applet jar manifest |
|
404 |
for (int i=0;i<dirs.length;i++) { |
|
405 |
for (int j=0;j<fileExt.length;j++) { |
|
406 |
if (extName.toLowerCase().endsWith(fileExt[j])) { |
|
407 |
fExtension = new File(dirs[i], extName); |
|
408 |
} else { |
|
409 |
fExtension = new File(dirs[i], extName+fileExt[j]); |
|
410 |
} |
|
411 |
debug("checkExtensionExists:fileName " + fExtension.getName()); |
|
412 |
if (fExtension.exists()) { |
|
413 |
return fExtension; |
|
414 |
} |
|
415 |
} |
|
416 |
} |
|
417 |
return null; |
|
418 |
||
419 |
} catch(Exception e) { |
|
420 |
debugException(e); |
|
421 |
return null; |
|
422 |
} |
|
423 |
} |
|
424 |
}); |
|
425 |
} |
|
426 |
||
427 |
/** |
|
428 |
* <p> |
|
429 |
* @return the java.ext.dirs property as a list of directory |
|
430 |
* </p> |
|
431 |
*/ |
|
432 |
private static File[] getExtDirs() { |
|
433 |
String s = java.security.AccessController.doPrivileged( |
|
434 |
new sun.security.action.GetPropertyAction("java.ext.dirs")); |
|
435 |
||
436 |
File[] dirs; |
|
437 |
if (s != null) { |
|
438 |
StringTokenizer st = |
|
439 |
new StringTokenizer(s, File.pathSeparator); |
|
440 |
int count = st.countTokens(); |
|
441 |
debug("getExtDirs count " + count); |
|
442 |
dirs = new File[count]; |
|
443 |
for (int i = 0; i < count; i++) { |
|
444 |
dirs[i] = new File(st.nextToken()); |
|
445 |
debug("getExtDirs dirs["+i+"] "+ dirs[i]); |
|
446 |
} |
|
447 |
} else { |
|
448 |
dirs = new File[0]; |
|
449 |
debug("getExtDirs dirs " + dirs); |
|
450 |
} |
|
451 |
debug("getExtDirs dirs.length " + dirs.length); |
|
452 |
return dirs; |
|
453 |
} |
|
454 |
||
455 |
/* |
|
456 |
* <p> |
|
457 |
* Scan the directories and return all files installed in those |
|
458 |
* </p> |
|
459 |
* @param dirs list of directories to scan |
|
460 |
* |
|
461 |
* @return the list of files installed in all the directories |
|
462 |
*/ |
|
463 |
private static File[] getExtFiles(File[] dirs) throws IOException { |
|
51 | 464 |
Vector<File> urls = new Vector<File>(); |
2 | 465 |
for (int i = 0; i < dirs.length; i++) { |
466 |
String[] files = dirs[i].list(new JarFilter()); |
|
467 |
if (files != null) { |
|
468 |
debug("getExtFiles files.length " + files.length); |
|
469 |
for (int j = 0; j < files.length; j++) { |
|
470 |
File f = new File(dirs[i], files[j]); |
|
471 |
urls.add(f); |
|
472 |
debug("getExtFiles f["+j+"] "+ f); |
|
473 |
} |
|
474 |
} |
|
475 |
} |
|
476 |
File[] ua = new File[urls.size()]; |
|
477 |
urls.copyInto(ua); |
|
478 |
debug("getExtFiles ua.length " + ua.length); |
|
479 |
return ua; |
|
480 |
} |
|
481 |
||
482 |
/* |
|
483 |
* <p> |
|
484 |
* @return the list of installed extensions jar files |
|
485 |
* </p> |
|
486 |
*/ |
|
487 |
private File[] getInstalledExtensions() throws IOException { |
|
51 | 488 |
return AccessController.doPrivileged( |
489 |
new PrivilegedAction<File[]>() { |
|
490 |
public File[] run() { |
|
2 | 491 |
try { |
492 |
return getExtFiles(getExtDirs()); |
|
493 |
} catch(IOException e) { |
|
494 |
debug("Cannot get list of installed extensions"); |
|
495 |
debugException(e); |
|
51 | 496 |
return new File[0]; |
2 | 497 |
} |
498 |
} |
|
499 |
}); |
|
500 |
} |
|
501 |
||
502 |
/* |
|
503 |
* <p> |
|
504 |
* Add the newly installed jar file to the extension class loader. |
|
505 |
* </p> |
|
506 |
* |
|
507 |
* @param cl the current installed extension class loader |
|
508 |
* |
|
509 |
* @return true if successful |
|
510 |
*/ |
|
511 |
private Boolean addNewExtensionsToClassLoader(Launcher.ExtClassLoader cl) { |
|
512 |
try { |
|
513 |
File[] installedExts = getInstalledExtensions(); |
|
514 |
for (int i=0;i<installedExts.length;i++) { |
|
515 |
final File instFile = installedExts[i]; |
|
516 |
URL instURL = AccessController.doPrivileged( |
|
517 |
new PrivilegedAction<URL>() { |
|
518 |
public URL run() { |
|
519 |
try { |
|
520 |
return ParseUtil.fileToEncodedURL(instFile); |
|
521 |
} catch (MalformedURLException e) { |
|
522 |
debugException(e); |
|
523 |
return null; |
|
524 |
} |
|
525 |
} |
|
526 |
}); |
|
527 |
if (instURL != null) { |
|
528 |
URL[] urls = cl.getURLs(); |
|
529 |
boolean found=false; |
|
530 |
for (int j = 0; j<urls.length; j++) { |
|
531 |
debug("URL["+j+"] is " + urls[j] + " looking for "+ |
|
532 |
instURL); |
|
533 |
if (urls[j].toString().compareToIgnoreCase( |
|
534 |
instURL.toString())==0) { |
|
535 |
found=true; |
|
536 |
debug("Found !"); |
|
537 |
} |
|
538 |
} |
|
539 |
if (!found) { |
|
540 |
debug("Not Found ! adding to the classloader " + |
|
541 |
instURL); |
|
542 |
cl.addExtURL(instURL); |
|
543 |
} |
|
544 |
} |
|
545 |
} |
|
546 |
} catch (MalformedURLException e) { |
|
547 |
e.printStackTrace(); |
|
548 |
} catch (IOException e) { |
|
549 |
e.printStackTrace(); |
|
550 |
// let's continue with the next installed extension |
|
551 |
} |
|
552 |
return Boolean.TRUE; |
|
553 |
} |
|
554 |
||
555 |
// True to display all debug and trace messages |
|
556 |
static final boolean DEBUG = false; |
|
557 |
||
558 |
private static void debug(String s) { |
|
559 |
if (DEBUG) { |
|
560 |
System.err.println(s); |
|
561 |
} |
|
562 |
} |
|
563 |
||
564 |
private void debugException(Throwable e) { |
|
565 |
if (DEBUG) { |
|
566 |
e.printStackTrace(); |
|
567 |
} |
|
568 |
} |
|
569 |
||
570 |
} |