--- 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);
+ }
}