1.1 --- a/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java Tue Jan 27 17:50:53 2009 -0800 1.2 +++ b/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java Tue Jan 27 18:38:39 2009 -0800 1.3 @@ -83,7 +83,7 @@ 1.4 cpString = appendPath(docletPath, cpString); 1.5 URL[] urls = pathToURLs(cpString); 1.6 if (docletParentClassLoader == null) 1.7 - appClassLoader = new URLClassLoader(urls); 1.8 + appClassLoader = new URLClassLoader(urls, getDelegationClassLoader(docletClassName)); 1.9 else 1.10 appClassLoader = new URLClassLoader(urls, docletParentClassLoader); 1.11 1.12 @@ -98,6 +98,57 @@ 1.13 docletClass = dc; 1.14 } 1.15 1.16 + /* 1.17 + * Returns the delegation class loader to use when creating 1.18 + * appClassLoader (used to load the doclet). The context class 1.19 + * loader is the best choice, but legacy behavior was to use the 1.20 + * default delegation class loader (aka system class loader). 1.21 + * 1.22 + * Here we favor using the context class loader. To ensure 1.23 + * compatibility with existing apps, we revert to legacy 1.24 + * behavior if either or both of the following conditions hold: 1.25 + * 1.26 + * 1) the doclet is loadable from the system class loader but not 1.27 + * from the context class loader, 1.28 + * 1.29 + * 2) this.getClass() is loadable from the system class loader but not 1.30 + * from the context class loader. 1.31 + */ 1.32 + private ClassLoader getDelegationClassLoader(String docletClassName) { 1.33 + ClassLoader ctxCL = Thread.currentThread().getContextClassLoader(); 1.34 + ClassLoader sysCL = ClassLoader.getSystemClassLoader(); 1.35 + if (sysCL == null) 1.36 + return ctxCL; 1.37 + if (ctxCL == null) 1.38 + return sysCL; 1.39 + 1.40 + // Condition 1. 1.41 + try { 1.42 + sysCL.loadClass(docletClassName); 1.43 + try { 1.44 + ctxCL.loadClass(docletClassName); 1.45 + } catch (ClassNotFoundException e) { 1.46 + return sysCL; 1.47 + } 1.48 + } catch (ClassNotFoundException e) { 1.49 + } 1.50 + 1.51 + // Condition 2. 1.52 + try { 1.53 + if (getClass() == sysCL.loadClass(getClass().getName())) { 1.54 + try { 1.55 + if (getClass() != ctxCL.loadClass(getClass().getName())) 1.56 + return sysCL; 1.57 + } catch (ClassNotFoundException e) { 1.58 + return sysCL; 1.59 + } 1.60 + } 1.61 + } catch (ClassNotFoundException e) { 1.62 + } 1.63 + 1.64 + return ctxCL; 1.65 + } 1.66 + 1.67 /** 1.68 * Generate documentation here. Return true on success. 1.69 */ 1.70 @@ -231,6 +282,8 @@ 1.71 docletClassName, methodName); 1.72 throw new DocletInvokeException(); 1.73 } 1.74 + ClassLoader savedCCL = 1.75 + Thread.currentThread().getContextClassLoader(); 1.76 try { 1.77 Thread.currentThread().setContextClassLoader(appClassLoader); 1.78 return meth.invoke(null , params); 1.79 @@ -256,6 +309,8 @@ 1.80 exc.getTargetException().printStackTrace(); 1.81 } 1.82 throw new DocletInvokeException(); 1.83 + } finally { 1.84 + Thread.currentThread().setContextClassLoader(savedCCL); 1.85 } 1.86 } 1.87