1 22 package org.objectweb.petals.classloader; 23 24 import java.io.File ; 25 import java.io.FileInputStream ; 26 import java.io.FileNotFoundException ; 27 import java.io.IOException ; 28 import java.io.InputStream ; 29 import java.net.URL ; 30 import java.net.URLClassLoader ; 31 import java.net.URLStreamHandlerFactory ; 32 import java.util.Enumeration ; 33 import java.util.HashSet ; 34 import java.util.List ; 35 import java.util.Set ; 36 import java.util.jar.JarFile ; 37 38 import org.objectweb.petals.classloader.factory.URLFactory; 39 import org.objectweb.petals.classloader.locator.Locator; 40 41 50 public class PetalsClassLoader extends URLClassLoader { 51 52 55 private static final String JAVA_PACKAGE = "java."; 56 57 60 private static final String JAVAX_PACKAGE = "javax."; 61 62 65 private boolean parentFirst; 66 67 70 private boolean ignoreParent; 71 72 75 private boolean usePackageIntelligence; 76 77 80 private Set <String > localKnownPackages; 81 82 85 protected ClassLoader parent; 86 87 90 private URLFactory[] factories; 91 92 95 private Locator[] locators; 96 97 100 private URL [] bases; 101 102 111 public PetalsClassLoader(URL [] baseUrls, List <String > classpathLocations, ClassLoader parent) throws IOException { 112 super(baseUrls, parent); 113 this.parent = parent; 114 this.bases = baseUrls; 115 initialize(classpathLocations); 116 } 117 118 126 public PetalsClassLoader(URL [] baseUrls, List <String > classpathLocations) throws IOException { 127 super(baseUrls); 128 this.bases = baseUrls; 129 initialize(classpathLocations); 130 } 131 132 142 public PetalsClassLoader(URL [] baseUrls, List <String > classpathLocations, ClassLoader parent, URLStreamHandlerFactory factory) throws IOException { 143 super(baseUrls, parent, factory); 144 this.parent = parent; 145 this.bases = baseUrls; 146 initialize(classpathLocations); 147 } 148 149 153 156 public boolean isParentFirst() { 157 return parentFirst; 158 } 159 160 163 public void setParentFirst(boolean use) { 164 this.parentFirst = use; 165 } 166 167 170 public boolean isIsolated() { 171 return ignoreParent; 172 } 173 174 177 public void setIsolated(boolean isolated) { 178 this.ignoreParent = isolated; 179 } 180 181 184 public boolean isUsingPackageIntelligence() { 185 localKnownPackages = null; 186 return usePackageIntelligence; 187 } 188 189 192 public void setUsingPackageIntelligence(boolean use) { 193 localKnownPackages = new HashSet <String >(); 194 this.usePackageIntelligence = use; 195 } 196 197 200 public URL [] getBases() { 201 return bases; 202 } 203 204 208 public String getClasspath() { 209 URL [] urls = getURLs(); 210 StringBuffer cp = new StringBuffer (); 211 for (int i = 0; i < urls.length; i++) { 212 String url = urls[i].getFile(); 213 if (url.indexOf("!/") == -1) { 215 cp.append(File.pathSeparator + url); 216 } 217 } 218 return cp.toString(); 219 } 220 221 225 232 @Override 233 protected synchronized Class <?> loadClass(String className, boolean resolve) throws ClassNotFoundException { 234 Class <?> clazz = null; 235 clazz = findLoadedClass(className); 236 if (clazz == null) { 237 if (useParentFirst(className, true)) { 239 try { 240 clazz = parent.loadClass(className); 241 } 242 catch (ClassNotFoundException cnfe) { 243 clazz = findClass(className); 244 } 245 } 246 else { 248 try { 249 clazz = findClass(className); 250 } 251 catch (Exception cnfe) { 252 try { 253 clazz = parent.loadClass(className); 254 } 255 catch (Exception e) { 256 throw new ClassNotFoundException (className); 257 } 258 if (clazz == null) { 259 throw new ClassNotFoundException (className); 260 } 261 } 262 } 263 } 264 if (resolve) { 265 resolveClass(clazz); 266 } 267 return clazz; 268 } 269 270 277 @Override 278 protected Class <?> findClass(String className) throws ClassNotFoundException { 279 return super.findClass(className); 280 } 281 282 288 @Override 289 public URL getResource(String resourceName) { 290 URL resource = null; 291 if (useParentFirst(resourceName, false)) { 293 resource = parent.getResource(resourceName); 294 if (resource == null) { 295 resource = findResource(resourceName); 296 } 297 } 298 else { 300 resource = findResource(resourceName); 301 if (resource == null && !isIsolated()) { 302 resource = parent.getResource(resourceName); 303 } 304 } 305 return resource; 306 } 307 308 314 @Override 315 public InputStream getResourceAsStream(String resourceName) { 316 InputStream inputStream = null; 317 if (useParentFirst(resourceName, false)) { 319 inputStream = parent.getResourceAsStream(resourceName); 320 if (inputStream == null) { 321 URL url = findResource(resourceName); 322 if (url != null) { 323 try { 324 if (url.getProtocol().equals("file")) { 325 inputStream = new FileInputStream (url.getPath()); 327 } 328 else if (url.getProtocol().equals("jar")) { 329 try { 331 String fileName = url.getPath().substring(0, url.getPath().indexOf("!")); 332 fileName = fileName.substring(5); 333 JarFile jarFile = new JarFile (fileName); 334 inputStream = jarFile.getInputStream(jarFile.getEntry(url.getPath().substring(url.getPath().indexOf("!") + 2))); 335 } 336 catch (IOException e) { 337 inputStream = null; 338 } 339 } 340 } 341 catch (FileNotFoundException e) { 342 inputStream = null; 343 } 344 } 345 } 346 } 347 else { 349 URL url = findResource(resourceName); 350 if (url == null && !isIsolated()) { 351 url = parent.getResource(resourceName); 352 } 353 if (url != null) { 354 try { 355 if (url.getProtocol().equals("file")) { 356 inputStream = new FileInputStream (url.getPath()); 358 } 359 else if (url.getProtocol().equals("jar")) { 360 try { 362 String fileName = url.getPath().substring(0, url.getPath().indexOf("!")); 363 fileName = fileName.substring(5); 364 JarFile jarFile = new JarFile (fileName); 365 inputStream = jarFile.getInputStream(jarFile.getEntry(url.getPath().substring(url.getPath().indexOf("!") + 2))); 366 } 367 catch (IOException e) { 368 inputStream = null; 369 } 370 } 371 } 372 catch (FileNotFoundException e) { 373 inputStream = null; 374 } 375 } 376 } 377 return inputStream; 378 } 379 380 385 @Override 386 public Enumeration <URL > getResources(String resourceName) throws IOException { 387 Enumeration <URL > resources = null; 388 if (useParentFirst(resourceName, false)) { 390 resources = parent.getResources(resourceName); 391 if (resources == null) { 392 resources = findResources(resourceName); 393 } 394 } 395 else { 397 resources = findResources(resourceName); 398 if (!resources.hasMoreElements() && !isIsolated()) { 399 resources = parent.getResources(resourceName); 400 } 401 } 402 return resources; 403 } 404 405 409 414 protected void initialize(List <String > classpathLocations) throws IOException { 415 this.parentFirst = true; 416 this.ignoreParent = false; 417 this.usePackageIntelligence = false; 418 if (parent == null) { 419 parent = getSystemClassLoader(); 420 } 421 factories = new URLFactory[bases.length]; 422 locators = new Locator[bases.length]; 423 for (int i = 0; i < bases.length; i++) { 425 factories[i] = URLFactory.getFactory(bases[i]); 426 locators[i] = Locator.getLocator(bases[i]); 427 } 428 for (String location : classpathLocations) { 430 addInRepository(location); 431 } 432 } 433 434 441 protected boolean useParentFirst(String resourceName, boolean usingForClass) { 442 boolean useParentFirst = isParentFirst() && !isIsolated(); 444 if (useParentFirst) { 446 if (isUsingPackageIntelligence() && usingForClass) { 447 String packageName = getPackageName(resourceName); 448 useParentFirst = !knowLocalPackage(packageName); 450 } 451 } 452 else { 454 useParentFirst = (JAVA_PACKAGE.startsWith(resourceName) || JAVAX_PACKAGE.startsWith(resourceName)); 455 } 456 return useParentFirst; 457 } 458 459 464 protected void addLocalKnownPackage(String packageName) { 465 if (localKnownPackages != null) { 466 localKnownPackages.add(packageName); 467 } 468 } 469 470 476 protected boolean knowLocalPackage(String packageName) { 477 boolean known = false; 478 if (localKnownPackages != null) { 479 known = localKnownPackages.contains(packageName); 480 } 481 return known; 482 } 483 484 490 protected String getPackageName(String className) { 491 int lastSeparator = className.lastIndexOf('.'); 492 String packageName = className.substring(0, lastSeparator); 493 return packageName; 494 } 495 496 504 protected void addInRepository(String location) throws IOException { 505 for (int i = 0; i < bases.length; i++) { 507 if (locators[i].hasDirectory(location) || locators[i].hasFile(location)) { 508 addURL(factories[i].getURL(location)); 509 } 510 } 511 } 512 513 516 public String toString() { 517 StringBuffer sb = new StringBuffer (); 518 519 sb.append("classloader : " + getClass().getName() + "\n"); 520 sb.append("\tmodules bases (not in loader!) : \n"); 521 for (int i = 0; i < bases.length; i++) { 522 sb.append("\t\t -" + bases[i] + "\n"); 523 } 524 sb.append("\trepositories :\n"); 525 URL [] rep = getURLs(); 526 for (int i = 0; i < rep.length; i++) { 527 sb.append("\t\t -" + rep[i] + "\n"); 528 } 529 sb.append("\tparent : " + getParent() + "\n"); 530 531 return sb.toString(); 532 } 533 534 542 Class <?> findLoadedClazz(String className) throws ClassNotFoundException { 543 return super.findLoadedClass(className); 544 } 545 } 546 | Popular Tags |