提交 e21afc43 编写于 作者: J jjg

6176978: current Javadoc's invocation and extension (Doclet) mechanisms are problematic

Reviewed-by: darcy
上级 b265b296
......@@ -83,7 +83,7 @@ public class DocletInvoker {
cpString = appendPath(docletPath, cpString);
URL[] urls = pathToURLs(cpString);
if (docletParentClassLoader == null)
appClassLoader = new URLClassLoader(urls);
appClassLoader = new URLClassLoader(urls, getDelegationClassLoader(docletClassName));
else
appClassLoader = new URLClassLoader(urls, docletParentClassLoader);
......@@ -98,6 +98,57 @@ public class DocletInvoker {
docletClass = dc;
}
/*
* Returns the delegation class loader to use when creating
* appClassLoader (used to load the doclet). The context class
* loader is the best choice, but legacy behavior was to use the
* default delegation class loader (aka system class loader).
*
* Here we favor using the context class loader. To ensure
* compatibility with existing apps, we revert to legacy
* behavior if either or both of the following conditions hold:
*
* 1) the doclet is loadable from the system class loader but not
* from the context class loader,
*
* 2) this.getClass() is loadable from the system class loader but not
* from the context class loader.
*/
private ClassLoader getDelegationClassLoader(String docletClassName) {
ClassLoader ctxCL = Thread.currentThread().getContextClassLoader();
ClassLoader sysCL = ClassLoader.getSystemClassLoader();
if (sysCL == null)
return ctxCL;
if (ctxCL == null)
return sysCL;
// Condition 1.
try {
sysCL.loadClass(docletClassName);
try {
ctxCL.loadClass(docletClassName);
} catch (ClassNotFoundException e) {
return sysCL;
}
} catch (ClassNotFoundException e) {
}
// Condition 2.
try {
if (getClass() == sysCL.loadClass(getClass().getName())) {
try {
if (getClass() != ctxCL.loadClass(getClass().getName()))
return sysCL;
} catch (ClassNotFoundException e) {
return sysCL;
}
}
} catch (ClassNotFoundException e) {
}
return ctxCL;
}
/**
* Generate documentation here. Return true on success.
*/
......@@ -231,6 +282,8 @@ public class DocletInvoker {
docletClassName, methodName);
throw new DocletInvokeException();
}
ClassLoader savedCCL =
Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(appClassLoader);
return meth.invoke(null , params);
......@@ -256,6 +309,8 @@ public class DocletInvoker {
exc.getTargetException().printStackTrace();
}
throw new DocletInvokeException();
} finally {
Thread.currentThread().setContextClassLoader(savedCCL);
}
}
......
/*
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6176978
* @summary current Javadoc's invocation and extension (Doclet) mechanisms are problematic
* @build T6176978
* @run main T6176978
*/
import java.io.*;
import java.net.*;
public class T6176978
{
public static void main(String[] args) throws Exception {
// create and use a temp dir that will not be on jtreg's
// default class path
File tmpDir = new File("tmp");
tmpDir.mkdirs();
File testSrc = new File(System.getProperty("test.src", "."));
String[] javac_args = {
"-d",
"tmp",
new File(testSrc, "X.java").getPath()
};
int rc = com.sun.tools.javac.Main.compile(javac_args);
if (rc != 0)
throw new Error("javac exit code: " + rc);
String[] jdoc_args = {
"-doclet",
"X",
new File(testSrc, "T6176978.java").getPath()
};
rc = com.sun.tools.javadoc.Main.execute(jdoc_args);
if (rc == 0)
throw new Error("javadoc unexpectedly succeeded");
Thread currThread = Thread.currentThread();
ClassLoader saveClassLoader = currThread.getContextClassLoader();
URLClassLoader urlCL = new URLClassLoader(new URL[] { tmpDir.toURL() });
currThread.setContextClassLoader(urlCL);
try {
rc = com.sun.tools.javadoc.Main.execute(jdoc_args);
if (rc != 0)
throw new Error("javadoc exit: " + rc);
}
finally {
currThread.setContextClassLoader(saveClassLoader);
}
}
}
/*
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import com.sun.javadoc.*;
public class X {
public static boolean start(RootDoc root) {
System.out.println("X.start");
return true;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册