--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java Mon Oct 10 06:47:47 2016 -0700
@@ -40,7 +40,6 @@
import jdk.javadoc.internal.doclets.toolkit.builders.BuilderFactory;
import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
-import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
import jdk.javadoc.internal.doclets.toolkit.util.InternalException;
import jdk.javadoc.internal.doclets.toolkit.util.PackageListWriter;
import jdk.javadoc.internal.doclets.toolkit.util.ResourceIOException;
@@ -112,8 +111,6 @@
return false;
}
- boolean dumpOnError = false; // set true to always show stack traces
-
try {
startGeneration(docEnv);
return true;
@@ -128,16 +125,16 @@
messages.error("doclet.exception.write.file",
e.fileName.getPath(), e.getCause());
}
- dumpStack(dumpOnError, e);
+ dumpStack(configuration.dumpOnError, e);
} catch (ResourceIOException e) {
messages.error("doclet.exception.read.resource",
e.resource.getPath(), e.getCause());
- dumpStack(dumpOnError, e);
+ dumpStack(configuration.dumpOnError, e);
} catch (SimpleDocletException e) {
configuration.reporter.print(ERROR, e.getMessage());
- dumpStack(dumpOnError, e);
+ dumpStack(configuration.dumpOnError, e);
} catch (InternalException e) {
configuration.reporter.print(ERROR, e.getMessage());
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java Mon Oct 10 06:47:47 2016 -0700
@@ -281,6 +281,8 @@
private String pkglistUrlForLinkOffline;
+ public boolean dumpOnError = false;
+
private List<GroupContainer> groups;
public abstract Messages getMessages();
@@ -616,6 +618,13 @@
showversion = true;
return true;
}
+ },
+ new Hidden(resources, "--dump-on-error") {
+ @Override
+ public boolean process(String opt, ListIterator<String> args) {
+ dumpOnError = true;
+ return true;
+ }
}
};
Set<Doclet.Option> set = new TreeSet<>();
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java Mon Oct 10 06:47:47 2016 -0700
@@ -75,6 +75,7 @@
import jdk.javadoc.doclet.DocletEnvironment.ModuleMode;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
+import static jdk.javadoc.internal.tool.Main.Result.*;
import static jdk.javadoc.internal.tool.JavadocTool.isValidClassName;
/**
@@ -158,6 +159,7 @@
private final Location location;
private final Modules modules;
private final Map<ToolOption, Object> opts;
+ private final Messager messager;
private final Map<String, Entry> entries = new LinkedHashMap<>();
@@ -201,6 +203,8 @@
this.fm = toolEnv.fileManager;
this.modules = Modules.instance(context);
this.opts = opts;
+ this.messager = Messager.instance0(context);
+
this.location = modules.multiModuleMode
? StandardLocation.MODULE_SOURCE_PATH
: toolEnv.fileManager.hasLocation(StandardLocation.SOURCE_PATH)
@@ -339,9 +343,9 @@
* This is a terminal operation, thus no further modifications
* are allowed to the specified data sets.
*
- * @throws IOException if an error occurs
+ * @throws ToolException if an error occurs
*/
- void analyze() throws IOException {
+ void analyze() throws ToolException {
// compute the specified element, by expanding module dependencies
computeSpecifiedModules();
@@ -354,7 +358,6 @@
// compute the packages belonging to all the specified modules
Set<PackageElement> expandedModulePackages = computeModulePackages();
initializeIncludedSets(expandedModulePackages);
-
}
ElementsTable classTrees(com.sun.tools.javac.util.List<JCCompilationUnit> classTrees) {
@@ -363,16 +366,17 @@
}
@SuppressWarnings("unchecked")
- ElementsTable scanSpecifiedItems() throws IOException {
+ ElementsTable scanSpecifiedItems() throws ToolException {
// scan modules specified on the command line
List<String> moduleNames = (List<String>) opts.computeIfAbsent(ToolOption.MODULE,
s -> Collections.EMPTY_LIST);
List<String> mlist = new ArrayList<>();
for (String m : moduleNames) {
- Location moduleLoc = fm.getModuleLocation(location, m);
+ Location moduleLoc = getModuleLocation(location, m);
if (moduleLoc == null) {
- toolEnv.error("main.module_not_found", m);
+ String text = messager.getText("main.module_not_found", m);
+ throw new ToolException(CMDERR, text);
} else {
mlist.add(m);
ModuleSymbol msym = syms.enterModule(names.fromString(m));
@@ -457,7 +461,7 @@
}
@SuppressWarnings("unchecked")
- private void computeSubpackages() throws IOException {
+ private void computeSubpackages() throws ToolException {
((List<String>) opts.computeIfAbsent(ToolOption.EXCLUDE, v -> Collections.EMPTY_LIST))
.stream()
.map((packageName) -> new ModulePackage(packageName))
@@ -469,7 +473,14 @@
for (ModulePackage modpkg : subPackages) {
Location packageLocn = getLocation(modpkg);
- for (JavaFileObject fo : fm.list(packageLocn, modpkg.packageName, sourceKinds, true)) {
+ Iterable<JavaFileObject> list = null;
+ try {
+ list = fm.list(packageLocn, modpkg.packageName, sourceKinds, true);
+ } catch (IOException ioe) {
+ String text = messager.getText("main.file.manager.list", modpkg.packageName);
+ throw new ToolException(SYSERR, text, ioe);
+ }
+ for (JavaFileObject fo : list) {
String binaryName = fm.inferBinaryName(packageLocn, fo);
String pn = getPackageName(binaryName);
String simpleName = getSimpleName(binaryName);
@@ -554,22 +565,28 @@
specifiedModuleElements = Collections.unmodifiableSet(result);
}
- private Set<PackageElement> getAllModulePackages(ModuleElement mdle) throws IOException {
+ private Set<PackageElement> getAllModulePackages(ModuleElement mdle) throws ToolException {
Set<PackageElement> result = new HashSet<>();
- ModuleSymbol msym = (ModuleSymbol)mdle;
- Location msymloc = fm.getModuleLocation(location, msym.name.toString());
- for (JavaFileObject fo : fm.list(msymloc, "", sourceKinds, true)) {
- if (fo.getName().endsWith("module-info.java"))
- continue;
- String binaryName = fm.inferBinaryName(msymloc, fo);
- String pn = getPackageName(binaryName);
- PackageSymbol psym = syms.enterPackage(msym, names.fromString(pn));
- result.add((PackageElement)psym);
+ ModuleSymbol msym = (ModuleSymbol) mdle;
+ Location msymloc = getModuleLocation(location, msym.name.toString());
+ try {
+ for (JavaFileObject fo : fm.list(msymloc, "", sourceKinds, true)) {
+ if (fo.getName().endsWith("module-info.java"))
+ continue;
+ String binaryName = fm.inferBinaryName(msymloc, fo);
+ String pn = getPackageName(binaryName);
+ PackageSymbol psym = syms.enterPackage(msym, names.fromString(pn));
+ result.add((PackageElement) psym);
+ }
+
+ } catch (IOException ioe) {
+ String text = messager.getText("main.file.manager.list", msymloc.getName());
+ throw new ToolException(SYSERR, text, ioe);
}
return result;
}
- private Set<PackageElement> computeModulePackages() throws IOException {
+ private Set<PackageElement> computeModulePackages() throws ToolException {
final AccessKind accessValue = accessFilter.getAccessValue(ElementKind.PACKAGE);
final boolean documentAllModulePackages = (accessValue == AccessKind.PACKAGE ||
accessValue == AccessKind.PRIVATE);
@@ -662,10 +679,10 @@
includedTypeElements = Collections.unmodifiableSet(iclasses);
}
- /**
+ /*
* Computes the included packages and freezes the specified packages list.
*/
- private void computeSpecifiedPackages() throws IOException {
+ private void computeSpecifiedPackages() throws ToolException {
computeSubpackages();
@@ -683,7 +700,7 @@
if (pkg != null) {
packlist.add(pkg);
} else {
- toolEnv.warning("main.package_not_found", modpkg.toString());
+ messager.printWarningUsingKey("main.package_not_found", modpkg.toString());
}
});
specifiedPackageElements = Collections.unmodifiableSet(packlist);
@@ -693,7 +710,7 @@
* Adds all classes as well as inner classes, to the specified
* list.
*/
- private void computeSpecifiedTypes() {
+ private void computeSpecifiedTypes() throws ToolException {
Set<TypeElement> classes = new LinkedHashSet<>();
classDecList.stream().filter((def) -> (shouldDocument(def.sym))).forEach((def) -> {
TypeElement te = (TypeElement) def.sym;
@@ -701,24 +718,28 @@
addAllClasses(classes, te, true);
}
});
- classArgList.forEach((className) -> {
+ for (String className : classArgList) {
TypeElement te = toolEnv.loadClass(className);
if (te == null) {
- toolEnv.error("javadoc.class_not_found", className);
+ String text = messager.getText("javadoc.class_not_found", className);
+ throw new ToolException(CMDERR, text);
} else {
addAllClasses(classes, te, true);
}
- });
+ }
specifiedTypeElements = Collections.unmodifiableSet(classes);
}
private void addFilesForParser(Collection<JavaFileObject> result,
- Collection<ModulePackage> collection, boolean recurse) throws IOException {
+ Collection<ModulePackage> collection,
+ boolean recurse) throws ToolException {
for (ModulePackage modpkg : collection) {
toolEnv.notice("main.Loading_source_files_for_package", modpkg.toString());
List<JavaFileObject> files = getFiles(modpkg, recurse);
if (files.isEmpty()) {
- toolEnv.error("main.no_source_files_for_package", modpkg.toString());
+ String text = messager.getText("main.no_source_files_for_package",
+ modpkg.toString());
+ throw new ToolException(CMDERR, text);
} else {
result.addAll(files);
}
@@ -732,7 +753,7 @@
* @return a list of java file objects
* @throws IOException if an error occurs
*/
- List<JavaFileObject> getFilesToParse() throws IOException {
+ List<JavaFileObject> getFilesToParse() throws ToolException {
List<JavaFileObject> result = new ArrayList<>();
addFilesForParser(result, cmdLinePackages, false);
addFilesForParser(result, subPackages, true);
@@ -744,9 +765,10 @@
*
* @param packageName the specified package
* @return the set of file objects for the specified package
- * @throws IOException if an error occurs while accessing the files
+ * @throws ToolException if an error occurs while accessing the files
*/
- private List<JavaFileObject> getFiles(ModulePackage modpkg, boolean recurse) throws IOException {
+ private List<JavaFileObject> getFiles(ModulePackage modpkg,
+ boolean recurse) throws ToolException {
Entry e = getEntry(modpkg);
// The files may have been found as a side effect of searching for subpackages
if (e.files != null) {
@@ -759,12 +781,18 @@
return Collections.emptyList();
}
String pname = modpkg.packageName;
- for (JavaFileObject fo : fm.list(packageLocn, pname, sourceKinds, recurse)) {
- String binaryName = fm.inferBinaryName(packageLocn, fo);
- String simpleName = getSimpleName(binaryName);
- if (isValidClassName(simpleName)) {
- lb.append(fo);
+
+ try {
+ for (JavaFileObject fo : fm.list(packageLocn, pname, sourceKinds, recurse)) {
+ String binaryName = fm.inferBinaryName(packageLocn, fo);
+ String simpleName = getSimpleName(binaryName);
+ if (isValidClassName(simpleName)) {
+ lb.append(fo);
+ }
}
+ } catch (IOException ioe) {
+ String text = messager.getText("main.file.manager.list", pname);
+ throw new ToolException(SYSERR, text, ioe);
}
return lb.toList();
@@ -781,20 +809,30 @@
return null;
}
- private Location getLocation(ModulePackage modpkg) throws IOException {
+ private Location getLocation(ModulePackage modpkg) throws ToolException {
if (location != StandardLocation.MODULE_SOURCE_PATH) {
return location;
}
if (modpkg.hasModule()) {
- return fm.getModuleLocation(location, modpkg.moduleName);
+ return getModuleLocation(location, modpkg.moduleName);
}
// TODO: handle invalid results better.
ModuleSymbol msym = findModuleOfPackageName(modpkg.packageName);
if (msym == null) {
return null;
}
- return fm.getModuleLocation(location, msym.name.toString());
+ return getModuleLocation(location, msym.name.toString());
+ }
+
+ private Location getModuleLocation(Location location, String msymName)
+ throws ToolException {
+ try {
+ return fm.getModuleLocation(location, msymName);
+ } catch (IOException ioe) {
+ String text = messager.getText("main.doclet_could_not_get_location", msymName);
+ throw new ToolException(ERROR, text, ioe);
+ }
}
private Entry getEntry(String name) {
@@ -841,7 +879,10 @@
}
}
} catch (CompletionFailure e) {
- // quietly ignore completion failures
+ if (e.getMessage() != null)
+ messager.printWarning(e.getMessage());
+ else
+ messager.printWarningUsingKey("main.unexpected.exception", e);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/IllegalOptionValue.java Mon Oct 10 06:47:47 2016 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.javadoc.internal.tool;
+
+import static jdk.javadoc.internal.tool.Main.Result.CMDERR;
+
+/**
+ * Provides a mechanism for the javadoc tool to indicate an option
+ * decoding issue, arising from command line error.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+
+class IllegalOptionValue extends OptionException {
+
+ private static final long serialVersionUID = 0;
+
+ /**
+ * Constructs an object containing a runnable and a message.
+ * @param method a method to display suitable usage text
+ * @param message the detailed message
+ */
+ IllegalOptionValue(Runnable method, String message) {
+ super(CMDERR, method, message);
+ }
+}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java Mon Oct 10 06:47:47 2016 -0700
@@ -27,7 +27,6 @@
import java.io.File;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
@@ -51,6 +50,8 @@
import com.sun.tools.javac.util.Position;
import jdk.javadoc.doclet.DocletEnvironment;
+import static jdk.javadoc.internal.tool.Main.Result.*;
+
/**
* This class could be the main entry point for Javadoc when Javadoc is used as a
* component in a larger software system. It provides operations to
@@ -120,9 +121,10 @@
}
}
- public DocletEnvironment getEnvironment(Map<ToolOption, Object> jdtoolOpts,
- List<String> javaNames,
- Iterable<? extends JavaFileObject> fileObjects) throws IOException {
+ public DocletEnvironment getEnvironment(Map<ToolOption,
+ Object> jdtoolOpts,
+ List<String> javaNames,
+ Iterable<? extends JavaFileObject> fileObjects) throws ToolException {
toolEnv = ToolEnvironment.instance(context);
toolEnv.initialize(jdtoolOpts);
ElementsTable etable = new ElementsTable(context, jdtoolOpts);
@@ -133,10 +135,12 @@
if (etable.xclasses) {
// If -Xclasses is set, the args should be a list of class names
for (String arg: javaNames) {
- if (!isValidPackageName(arg)) // checks
- toolEnv.error("main.illegal_class_name", arg);
+ if (!isValidPackageName(arg)) { // checks
+ String text = messager.getText("main.illegal_class_name", arg);
+ throw new ToolException(CMDERR, text);
+ }
}
- if (messager.nerrors() != 0) {
+ if (messager.hasErrors()) {
return null;
}
etable.setClassArgList(javaNames);
@@ -157,19 +161,23 @@
for (String arg: javaNames) {
if (fm != null && arg.endsWith(".java") && new File(arg).exists()) {
if (new File(arg).getName().equals("module-info.java")) {
- toolEnv.warning("main.file_ignored", arg);
+ messager.printWarningUsingKey("main.file_ignored", arg);
} else {
parse(fm.getJavaFileObjects(arg), classTrees, true);
}
} else if (isValidPackageName(arg)) {
packageNames.add(arg);
} else if (arg.endsWith(".java")) {
- if (fm == null)
- throw new IllegalArgumentException();
- else
- toolEnv.error("main.file_not_found", arg);
+ if (fm == null) {
+ String text = messager.getText("main.assertion.error", "fm == null");
+ throw new ToolException(ABNORMAL, text);
+ } else {
+ String text = messager.getText("main.file_not_found", arg);
+ throw new ToolException(ERROR, text);
+ }
} else {
- toolEnv.error("main.illegal_package_name", arg);
+ String text = messager.getText("main.illegal_package_name", arg);
+ throw new ToolException(CMDERR, text);
}
}
@@ -185,7 +193,7 @@
parse(etable.getFilesToParse(), packageTrees, false);
modules.enter(packageTrees.toList(), null);
- if (messager.nerrors() != 0) {
+ if (messager.hasErrors()) {
return null;
}
@@ -197,10 +205,19 @@
enterDone = true;
etable.analyze();
} catch (CompletionFailure cf) {
- toolEnv.printError(cf.getMessage());
- } catch (Abort ex) {}
+ throw new ToolException(ABNORMAL, cf.getMessage(), cf);
+ } catch (Abort abort) {
+ if (messager.hasErrors()) {
+ // presumably a message has been emitted, keep silent
+ throw new ToolException(ABNORMAL, "", abort);
+ } else {
+ String text = messager.getText("main.internal.error");
+ Throwable t = abort.getCause() == null ? abort : abort.getCause();
+ throw new ToolException(ABNORMAL, text, t);
+ }
+ }
- if (messager.nerrors() != 0)
+ if (messager.hasErrors())
return null;
toolEnv.docEnv = new DocEnvImpl(toolEnv, etable);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Main.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Main.java Mon Oct 10 06:47:47 2016 -0700
@@ -60,7 +60,7 @@
*/
public static int execute(String... args) {
Start jdoc = new Start();
- return jdoc.begin(args);
+ return jdoc.begin(args).exitCode;
}
/**
@@ -72,7 +72,7 @@
*/
public static int execute(String[] args, PrintWriter writer) {
Start jdoc = new Start(writer, writer);
- return jdoc.begin(args);
+ return jdoc.begin(args).exitCode;
}
/**
@@ -85,6 +85,36 @@
*/
public static int execute(String[] args, PrintWriter outWriter, PrintWriter errWriter) {
Start jdoc = new Start(outWriter, errWriter);
- return jdoc.begin(args);
+ return jdoc.begin(args).exitCode;
+ }
+
+ public static enum Result {
+ /** completed with no errors */
+ OK(0),
+ /** Completed with reported errors */
+ ERROR(1),
+ /** Bad command-line arguments */
+ CMDERR(2),
+ /** System error or resource exhaustion */
+ SYSERR(3),
+ /** Terminated abnormally */
+ ABNORMAL(4);
+
+ private static final long serialVersionUID = 1L;
+
+ Result(int exitCode) {
+ this.exitCode = exitCode;
+ }
+
+ public boolean isOK() {
+ return (exitCode == 0);
+ }
+
+ public final int exitCode;
+
+ @Override
+ public String toString() {
+ return name() + '(' + exitCode + ')';
+ }
}
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Messager.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Messager.java Mon Oct 10 06:47:47 2016 -0700
@@ -48,10 +48,8 @@
/**
* Utility for integrating with javadoc tools and for localization.
- * Handle Resources. Access to error and warning counts.
- * Message formatting.
- * <br>
- * Also provides implementation for DocErrorReporter.
+ * Handle resources, access to error and warning counts and
+ * message formatting.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
@@ -139,10 +137,6 @@
}
}
- public static class ExitJavadoc extends Error {
- private static final long serialVersionUID = 0;
- }
-
final String programName;
private Locale locale;
@@ -240,7 +234,7 @@
report(DiagnosticType.ERROR, prefix, msg);
return;
}
- incrementErrorCount(prefix, msg);
+ printError(prefix, msg);
}
public void printError(Element e, String msg) {
@@ -249,10 +243,15 @@
report(DiagnosticType.ERROR, prefix, msg);
return;
}
- incrementErrorCount(prefix, msg);
+ printError(prefix, msg);
}
- private void incrementErrorCount(String prefix, String msg) {
+ public void printErrorUsingKey(String key, Object... args) {
+ printError((Element)null, getText(key, args));
+ }
+
+ // print the error and increment count
+ private void printError(String prefix, String msg) {
if (nerrors < MaxErrors) {
PrintWriter errWriter = getWriter(WriterKind.ERROR);
printRawLines(errWriter, prefix + ": " + getText("javadoc.error") + " - " + msg);
@@ -272,13 +271,21 @@
printWarning((DocTreePath)null, msg);
}
+ public void printWarningUsingKey(String key, Object... args) {
+ printWarning((Element)null, getText(key, args));
+ }
+
+ public void printWarning(Element e, String key, Object... args) {
+ printWarning(getText(key, args));
+ }
+
public void printWarning(DocTreePath path, String msg) {
String prefix = getDiagSource(path);
if (diagListener != null) {
report(DiagnosticType.WARNING, prefix, msg);
return;
}
- incrementWarningCount(prefix, msg);
+ printWarning(prefix, msg);
}
public void printWarning(Element e, String msg) {
@@ -287,10 +294,11 @@
report(DiagnosticType.WARNING, prefix, msg);
return;
}
- incrementWarningCount(prefix, msg);
+ printWarning(prefix, msg);
}
- private void incrementWarningCount(String prefix, String msg) {
+ // print the warning and increment count
+ private void printWarning(String prefix, String msg) {
if (nwarnings < MaxWarnings) {
PrintWriter warnWriter = getWriter(WriterKind.WARNING);
printRawLines(warnWriter, prefix + ": " + getText("javadoc.warning") + " - " + msg);
@@ -342,50 +350,6 @@
}
/**
- * Print error message, increment error count.
- *
- * @param key selects message from resource
- */
- public void error(Element e, String key, Object... args) {
- printError(e, getText(key, args));
- }
-
- /**
- * Print error message, increment error count.
- *
- * @param key selects message from resource
- */
- public void error(DocTreePath path, String key, Object... args) {
- printError(path, getText(key, args));
- }
-
- public void error(String key, Object... args) {
- printError((Element)null, getText(key, args));
- }
-
- public void warning(String key, Object... args) {
- printWarning((Element)null, getText(key, args));
- }
-
- /**
- * Print warning message, increment warning count.
- *
- * @param key selects message from resource
- */
- public void warning(Element e, String key, Object... args) {
- printWarning(e, getText(key, args));
- }
-
- /**
- * Print warning message, increment warning count.
- *
- * @param key selects message from resource
- */
- public void warning(DocTreePath path, String key, Object... args) {
- printWarning(path, getText(key, args));
- }
-
- /**
* Print a message.
*
* @param key selects message from resource
@@ -395,21 +359,23 @@
}
/**
- * Return total number of errors, including those recorded
- * in the compilation log.
+ * Returns true if errors have been recorded.
*/
- public int nerrors() { return nerrors; }
+ public boolean hasErrors() {
+ return nerrors != 0;
+ }
/**
- * Return total number of warnings, including those recorded
- * in the compilation log.
+ * Returns true if warnings have been recorded.
*/
- public int nwarnings() { return nwarnings; }
+ public boolean hasWarnings() {
+ return nwarnings != 0;
+ }
/**
* Print exit message.
*/
- public void exitNotice() {
+ public void printErrorWarningCounts() {
if (nerrors > 0) {
notice((nerrors > 1) ? "main.errors" : "main.error",
"" + nerrors);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/OptionException.java Mon Oct 10 06:47:47 2016 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.javadoc.internal.tool;
+
+import jdk.javadoc.internal.tool.Main.Result;
+
+/**
+ * Provides a general mechanism for the javadoc tool to indicate an option
+ * decoding issue.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+
+class OptionException extends Exception {
+
+ private static final long serialVersionUID = 0;
+
+ public final Result result;
+ public final String message;
+ public final Runnable m;
+
+ /**
+ * Constructs an object with a result, runnable and a message
+ * to be printed out by the catcher. The runnable can be invoked
+ * by the catcher to display the usage text.
+ * @param result the exit code
+ * @param method the method to invoke
+ * @param message the detailed message
+ */
+ public OptionException(Result result, Runnable method, String message) {
+ this.result = result;
+ this.m = method;
+ this.message = message;
+ if (result == null || result.isOK() || method == null || message == null) {
+ throw new AssertionError("result == null || result.isOK() || " +
+ "method == null || message == null");
+ }
+ }
+
+ /**
+ * Constructs an object with a result and a runnable.
+ * The runnable can be invoked by the catcher to display the usage text.
+ * @param result the exit code
+ * @param method the method to invoke
+ */
+ public OptionException(Result result, Runnable method) {
+ this.result = result;
+ this.m = method;
+ this.message = null;
+ if (result == null || method == null) {
+ throw new AssertionError("result == null || method == null");
+ }
+ }
+}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java Mon Oct 10 06:47:47 2016 -0700
@@ -26,7 +26,6 @@
package jdk.javadoc.internal.tool;
import java.io.File;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Path;
@@ -65,11 +64,12 @@
import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.Doclet.Option;
import jdk.javadoc.doclet.DocletEnvironment;
-import jdk.javadoc.internal.doclets.toolkit.Resources;
+import jdk.javadoc.internal.tool.Main.Result;
import static javax.tools.DocumentationTool.Location.*;
import static com.sun.tools.javac.main.Option.*;
+import static jdk.javadoc.internal.tool.Main.Result.*;
/**
* Main program of Javadoc.
@@ -170,41 +170,28 @@
*/
@Override
void usage() {
- usage(true);
- }
-
- void usage(boolean exit) {
- usage("main.usage", "-help", "main.usage.foot");
-
- if (exit)
- throw new Messager.ExitJavadoc();
+ usage("main.usage", OptionKind.STANDARD, "main.usage.foot");
}
@Override
void Xusage() {
- Xusage(true);
+ usage("main.Xusage", OptionKind.EXTENDED, "main.Xusage.foot");
}
- void Xusage(boolean exit) {
- usage("main.Xusage", "-X", "main.Xusage.foot");
-
- if (exit)
- throw new Messager.ExitJavadoc();
- }
-
- private void usage(String header, String option, String footer) {
- messager.notice(header);
- showToolOptions(option.equals("-X") ? OptionKind.EXTENDED : OptionKind.STANDARD);
+ private void usage(String headerKey, OptionKind kind, String footerKey) {
+ messager.notice(headerKey);
+ showToolOptions(kind);
// let doclet print usage information
if (docletClass != null) {
String name = doclet.getName();
messager.notice("main.doclet.usage.header", name);
- showDocletOptions(option.equals("-X") ? Option.Kind.EXTENDED : Option.Kind.STANDARD);
+ showDocletOptions(kind == OptionKind.EXTENDED
+ ? Option.Kind.EXTENDED
+ : Option.Kind.STANDARD);
}
-
- if (footer != null)
- messager.notice(footer);
+ if (footerKey != null)
+ messager.notice(footerKey);
}
void showToolOptions(OptionKind kind) {
@@ -326,25 +313,23 @@
* of class loader creation, needed to detect the doclet/taglet class variants.
*/
@SuppressWarnings("deprecation")
- int begin(String... argv) {
+ Result begin(String... argv) {
// Preprocess @file arguments
try {
argv = CommandLine.parse(argv);
- } catch (FileNotFoundException e) {
- messager.error("main.cant.read", e.getMessage());
- throw new Messager.ExitJavadoc();
} catch (IOException e) {
- e.printStackTrace(System.err);
- throw new Messager.ExitJavadoc();
+ error("main.cant.read", e.getMessage());
+ return ERROR;
}
if (argv.length > 0 && "-Xold".equals(argv[0])) {
- messager.warning("main.legacy_api");
+ warn("main.legacy_api");
String[] nargv = Arrays.copyOfRange(argv, 1, argv.length);
- return com.sun.tools.javadoc.Main.execute(nargv);
+ return com.sun.tools.javadoc.Main.execute(nargv) == 0
+ ? OK
+ : ERROR;
}
- boolean ok = begin(Arrays.asList(argv), Collections.<JavaFileObject> emptySet());
- return ok ? 0 : 1;
+ return begin(Arrays.asList(argv), Collections.<JavaFileObject> emptySet());
}
// Called by 199 API.
@@ -356,11 +341,11 @@
for (String opt: options)
opts.add(opt);
- return begin(opts, fileObjects);
+ return begin(opts, fileObjects).isOK();
}
@SuppressWarnings("deprecation")
- private boolean begin(List<String> options, Iterable<? extends JavaFileObject> fileObjects) {
+ private Result begin(List<String> options, Iterable<? extends JavaFileObject> fileObjects) {
fileManager = context.get(JavaFileManager.class);
if (fileManager == null) {
JavacFileManager.preRegister(context);
@@ -369,8 +354,28 @@
((BaseFileManager) fileManager).autoClose = true;
}
}
+
// locale, doclet and maybe taglet, needs to be determined first
- docletClass = preProcess(fileManager, options);
+ try {
+ docletClass = preprocess(fileManager, options);
+ } catch (ToolException te) {
+ if (!te.result.isOK()) {
+ if (te.message != null) {
+ messager.printError(te.message);
+ }
+ Throwable t = te.getCause();
+ dumpStack(t == null ? te : t);
+ }
+ return te.result;
+ } catch (OptionException oe) {
+ if (oe.message != null) {
+ messager.printError(oe.message);
+ }
+ oe.m.run();
+ Throwable t = oe.getCause();
+ dumpStack(t == null ? oe : t);
+ return oe.result;
+ }
if (jdk.javadoc.doclet.Doclet.class.isAssignableFrom(docletClass)) {
// no need to dispatch to old, safe to init now
initMessager();
@@ -379,43 +384,62 @@
Object o = docletClass.getConstructor().newInstance();
doclet = (Doclet) o;
} catch (ReflectiveOperationException exc) {
- exc.printStackTrace();
- if (!apiMode) {
- error("main.could_not_instantiate_class", docletClass);
- throw new Messager.ExitJavadoc();
+ if (apiMode) {
+ throw new ClientCodeException(exc);
}
- throw new ClientCodeException(exc);
+ error("main.could_not_instantiate_class", docletClass);
+ return ERROR;
}
} else {
- if (this.apiMode) {
+ if (apiMode) {
com.sun.tools.javadoc.main.Start ostart
= new com.sun.tools.javadoc.main.Start(context);
- return ostart.begin(docletClass, options, fileObjects);
+ return ostart.begin(docletClass, options, fileObjects)
+ ? OK
+ : ERROR;
}
warn("main.legacy_api");
String[] array = options.toArray(new String[options.size()]);
- return com.sun.tools.javadoc.Main.execute(array) == 0;
+ return com.sun.tools.javadoc.Main.execute(array) == 0
+ ? OK
+ : ERROR;
}
- boolean failed = false;
+ Result result = OK;
try {
- failed = !parseAndExecute(options, fileObjects);
- } catch (Messager.ExitJavadoc exc) {
- // ignore, we just exit this way
+ result = parseAndExecute(options, fileObjects)
+ ? OK
+ : ERROR;
+ } catch (OptionException toe) {
+ if (toe.message != null)
+ messager.printError(toe.message);
+
+ toe.m.run();
+ Throwable t = toe.getCause();
+ dumpStack(t == null ? toe : t);
+ return toe.result;
+ } catch (ToolException exc) {
+ if (exc.message != null) {
+ messager.printError(exc.message);
+ }
+ Throwable t = exc.getCause();
+ if (result == ABNORMAL) {
+ reportInternalError(t == null ? exc : t);
+ } else {
+ dumpStack(t == null ? exc : t);
+ }
+ return exc.result;
} catch (OutOfMemoryError ee) {
- messager.error("main.out.of.memory");
- failed = true;
+ error("main.out.of.memory");
+ result = SYSERR;
+ dumpStack(ee);
} catch (ClientCodeException e) {
// simply rethrow these exceptions, to be caught and handled by JavadocTaskImpl
throw e;
- } catch (Error ee) {
- ee.printStackTrace(System.err);
- messager.error("main.fatal.error");
- failed = true;
- } catch (Exception ee) {
- ee.printStackTrace(System.err);
- messager.error("main.fatal.exception");
- failed = true;
+ } catch (Error | Exception ee) {
+ error("main.fatal.error", ee);
+ reportInternalError(ee);
+ result = ABNORMAL;
} finally {
if (fileManager != null
&& fileManager instanceof BaseFileManager
@@ -424,17 +448,34 @@
fileManager.close();
} catch (IOException ignore) {}
}
- boolean haveErrorWarnings = messager.nerrors() > 0 ||
- (rejectWarnings && messager.nwarnings() > 0);
- if (failed && !haveErrorWarnings) {
+ boolean haveErrorWarnings = messager.hasErrors()
+ || (rejectWarnings && messager.hasWarnings());
+ if (!result.isOK() && !haveErrorWarnings) {
// the doclet failed, but nothing reported, flag it!.
- messager.error("main.unknown.error");
+ error("main.unknown.error");
}
- failed |= haveErrorWarnings;
- messager.exitNotice();
+ if (haveErrorWarnings && result.isOK()) {
+ result = ERROR;
+ }
+ messager.printErrorWarningCounts();
messager.flush();
}
- return !failed;
+ return result;
+ }
+
+ private void reportInternalError(Throwable t) {
+ messager.printErrorUsingKey("doclet.internal.report.bug");
+ dumpStack(true, t);
+ }
+
+ private void dumpStack(Throwable t) {
+ dumpStack(false, t);
+ }
+
+ private void dumpStack(boolean enabled, Throwable t) {
+ if (t != null && (enabled || dumpOnError)) {
+ t.printStackTrace(System.err);
+ }
}
/**
@@ -442,7 +483,7 @@
*/
@SuppressWarnings("unchecked")
private boolean parseAndExecute(List<String> argList,
- Iterable<? extends JavaFileObject> fileObjects) throws IOException {
+ Iterable<? extends JavaFileObject> fileObjects) throws ToolException, OptionException {
long tm = System.currentTimeMillis();
List<String> javaNames = new ArrayList<>();
@@ -463,17 +504,21 @@
if (platformString != null) {
if (compOpts.isSet("-source")) {
- usageError("main.release.bootclasspath.conflict", "-source");
+ String text = messager.getText("main.release.bootclasspath.conflict", "-source");
+ throw new ToolException(CMDERR, text);
}
if (fileManagerOpts.containsKey(BOOT_CLASS_PATH)) {
- usageError("main.release.bootclasspath.conflict", BOOT_CLASS_PATH.getPrimaryName());
+ String text = messager.getText("main.release.bootclasspath.conflict",
+ BOOT_CLASS_PATH.getPrimaryName());
+ throw new ToolException(CMDERR, text);
}
PlatformDescription platformDescription =
PlatformUtils.lookupPlatformDescription(platformString);
if (platformDescription == null) {
- usageError("main.unsupported.release.version", platformString);
+ String text = messager.getText("main.unsupported.release.version", platformString);
+ throw new IllegalArgumentException(text);
}
compOpts.put(SOURCE, platformDescription.getSourceVersion());
@@ -485,10 +530,15 @@
if (platformCP != null) {
if (fileManager instanceof StandardJavaFileManager) {
StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager;
-
- sfm.setLocationFromPaths(StandardLocation.PLATFORM_CLASS_PATH, platformCP);
+ try {
+ sfm.setLocationFromPaths(StandardLocation.PLATFORM_CLASS_PATH, platformCP);
+ } catch (IOException ioe) {
+ throw new ToolException(SYSERR, ioe.getMessage(), ioe);
+ }
} else {
- usageError("main.release.not.standard.file.manager", platformString);
+ String text = messager.getText("main.release.not.standard.file.manager",
+ platformString);
+ throw new ToolException(ABNORMAL, text);
}
}
}
@@ -502,7 +552,8 @@
s -> Collections.EMPTY_LIST);
if (subpkgs.isEmpty()) {
if (javaNames.isEmpty() && isEmpty(fileObjects)) {
- usageError("main.No_modules_packages_or_classes_specified");
+ String text = messager.getText("main.No_modules_packages_or_classes_specified");
+ throw new ToolException(CMDERR, text);
}
}
}
@@ -535,7 +586,8 @@
}
Set<Doclet.Option> docletOptions = null;
- int handleDocletOptions(int idx, List<String> args, boolean isToolOption) {
+ int handleDocletOptions(int idx, List<String> args, boolean isToolOption)
+ throws OptionException {
if (docletOptions == null) {
docletOptions = doclet.getSupportedOptions();
}
@@ -549,24 +601,25 @@
argBase = arg;
argVal = null;
}
-
+ String text = null;
for (Doclet.Option opt : docletOptions) {
if (opt.matches(argBase)) {
if (argVal != null) {
switch (opt.getArgumentCount()) {
case 0:
- usageError("main.unnecessary_arg_provided", argBase);
- break;
+ text = messager.getText("main.unnecessary_arg_provided", argBase);
+ throw new OptionException(ERROR, this::usage, text);
case 1:
opt.process(arg, Arrays.asList(argVal).listIterator());
break;
default:
- usageError("main.only_one_argument_with_equals", argBase);
- break;
+ text = messager.getText("main.only_one_argument_with_equals", argBase);
+ throw new OptionException(ERROR, this::usage, text);
}
} else {
if (args.size() - idx -1 < opt.getArgumentCount()) {
- usageError("main.requires_argument", arg);
+ text = messager.getText("main.requires_argument", arg);
+ throw new OptionException(ERROR, this::usage, text);
}
opt.process(arg, args.listIterator(idx + 1));
idx += opt.getArgumentCount();
@@ -575,12 +628,15 @@
}
}
// check if arg is accepted by the tool before emitting error
- if (!isToolOption)
- usageError("main.invalid_flag", arg);
+ if (!isToolOption) {
+ text = messager.getText("main.invalid_flag", arg);
+ throw new OptionException(ERROR, this::usage, text);
+ }
return idx;
}
- private Class<?> preProcess(JavaFileManager jfm, List<String> argv) {
+ private Class<?> preprocess(JavaFileManager jfm,
+ List<String> argv) throws ToolException, OptionException {
// doclet specifying arguments
String userDocletPath = null;
String userDocletName = null;
@@ -593,19 +649,31 @@
// Step 1: loop through the args, set locale early on, if found.
for (int i = 0 ; i < argv.size() ; i++) {
String arg = argv.get(i);
- if (arg.equals(ToolOption.LOCALE.primaryName)) {
+ if (arg.equals(ToolOption.DUMPONERROR.primaryName)) {
+ dumpOnError = true;
+ } else if (arg.equals(ToolOption.LOCALE.primaryName)) {
checkOneArg(argv, i++);
String lname = argv.get(i);
locale = getLocale(lname);
} else if (arg.equals(ToolOption.DOCLET.primaryName)) {
checkOneArg(argv, i++);
if (userDocletName != null) {
- usageError("main.more_than_one_doclet_specified_0_and_1",
+ if (apiMode) {
+ throw new IllegalArgumentException("More than one doclet specified (" +
+ userDocletName + " and " + argv.get(i) + ").");
+ }
+ String text = messager.getText("main.more_than_one_doclet_specified_0_and_1",
userDocletName, argv.get(i));
+ throw new ToolException(CMDERR, text);
}
if (docletName != null) {
- usageError("main.more_than_one_doclet_specified_0_and_1",
+ if (apiMode) {
+ throw new IllegalArgumentException("More than one doclet specified (" +
+ docletName + " and " + argv.get(i) + ").");
+ }
+ String text = messager.getText("main.more_than_one_doclet_specified_0_and_1",
docletName, argv.get(i));
+ throw new ToolException(CMDERR, text);
}
userDocletName = argv.get(i);
} else if (arg.equals(ToolOption.DOCLETPATH.primaryName)) {
@@ -644,23 +712,37 @@
try {
((StandardJavaFileManager)fileManager).setLocation(DOCLET_PATH, paths);
} catch (IOException ioe) {
- error("main.doclet_could_not_set_location", paths);
- throw new Messager.ExitJavadoc();
+ if (apiMode) {
+ throw new IllegalArgumentException("Could not set location for " +
+ userDocletPath, ioe);
+ }
+ String text = messager.getText("main.doclet_could_not_set_location",
+ userDocletPath);
+ throw new ToolException(CMDERR, text, ioe);
}
}
cl = fileManager.getClassLoader(DOCLET_PATH);
if (cl == null) {
// despite doclet specified on cmdline no classloader found!
- error("main.doclet_no_classloader_found", userDocletName);
- throw new Messager.ExitJavadoc();
+ if (apiMode) {
+ throw new IllegalArgumentException("Could not obtain classloader to load "
+ + userDocletPath);
+ }
+ String text = messager.getText("main.doclet_no_classloader_found",
+ userDocletName);
+ throw new ToolException(CMDERR, text);
}
}
try {
Class<?> klass = cl.loadClass(userDocletName);
return klass;
} catch (ClassNotFoundException cnfe) {
- error("main.doclet_class_not_found", userDocletName);
- throw new Messager.ExitJavadoc();
+ if (apiMode) {
+ throw new IllegalArgumentException("Cannot find doclet class " + userDocletName,
+ cnfe);
+ }
+ String text = messager.getText("main.doclet_class_not_found", userDocletName);
+ throw new ToolException(CMDERR, text, cnfe);
}
}
@@ -669,8 +751,11 @@
try {
return Class.forName(docletName, true, getClass().getClassLoader());
} catch (ClassNotFoundException cnfe) {
- error("main.doclet_class_not_found", userDocletName);
- throw new Messager.ExitJavadoc();
+ if (apiMode) {
+ throw new IllegalArgumentException("Cannot find doclet class " + userDocletName);
+ }
+ String text = messager.getText("main.doclet_class_not_found", userDocletName);
+ throw new ToolException(CMDERR, text, cnfe);
}
}
@@ -690,20 +775,20 @@
* nature to take its own course.
*/
@SuppressWarnings("deprecation")
- private boolean hasOldTaglet(List<String> tagletNames, List<File> tagletPaths) {
+ private boolean hasOldTaglet(List<String> tagletNames, List<File> tagletPaths) throws ToolException {
if (!fileManager.hasLocation(TAGLET_PATH)) {
try {
((StandardJavaFileManager) fileManager).setLocation(TAGLET_PATH, tagletPaths);
} catch (IOException ioe) {
- error("main.doclet_could_not_set_location", tagletPaths);
- throw new Messager.ExitJavadoc();
+ String text = messager.getText("main.doclet_could_not_set_location", tagletPaths);
+ throw new ToolException(CMDERR, text, ioe);
}
}
ClassLoader cl = fileManager.getClassLoader(TAGLET_PATH);
if (cl == null) {
// no classloader found!
- error("main.doclet_no_classloader_found", tagletNames.get(0));
- throw new Messager.ExitJavadoc();
+ String text = messager.getText("main.doclet_no_classloader_found", tagletNames.get(0));
+ throw new ToolException(CMDERR, text);
}
for (String tagletName : tagletNames) {
try {
@@ -712,14 +797,15 @@
return true;
}
} catch (ClassNotFoundException cnfe) {
- error("main.doclet_class_not_found", tagletName);
- throw new Messager.ExitJavadoc();
+ String text = messager.getText("main.doclet_class_not_found", tagletName);
+ throw new ToolException(CMDERR, text, cnfe);
}
}
return false;
}
- private void parseArgs(List<String> args, List<String> javaNames) {
+ private void parseArgs(List<String> args, List<String> javaNames) throws ToolException,
+ OptionException {
for (int i = 0 ; i < args.size() ; i++) {
String arg = args.get(i);
ToolOption o = ToolOption.get(arg);
@@ -727,7 +813,6 @@
// handle a doclet argument that may be needed however
// don't increment the index, and allow the tool to consume args
handleDocletOptions(i, args, true);
-
if (o.hasArg) {
if (arg.startsWith("--") && arg.contains("=")) {
o.process(this, arg.substring(arg.indexOf('=') + 1));
@@ -763,24 +848,19 @@
* Check the one arg option.
* Error and exit if one argument is not provided.
*/
- private void checkOneArg(List<String> args, int index) {
+ private void checkOneArg(List<String> args, int index) throws OptionException {
if ((index + 1) >= args.size() || args.get(index + 1).startsWith("-d")) {
- usageError("main.requires_argument", args.get(index));
+ String text = messager.getText("main.requires_argument", args.get(index));
+ throw new OptionException(CMDERR, this::usage, text);
}
}
- @Override
- void usageError(String key, Object... args) {
- error(key, args);
- usage(true);
- }
-
void error(String key, Object... args) {
- messager.error(key, args);
+ messager.printErrorUsingKey(key, args);
}
void warn(String key, Object... args) {
- messager.warning(key, args);
+ messager.printWarningUsingKey(key, args);
}
/**
@@ -788,7 +868,7 @@
* else return null and if locale option is not used
* then return default locale.
*/
- private Locale getLocale(String localeName) {
+ private Locale getLocale(String localeName) throws ToolException {
Locale userlocale = null;
if (localeName == null || localeName.isEmpty()) {
return Locale.getDefault();
@@ -804,8 +884,8 @@
if (seconduscore > 0) {
if (seconduscore != firstuscore + 3
|| localeName.length() <= seconduscore + 1) {
- usageError("main.malformed_locale_name", localeName);
- return null;
+ String text = messager.getText("main.malformed_locale_name", localeName);
+ throw new ToolException(CMDERR, text);
}
country = localeName.substring(firstuscore + 1,
seconduscore);
@@ -813,19 +893,19 @@
} else if (localeName.length() == firstuscore + 3) {
country = localeName.substring(firstuscore + 1);
} else {
- usageError("main.malformed_locale_name", localeName);
- return null;
+ String text = messager.getText("main.malformed_locale_name", localeName);
+ throw new ToolException(CMDERR, text);
}
} else if (firstuscore == -1 && localeName.length() == 2) {
language = localeName;
} else {
- usageError("main.malformed_locale_name", localeName);
- return null;
+ String text = messager.getText("main.malformed_locale_name", localeName);
+ throw new ToolException(CMDERR, text);
}
userlocale = searchLocale(language, country, variant);
if (userlocale == null) {
- usageError("main.illegal_locale_name", localeName);
- return null;
+ String text = messager.getText("main.illegal_locale_name", localeName);
+ throw new ToolException(CMDERR, text);
} else {
return userlocale;
}
@@ -861,4 +941,9 @@
}
};
}
+
+ @Override
+ String getLocalizedMessage(String msg, Object... args) {
+ return messager.getText(msg, args);
+ }
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java Mon Oct 10 06:47:47 2016 -0700
@@ -87,7 +87,7 @@
return instance;
}
- private final Messager messager;
+ final Messager messager;
/** Predefined symbols known to the compiler. */
public final Symtab syms;
@@ -204,182 +204,8 @@
return path != null;
}
- //---------------- print forwarders ----------------//
-
- // ERRORS
/**
- * Print error message, increment error count.
- *
- * @param msg message to print.
- */
- public void printError(String msg) {
- messager.printError(msg);
- }
-
-// /**
-// * Print error message, increment error count.
-// *
-// * @param key selects message from resource
-// */
-// public void error(Element element, String key) {
-// if (element == null)
-// messager.error(key);
-// else
-// messager.error(element, key);
-// }
-//
-// public void error(String prefix, String key) {
-// printError(prefix + ":" + messager.getText(key));
-// }
-//
-// /**
-// * Print error message, increment error count.
-// *
-// * @param path the path to the source
-// * @param key selects message from resource
-// */
-// public void error(DocTreePath path, String key) {
-// messager.error(path, key);
-// }
-//
-// /**
-// * Print error message, increment error count.
-// *
-// * @param path the path to the source
-// * @param msg message to print.
-// */
-// public void printError(DocTreePath path, String msg) {
-// messager.printError(path, msg);
-// }
-//
-// /**
-// * Print error message, increment error count.
-// * @param e the target element
-// * @param msg message to print.
-// */
-// public void printError(Element e, String msg) {
-// messager.printError(e, msg);
-// }
-
- /**
- * Print error message, increment error count.
- * @param key selects message from resource
- * @param args replacement arguments
- */
- public void error(String key, String... args) {
- error(null, key, args);
- }
-
- /**
- * Print error message, increment error count.
- *
- * @param element the source element
- * @param key selects message from resource
- * @param args replacement arguments
- */
- public void error(Element element, String key, String... args) {
- if (element == null)
- messager.error(key, (Object[]) args);
- else
- messager.error(element, key, (Object[]) args);
- }
-
- // WARNINGS
-
-// /**
-// * Print warning message, increment warning count.
-// *
-// * @param msg message to print.
-// */
-// public void printWarning(String msg) {
-// messager.printWarning(msg);
-// }
-//
-// public void warning(String key) {
-// warning((Element)null, key);
-// }
-
- public void warning(String key, String... args) {
- warning((Element)null, key, args);
- }
-
-// /**
-// * Print warning message, increment warning count.
-// *
-// * @param element the source element
-// * @param key selects message from resource
-// */
-// public void warning(Element element, String key) {
-// if (element == null)
-// messager.warning(key);
-// else
-// messager.warning(element, key);
-// }
-//
-// /**
-// * Print warning message, increment warning count.
-// *
-// * @param path the path to the source
-// * @param msg message to print.
-// */
-// public void printWarning(DocTreePath path, String msg) {
-// messager.printWarning(path, msg);
-// }
-//
-// /**
-// * Print warning message, increment warning count.
-// *
-// * @param e the source element
-// * @param msg message to print.
-// */
-// public void printWarning(Element e, String msg) {
-// messager.printWarning(e, msg);
-// }
-
- /**
- * Print warning message, increment warning count.
- *
- * @param e the source element
- * @param key selects message from resource
- * @param args the replace arguments
- */
- public void warning(Element e, String key, String... args) {
- if (e == null)
- messager.warning(key, (Object[]) args);
- else
- messager.warning(e, key, (Object[]) args);
- }
-
-// Note: no longer required
-// /**
-// * Print a message.
-// *
-// * @param msg message to print.
-// */
-// public void printNotice(String msg) {
-// if (quiet) {
-// return;
-// }
-// messager.printNotice(msg);
-// }
-
-// Note: no longer required
-// /**
-// * Print a message.
-// *
-// * @param e the source element
-// * @param msg message to print.
-// */
-// public void printNotice(Element e, String msg) {
-// if (quiet) {
-// return;
-// }
-// messager.printNotice(e, msg);
-// }
-
- // NOTICES
- /**
- * Print a message.
+ * Print a notice, iff <em>quiet</em> is not specified.
*
* @param key selects message from resource
*/
@@ -390,22 +216,8 @@
messager.notice(key);
}
-// Note: not used anymore
-// /**
-// * Print a message.
-// *
-// * @param path the path to the source
-// * @param msg message to print.
-// */
-// public void printNotice(DocTreePath path, String msg) {
-// if (quiet) {
-// return;
-// }
-// messager.printNotice(path, msg);
-// }
-
/**
- * Print a message.
+ * Print a notice, iff <em>quiet</em> is not specified.
*
* @param key selects message from resource
* @param a1 first argument
@@ -417,48 +229,6 @@
messager.notice(key, a1);
}
-// Note: not used anymore
-// /**
-// * Print a message.
-// *
-// * @param key selects message from resource
-// * @param a1 first argument
-// * @param a2 second argument
-// */
-// public void notice(String key, String a1, String a2) {
-// if (quiet) {
-// return;
-// }
-// messager.notice(key, a1, a2);
-// }
-//
-
-// Note: not used anymore
-// /**
-// * Print a message.
-// *
-// * @param key selects message from resource
-// * @param a1 first argument
-// * @param a2 second argument
-// * @param a3 third argument
-// */
-// public void notice(String key, String a1, String a2, String a3) {
-// if (quiet) {
-// return;
-// }
-// messager.notice(key, a1, a2, a3);
-// }
-
- /**
- * Exit, reporting errors and warnings.
- */
- public void exit() {
- // Messager should be replaced by a more general
- // compilation environment. This can probably
- // subsume DocEnv as well.
- throw new Messager.ExitJavadoc();
- }
-
TreePath getTreePath(JCCompilationUnit tree) {
TreePath p = treePaths.get(tree);
if (p == null)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolException.java Mon Oct 10 06:47:47 2016 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.javadoc.internal.tool;
+
+import jdk.javadoc.internal.tool.Main.Result;
+
+/**
+ * Provides a mechanism for the javadoc tool to terminate execution.
+ * This class is constructed with a result and an error message,
+ * that can be printed out before termination, a cause can also
+ * be wrapped to supply extended information about the exception.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+
+class ToolException extends Exception {
+
+ private static final long serialVersionUID = 0;
+
+ final String message;
+
+ final Result result;
+
+ /**
+ * Constructs an object containing a result and a message to be
+ * printed out by the catcher.
+ * @param result the exit code
+ * @param message the detailed message
+ */
+ ToolException(Result result, String message) {
+ this.message = message;
+ this.result = result;
+ if (result == null || result.isOK() || message == null) {
+ throw new AssertionError("result == null || result.isOK() || message == null");
+ }
+ }
+
+ /**
+ * Constructs an object containing a result, a messages and an underlying cause.
+ * @param result the exit code
+ * @param message the detailed message
+ * @param cause the underlying cause
+ */
+ ToolException(Result result, String message, Throwable cause) {
+ super(cause);
+ this.message = message;
+ this.result = result;
+ if (result == null || message == null || cause == null || result.isOK()) {
+ throw new AssertionError("result == null || message == null"
+ + " || cause == null || result.isOK()");
+ }
+ }
+}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java Mon Oct 10 06:47:47 2016 -0700
@@ -40,6 +40,7 @@
import com.sun.tools.javac.util.Options;
import static com.sun.tools.javac.main.Option.OptionKind.*;
+import static jdk.javadoc.internal.tool.Main.Result.*;
/**
* javadoc tool options.
@@ -226,63 +227,63 @@
PACKAGE("-package", STANDARD) {
@Override
- public void process(Helper helper) {
+ public void process(Helper helper) throws OptionException {
helper.setSimpleFilter("package");
}
},
PRIVATE("-private", STANDARD) {
@Override
- public void process(Helper helper) {
+ public void process(Helper helper) throws OptionException {
helper.setSimpleFilter("private");
}
},
PROTECTED("-protected", STANDARD) {
@Override
- public void process(Helper helper) {
+ public void process(Helper helper) throws OptionException {
helper.setSimpleFilter("protected");
}
},
PUBLIC("-public", STANDARD) {
@Override
- public void process(Helper helper) {
+ public void process(Helper helper) throws OptionException {
helper.setSimpleFilter("public");
}
},
SHOW_MEMBERS("--show-members", STANDARD, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws OptionException {
helper.setFilter(this, arg);
}
},
SHOW_TYPES("--show-types", STANDARD, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws OptionException {
helper.setFilter(this, arg);
}
},
SHOW_PACKAGES("--show-packages", STANDARD, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws OptionException {
helper.setShowPackageAccess(SHOW_PACKAGES, arg);
}
},
SHOW_MODULE_CONTENTS("--show-module-contents", STANDARD, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws OptionException {
helper.setShowModuleContents(SHOW_MODULE_CONTENTS, arg);
}
},
EXPAND_REQUIRES("--expand-requires", STANDARD, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws OptionException {
helper.setExpandRequires(EXPAND_REQUIRES, arg);
}
},
@@ -342,19 +343,26 @@
}
},
+ DUMPONERROR("--dump-on-error", HIDDEN) {
+ @Override
+ public void process(Helper helper) {
+ helper.dumpOnError = true;
+ }
+ },
+
// ----- help options -----
HELP("--help -help", STANDARD) {
@Override
- public void process(Helper helper) {
- helper.usage();
+ public void process(Helper helper) throws OptionException {
+ throw new OptionException(OK, helper::usage);
}
},
X("-X", STANDARD) {
@Override
- public void process(Helper helper) {
- helper.Xusage();
+ public void process(Helper helper) throws OptionException {
+ throw new OptionException(OK, helper::Xusage);
}
},
@@ -395,9 +403,9 @@
this.hasSuffix = lastChar == ':' || lastChar == '=';
}
- void process(Helper helper, String arg) { }
+ void process(Helper helper, String arg) throws OptionException { }
- void process(Helper helper) { }
+ void process(Helper helper) throws OptionException { }
List<String> getNames() {
return names;
@@ -451,6 +459,9 @@
/** Javadoc tool options */
final Map<ToolOption, Object> jdtoolOpts = new EnumMap<>(ToolOption.class);
+ /** dump stack traces for debugging etc.*/
+ boolean dumpOnError = false;
+
/** Set by -breakiterator. */
boolean breakiterator = false;
@@ -470,7 +481,8 @@
abstract void usage();
abstract void Xusage();
- abstract void usageError(String msg, Object... args);
+ abstract String getLocalizedMessage(String msg, Object... args);
+
abstract OptionHelper getOptionHelper();
@SuppressWarnings("unchecked")
@@ -480,7 +492,7 @@
jdtoolOpts.put(opt, list);
}
- void setExpandRequires(ToolOption opt, String arg) {
+ void setExpandRequires(ToolOption opt, String arg) throws OptionException {
switch (arg) {
case "public":
jdtoolOpts.put(opt, AccessKind.PUBLIC);
@@ -489,11 +501,12 @@
jdtoolOpts.put(opt, AccessKind.PRIVATE);
break;
default:
- usageError("main.illegal_option_value", arg);
+ String text = getLocalizedMessage("main.illegal_option_value", arg);
+ throw new IllegalOptionValue(this::usage, text);
}
}
- void setShowModuleContents(ToolOption opt, String arg) {
+ void setShowModuleContents(ToolOption opt, String arg) throws OptionException {
switch (arg) {
case "api":
jdtoolOpts.put(opt, AccessKind.PUBLIC);
@@ -502,11 +515,12 @@
jdtoolOpts.put(opt, AccessKind.PRIVATE);
break;
default:
- usageError("main.illegal_option_value", arg);
+ String text = getLocalizedMessage("main.illegal_option_value", arg);
+ throw new IllegalOptionValue(this::usage, text);
}
}
- void setShowPackageAccess(ToolOption opt, String arg) {
+ void setShowPackageAccess(ToolOption opt, String arg) throws OptionException {
switch (arg) {
case "exported":
jdtoolOpts.put(opt, AccessKind.PUBLIC);
@@ -515,16 +529,17 @@
jdtoolOpts.put(opt, AccessKind.PRIVATE);
break;
default:
- usageError("main.illegal_option_value", arg);
+ String text = getLocalizedMessage("main.illegal_option_value", arg);
+ throw new IllegalOptionValue(this::usage, text);
}
}
- void setFilter(ToolOption opt, String arg) {
+ void setFilter(ToolOption opt, String arg) throws OptionException {
jdtoolOpts.put(opt, getAccessValue(arg));
}
- void setSimpleFilter(String arg) {
+ void setSimpleFilter(String arg) throws OptionException {
handleSimpleOption(arg);
}
@@ -532,7 +547,7 @@
fileManagerOpts.put(opt, arg);
}
- void handleSimpleOption(String arg) {
+ void handleSimpleOption(String arg) throws OptionException {
populateSimpleAccessMap(getAccessValue(arg));
}
@@ -541,7 +556,7 @@
* -private, so on, in addition to the new ones such as
* --show-types:public and so on.
*/
- private AccessKind getAccessValue(String arg) {
+ private AccessKind getAccessValue(String arg) throws OptionException {
int colon = arg.indexOf(':');
String value = (colon > 0)
? arg.substring(colon + 1)
@@ -556,8 +571,8 @@
case "private":
return AccessKind.PRIVATE;
default:
- usageError("main.illegal_option_value", value);
- return null;
+ String text = getLocalizedMessage("main.illegal_option_value", value);
+ throw new IllegalOptionValue(this::usage, text);
}
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties Mon Oct 10 06:47:47 2016 -0700
@@ -265,13 +265,13 @@
main.Building_tree=Constructing Javadoc information...
main.no_source_files_for_package=No source files for package {0}
main.package_not_found=Package {0} not found
-main.fatal.error=fatal error
-main.fatal.exception=fatal exception
+main.fatal.error=fatal error encountered: {0}
main.out.of.memory=java.lang.OutOfMemoryError: Please increase memory.\n\
For example, on the JDK Classic or HotSpot VMs, add the option -J-Xmx\n\
such as -J-Xmx32m.
main.done_in=[done in {0} ms]
main.more_than_one_doclet_specified_0_and_1=More than one doclet specified ({0} and {1}).
+main.doclet_could_not_get_location=Could not get location for {0}
main.doclet_could_not_set_location=Could not set location for {0}
main.doclet_no_classloader_found=Could not obtain classloader to load {0}
main.could_not_instantiate_class=Could not instantiate class {0}
@@ -286,7 +286,15 @@
main.release.bootclasspath.conflict=option {0} cannot be used together with -release
main.unsupported.release.version=release version {0} not supported
main.release.not.standard.file.manager=-release option specified, but the provided JavaFileManager is not a StandardJavaFileManager.
+main.file.manager.list=FileManager error listing files: "{0}"
+main.assertion.error=assertion failed: "{0}}"
main.unknown.error=an unknown error has occurred
+main.internal.error=an internal error has occurred
+main.unexpected.exception=an unexpected exception was caught: {0}
+doclet.internal.report.bug=\
+Please file a bug against the javadoc tool via the Java bug reporting page\n\
+(http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com)\n\
+for duplicates. Include error messages and the following diagnostic in your report. Thank you.
main.legacy_api=The old Doclet and Taglet APIs in the packages\n\
com.sun.javadoc, com.sun.tools.doclets and their implementations\n\
are planned to be removed in a future JDK release. These\n\
--- a/langtools/test/jdk/javadoc/doclet/T6735320/T6735320.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/T6735320/T6735320.java Mon Oct 10 06:47:47 2016 -0700
@@ -42,7 +42,7 @@
void test() {
javadoc("-d", "out",
testSrc("SerialFieldTest.java"));
- checkExit(Exit.FAILED);
+ checkExit(Exit.ERROR);
checkOutput(Output.STDERR, false,
"OutOfBoundsException");
}
--- a/langtools/test/jdk/javadoc/doclet/dupThrowsTags/TestDupThrowsTags.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/dupThrowsTags/TestDupThrowsTags.java Mon Oct 10 06:47:47 2016 -0700
@@ -42,7 +42,7 @@
void test() {
javadoc("-d", "out",
testSrc("TestDupThrowsTags.java"));
- checkExit(Exit.FAILED);
+ checkExit(Exit.ERROR);
checkOutput("TestDupThrowsTags.html", true,
"Test 1 passes",
--- a/langtools/test/jdk/javadoc/doclet/lib/JavadocTester.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/lib/JavadocTester.java Mon Oct 10 06:47:47 2016 -0700
@@ -327,15 +327,27 @@
outputDirectoryCheck = c;
}
+ /**
+ * The exit codes returned by the javadoc tool.
+ * @see jdk.javadoc.internal.tool.Main.Result
+ */
public enum Exit {
- OK(0),
- FAILED(1);
+ OK(0), // Javadoc completed with no errors.
+ ERROR(1), // Completed but reported errors.
+ CMDERR(2), // Bad command-line arguments
+ SYSERR(3), // System error or resource exhaustion.
+ ABNORMAL(4); // Javadoc terminated abnormally
Exit(int code) {
this.code = code;
}
final int code;
+
+ @Override
+ public String toString() {
+ return name() + '(' + code + ')';
+ }
}
/**
@@ -349,7 +361,7 @@
if (exitCode == expected.code) {
passed("return code " + exitCode);
} else {
- failed("return code " + exitCode +"; expected " + expected.code + " (" + expected + ")");
+ failed("return code " + exitCode +"; expected " + expected);
}
}
--- a/langtools/test/jdk/javadoc/doclet/testBadSourceFile/TestBadSourceFile.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testBadSourceFile/TestBadSourceFile.java Mon Oct 10 06:47:47 2016 -0700
@@ -50,6 +50,6 @@
javadoc("-Xdoclint:none",
"-d", "out",
testSrc("C2.java"));
- checkExit(Exit.FAILED);
+ checkExit(Exit.ERROR);
}
}
--- a/langtools/test/jdk/javadoc/doclet/testConstantValuesPage/TestConstantValuesPage.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testConstantValuesPage/TestConstantValuesPage.java Mon Oct 10 06:47:47 2016 -0700
@@ -45,7 +45,7 @@
javadoc("-d", "out",
"-sourcepath", testSrc,
"foo");
- checkExit(Exit.FAILED);
+ checkExit(Exit.CMDERR);
checkOutput(Output.OUT, false,
"constant-values.html...");
--- a/langtools/test/jdk/javadoc/doclet/testDocErrorReporter/TestDocErrorReporter.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testDocErrorReporter/TestDocErrorReporter.java Mon Oct 10 06:47:47 2016 -0700
@@ -52,6 +52,8 @@
"-encoding", "xyz",
testSrc("TestDocErrorReporter.java"));
- checkExit(Exit.FAILED);
+ checkExit(Exit.ERROR);
+
+ checkOutput(Output.OUT, true, "error: unsupported encoding: xyz");
}
}
--- a/langtools/test/jdk/javadoc/doclet/testHelpOption/TestHelpOption.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testHelpOption/TestHelpOption.java Mon Oct 10 06:47:47 2016 -0700
@@ -111,7 +111,7 @@
"-helpfile", testSrc("test-help.html"),
"-helpfile", testSrc("test-help.html"),
testSrc("Sample.java"));
- checkExit(Exit.FAILED);
+ checkExit(Exit.ERROR);
}
@Test
@@ -121,7 +121,7 @@
"-helpfile", testSrc("test-help.html"),
"-nohelp",
testSrc("Sample.java"));
- checkExit(Exit.FAILED);
+ checkExit(Exit.ERROR);
}
private void checkOutput(boolean withOption) {
--- a/langtools/test/jdk/javadoc/doclet/testIOException/TestIOException.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testIOException/TestIOException.java Mon Oct 10 06:47:47 2016 -0700
@@ -57,7 +57,7 @@
try {
javadoc("-d", outDir.toString(),
new File(testSrc, "TestIOException.java").getPath());
- checkExit(Exit.FAILED);
+ checkExit(Exit.ERROR);
checkOutput(Output.OUT, true,
"Destination directory not writable: " + outDir);
} finally {
@@ -85,7 +85,7 @@
javadoc("-d", outDir.toString(),
new File(testSrc, "TestIOException.java").getPath());
- checkExit(Exit.FAILED);
+ checkExit(Exit.ERROR);
checkOutput(Output.OUT, true,
"Error writing file: " + index);
} finally {
@@ -123,7 +123,7 @@
setOutputDirectoryCheck(DirectoryCheck.NONE);
javadoc("-d", outDir.toString(),
src_p_C.getPath());
- checkExit(Exit.FAILED);
+ checkExit(Exit.ERROR);
checkOutput(Output.OUT, true,
"Error writing file: " + new File(pkgOutDir, "C.html"));
} finally {
@@ -167,7 +167,7 @@
javadoc("-d", outDir.toString(),
"-sourcepath", srcDir.getPath(),
"p");
- checkExit(Exit.FAILED);
+ checkExit(Exit.ERROR);
checkOutput(Output.OUT, true,
"Error writing file: " + new File(docFilesOutDir, "info.txt"));
} finally {
--- a/langtools/test/jdk/javadoc/doclet/testPackageHtml/TestPackageHtml.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testPackageHtml/TestPackageHtml.java Mon Oct 10 06:47:47 2016 -0700
@@ -42,7 +42,7 @@
javadoc("-d", "out-pkg-html",
"-sourcepath", testSrc,
"pkg1");
- checkExit(Exit.FAILED);
+ checkExit(Exit.ERROR);
checkOutput(Output.OUT, true, "package.html:10: error: bad use of '>'");
}
}
--- a/langtools/test/jdk/javadoc/doclet/testParamTaglet/TestParamTaglet.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testParamTaglet/TestParamTaglet.java Mon Oct 10 06:47:47 2016 -0700
@@ -46,7 +46,7 @@
javadoc("-d", "out",
"-sourcepath", testSrc,
"pkg");
- checkExit(Exit.FAILED);
+ checkExit(Exit.ERROR);
checkOutput("pkg/C.html", true,
//Regular param tags.
--- a/langtools/test/jdk/javadoc/doclet/testSearch/TestSearch.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testSearch/TestSearch.java Mon Oct 10 06:47:47 2016 -0700
@@ -73,7 +73,7 @@
void test2a() {
javadoc("-d", "out-2a", "-Xdoclint:all", "-sourcepath", testSrc,
"-use", "pkg", "pkg1", "pkg2", "pkg3");
- checkExit(Exit.FAILED);
+ checkExit(Exit.ERROR);
checkDocLintErrors();
checkSearchOutput(true);
checkSingleIndex(true);
--- a/langtools/test/jdk/javadoc/doclet/testSerializedFormDeprecationInfo/TestSerializedFormDeprecationInfo.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testSerializedFormDeprecationInfo/TestSerializedFormDeprecationInfo.java Mon Oct 10 06:47:47 2016 -0700
@@ -44,7 +44,7 @@
javadoc("-d", "out-default",
"-sourcepath", testSrc,
"pkg1");
- checkExit(Exit.FAILED); // TODO: should be OK
+ checkExit(Exit.OK);
checkCommentDeprecated(true);
checkNoComment(false);
@@ -56,7 +56,7 @@
"-nocomment",
"-sourcepath", testSrc,
"pkg1");
- checkExit(Exit.FAILED); // TODO: should be OK
+ checkExit(Exit.OK);
checkNoComment(true);
checkCommentDeprecated(false);
@@ -68,7 +68,7 @@
"-nodeprecated",
"-sourcepath", testSrc,
"pkg1");
- checkExit(Exit.FAILED); // TODO: should be OK
+ checkExit(Exit.OK);
checkNoDeprecated(true);
checkNoCommentNoDeprecated(false);
@@ -81,7 +81,7 @@
"-nodeprecated",
"-sourcepath", testSrc,
"pkg1");
- checkExit(Exit.FAILED); // TODO: should be OK
+ checkExit(Exit.OK);
checkNoCommentNoDeprecated(true);
checkNoDeprecated(false);
}
@@ -93,7 +93,7 @@
"<dl>\n"
+ "<dt><span class=\"throwsLabel\">Throws:</span></dt>\n"
+ "<dd><code>"
- + "java.io.IOException</code></dd>\n"
+ + "java.io.IOException</code> - on error</dd>\n"
+ "<dt><span class=\"seeLabel\">See Also:</span>"
+ "</dt>\n"
+ "<dd><a href=\"pkg1/C1.html#setUndecorated-boolean-\">"
@@ -121,7 +121,7 @@
+ "<div class=\"block\">Reads the object stream.</div>\n"
+ "<dl>\n"
+ "<dt><span class=\"throwsLabel\">Throws:</span></dt>\n"
- + "<dd><code>java.io.IOException</code></dd>\n"
+ + "<dd><code>java.io.IOException</code> - on error</dd>\n"
+ "</dl>",
"<span class=\"deprecatedLabel\">Deprecated.</span>"
+ " </div>\n"
--- a/langtools/test/jdk/javadoc/doclet/testSerializedFormDeprecationInfo/pkg1/C1.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testSerializedFormDeprecationInfo/pkg1/C1.java Mon Oct 10 06:47:47 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. 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
@@ -75,7 +75,6 @@
* @param test boolean value
* @exception IllegalArgumentException if the <code>owner</code>'s
* <code>GraphicsConfiguration</code> is not from a screen device
- * @exception HeadlessException
*/
public C1(String title, boolean test) {
@@ -98,6 +97,7 @@
}
/**
+ * @throws java.io.IOException on error
* @see #setUndecorated(boolean)
*/
public void readObject() throws IOException {
--- a/langtools/test/jdk/javadoc/doclet/testSerializedFormDeprecationInfo/pkg1/C2.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testSerializedFormDeprecationInfo/pkg1/C2.java Mon Oct 10 06:47:47 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. 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
@@ -74,7 +74,7 @@
* Reads the object stream.
*
* @param s ObjectInputStream
- * @throws IOException
+ * @throws IOException on error
* @deprecated As of JDK version 1.5, replaced by
* {@link C1#setUndecorated(boolean) setUndecorated(boolean)}.
*/
--- a/langtools/test/jdk/javadoc/doclet/testSinceTag/TestSinceTag.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testSinceTag/TestSinceTag.java Mon Oct 10 06:47:47 2016 -0700
@@ -45,7 +45,7 @@
javadoc("-d", "out-since",
"-sourcepath", testSrc,
"pkg1");
- checkExit(Exit.FAILED); // TODO: investigate
+ checkExit(Exit.OK);
checkSince(true);
}
@@ -56,7 +56,7 @@
"-sourcepath", testSrc,
"-nosince",
"pkg1");
- checkExit(Exit.FAILED); // TODO: investigate
+ checkExit(Exit.OK);
checkSince(false);
}
--- a/langtools/test/jdk/javadoc/doclet/testSinceTag/pkg1/C1.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testSinceTag/pkg1/C1.java Mon Oct 10 06:47:47 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. 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
@@ -72,7 +72,6 @@
* @param test boolean value
* @exception IllegalArgumentException if the <code>owner</code>'s
* <code>GraphicsConfiguration</code> is not from a screen device
- * @exception HeadlessException
*/
public C1(String title, boolean test) {
}
@@ -93,6 +92,7 @@
}
/**
+ * @throws java.io.IOException on error
* @see #setUndecorated(boolean)
*/
public void readObject() throws IOException {
--- a/langtools/test/jdk/javadoc/doclet/testSupplementary/TestSupplementary.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testSupplementary/TestSupplementary.java Mon Oct 10 06:47:47 2016 -0700
@@ -52,7 +52,7 @@
javadoc("-locale", "en_US",
"-d", "out",
testSrc("C.java"));
- checkExit(Exit.FAILED);
+ checkExit(Exit.ERROR);
checkOutput(Output.OUT, true,
"C.java:36: error: unexpected text",
--- a/langtools/test/jdk/javadoc/doclet/testThrowsTag/TestThrowsTag.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testThrowsTag/TestThrowsTag.java Mon Oct 10 06:47:47 2016 -0700
@@ -45,7 +45,7 @@
javadoc("-d", "out",
"-sourcepath", testSrc,
"pkg");
- checkExit(Exit.FAILED); // TODO: investigate why failed
+ checkExit(Exit.OK);
checkOutput("pkg/C.html", true,
"<dd><code><a href=\"../pkg/T1.html\" title=\"class in pkg\">T1</a></code> - the first throws tag.</dd>\n" +
--- a/langtools/test/jdk/javadoc/doclet/testThrowsTag/pkg/T1.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testThrowsTag/pkg/T1.java Mon Oct 10 06:47:47 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2016, Oracle and/or its affiliates. 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
@@ -23,4 +23,4 @@
package pkg;
-public class T1 extends Exception {}
+public class T1 extends RuntimeException {}
--- a/langtools/test/jdk/javadoc/doclet/testThrowsTag/pkg/T2.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testThrowsTag/pkg/T2.java Mon Oct 10 06:47:47 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2016, Oracle and/or its affiliates. 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
@@ -23,4 +23,4 @@
package pkg;
-public class T2 extends Exception {}
+public class T2 extends RuntimeException {}
--- a/langtools/test/jdk/javadoc/doclet/testThrowsTag/pkg/T3.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testThrowsTag/pkg/T3.java Mon Oct 10 06:47:47 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2016, Oracle and/or its affiliates. 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
@@ -23,4 +23,4 @@
package pkg;
-public class T3 extends Exception {}
+public class T3 extends RuntimeException {}
--- a/langtools/test/jdk/javadoc/doclet/testThrowsTag/pkg/T4.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testThrowsTag/pkg/T4.java Mon Oct 10 06:47:47 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2016, Oracle and/or its affiliates. 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
@@ -23,4 +23,4 @@
package pkg;
-public class T4 extends Exception {}
+public class T4 extends RuntimeException {}
--- a/langtools/test/jdk/javadoc/doclet/testValueTag/TestValueTag.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testValueTag/TestValueTag.java Mon Oct 10 06:47:47 2016 -0700
@@ -46,7 +46,7 @@
"-sourcepath", testSrc,
"-tag", "todo",
"pkg1", "pkg2");
- checkExit(Exit.FAILED);
+ checkExit(Exit.ERROR);
checkOutput("pkg1/Class1.html", true,
// Base case: using @value on a constant.
--- a/langtools/test/jdk/javadoc/doclet/testWarnings/TestWarnings.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/doclet/testWarnings/TestWarnings.java Mon Oct 10 06:47:47 2016 -0700
@@ -47,7 +47,7 @@
javadoc("-d", "out-default",
"-sourcepath", testSrc,
"pkg");
- checkExit(Exit.FAILED);
+ checkExit(Exit.ERROR);
checkOutput(Output.OUT, true,
"X.java:23: error: self-closing element not allowed");
@@ -75,7 +75,7 @@
"-private",
"-sourcepath", testSrc,
"pkg");
- checkExit(Exit.FAILED);
+ checkExit(Exit.ERROR);
checkOutput("pkg/X.html", true,
"<a href=\"../pkg/X.html#m--\"><code>m()</code></a><br/>",
--- a/langtools/test/jdk/javadoc/tool/ReleaseOption.java Tue Oct 11 00:28:49 2016 +0900
+++ b/langtools/test/jdk/javadoc/tool/ReleaseOption.java Mon Oct 10 06:47:47 2016 -0700
@@ -28,7 +28,11 @@
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
+
import jdk.javadoc.internal.tool.Main;
+import jdk.javadoc.internal.tool.Main.Result;
+
+import static jdk.javadoc.internal.tool.Main.Result.*;
/**
* @test
@@ -43,13 +47,13 @@
}
void run() {
- doRunTest(0, out -> out.contains("compiler.err.doesnt.exist: java.util.stream"), "--release", "7");
- doRunTest(0, out -> !out.contains("compiler.err.doesnt.exist: java.util.stream"), "--release", "8");
- doRunTest(1, out -> true, "--release", "7", "-source", "7");
- doRunTest(1, out -> true, "--release", "7", "-bootclasspath", "any");
+ doRunTest(OK, out -> out.contains("compiler.err.doesnt.exist: java.util.stream"), "--release", "7");
+ doRunTest(OK, out -> !out.contains("compiler.err.doesnt.exist: java.util.stream"), "--release", "8");
+ doRunTest(CMDERR, out -> true, "--release", "7", "-source", "7");
+ doRunTest(CMDERR, out -> true, "--release", "7", "-bootclasspath", "any");
}
- void doRunTest(int expectedResult, Predicate<String> validate, String... args) {
+ void doRunTest(Result expectedResult, Predicate<String> validate, String... args) {
System.err.println("running with args: " + Arrays.asList(args));
List<String> options = new ArrayList<>();
options.addAll(Arrays.asList(args));
@@ -60,7 +64,7 @@
int actualResult = Main.execute(options.toArray(new String[0]), pw);
System.err.println("actual result=" + actualResult);
System.err.println("actual output=" + out.toString());
- if (actualResult != expectedResult)
+ if (actualResult != expectedResult.exitCode)
throw new Error("Exit code not as expected");
if (!validate.test(out.toString())) {
throw new Error("Output not as expected");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/exceptionHandling/TestExceptionHandling.java Mon Oct 10 06:47:47 2016 -0700
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8151102
+ * @summary verify that option --dump-on-error functions correctly
+ * @library /tools/lib
+ * @modules
+ * jdk.javadoc/jdk.javadoc.internal.api
+ * jdk.javadoc/jdk.javadoc.internal.tool
+ * jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.main
+ * @build toolbox.ToolBox toolbox.TestRunner
+ * @run main TestExceptionHandling
+ */
+
+import java.io.File;
+import java.io.PrintStream;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+
+import toolbox.*;
+
+/**
+ * This class tests if stack traces printed when
+ * --dump-on-error. The standard doclet is used,
+ * to test the doclet as well as the tool.
+ */
+public class TestExceptionHandling extends TestRunner {
+
+ final ToolBox tb;
+ final File testSrcFile;
+ final PrintStream ostream;
+ final JavadocTask cmdTask;
+ final JavadocTask apiTask;
+
+ public static void main(String... args) throws Exception {
+ TestExceptionHandling tester = new TestExceptionHandling();
+ tester.runTests();
+ }
+
+ TestExceptionHandling() {
+ super(System.err);
+ tb = new ToolBox();
+ ostream = System.err;
+ testSrcFile = new File(System.getProperty("test.src"), "TestExceptionHandling.java");
+ cmdTask = new JavadocTask(tb, Task.Mode.CMDLINE);
+ apiTask = new JavadocTask(tb, Task.Mode.API);
+ }
+
+ @Test
+ public void testDocletTrace() throws Exception {
+ Path out = Paths.get("out");
+ // create a file with the same name as the output
+ out.toFile().createNewFile();
+ cmdTask.outdir(out);
+ cmdTask.options("--dump-on-error");
+ cmdTask.files(testSrcFile.getAbsolutePath());
+ Task.Result tr = cmdTask.run(Task.Expect.FAIL);
+
+ String errString = "Destination directory is not a directory: " + out.toString();
+ // check the regular message
+ assertPresent("javadoc: error - " + errString, tr.getOutputLines(Task.OutputKind.DIRECT));
+ // check that first line of the stack trace is present
+ assertPresent("jdk.javadoc.internal.doclets.toolkit.util.SimpleDocletException: " +
+ errString, tr.getOutputLines(Task.OutputKind.STDERR));
+
+ }
+
+ @Test
+ public void testToolTrace() throws Exception {
+ Path out = Paths.get("out.dir");
+ cmdTask.options("--dump-on-error", "-doclet", "NonExistentDoclet");
+ cmdTask.outdir(out);
+ cmdTask.files(testSrcFile.getAbsolutePath());
+ Task.Result tr = cmdTask.run(Task.Expect.FAIL);
+
+ // check the regular message
+ assertPresent("javadoc: error - Cannot find doclet class NonExistentDoclet",
+ tr.getOutputLines(Task.OutputKind.DIRECT));
+
+ // check that first line of the stack trace is present
+ assertPresent("java.lang.ClassNotFoundException: NonExistentDoclet",
+ tr.getOutputLines(Task.OutputKind.STDERR));
+
+ }
+
+ @Test
+ public void testApiModeMissingDoclet() throws Exception {
+ apiTask.options("-doclet", "MissingDoclet");
+ try {
+ Task.Result result = apiTask.run(Task.Expect.FAIL);
+ } catch (IllegalArgumentException iae) {
+ // ok got the right exception
+ return;
+ }
+ throw new Exception("expected exception/error not found");
+ }
+
+ @Test
+ public void testApiModeMultipleDoclets() throws Exception {
+ apiTask.options("-doclet", "MissingDoclet",
+ "-doclet", "SomeDoclet");
+ try {
+ Task.Result result = apiTask.run(Task.Expect.FAIL);
+ } catch (IllegalArgumentException iae) {
+ // ok got the right exception
+ return;
+ }
+ throw new Exception("expected exception/error not found");
+ }
+
+ void assertPresent(String regex, List<String> output) throws Exception {
+ List<String> gresult = tb.grep(regex, output);
+ if (gresult.isEmpty()) {
+ ostream.println("Expected: " + regex);
+ ostream.println("Output: ");
+ output.forEach(s -> {
+ ostream.println(s);
+ });
+ throw new Exception("Test fails expected output not found: " + regex);
+ }
+ }
+}