# HG changeset patch # User jjg # Date 1248899186 25200 # Node ID f2f87f1bc5ad4e430d75ddb78a042d76a5a9b01b # Parent 89c8080abf4815820b4dc94020e50485a8795dc0 4777949: Javap Rewrite : Warn javap usage on package classes with simple name. Reviewed-by: mcimadamore diff -r 89c8080abf48 -r f2f87f1bc5ad langtools/src/share/classes/com/sun/tools/javap/JavapFileManager.java --- a/langtools/src/share/classes/com/sun/tools/javap/JavapFileManager.java Tue Jul 28 11:00:05 2009 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javap/JavapFileManager.java Wed Jul 29 13:26:26 2009 -0700 @@ -41,13 +41,13 @@ * This code and its internal interfaces are subject to change or * deletion without notice. */ -class JavapFileManager extends JavacFileManager { +public class JavapFileManager extends JavacFileManager { private JavapFileManager(Context context, Charset charset) { super(context, true, charset); setIgnoreSymbolFile(true); } - static JavapFileManager create(final DiagnosticListener dl, PrintWriter log, Options options) { + public static JavapFileManager create(final DiagnosticListener dl, PrintWriter log) { Context javac_context = new Context(); if (dl != null) diff -r 89c8080abf48 -r f2f87f1bc5ad langtools/src/share/classes/com/sun/tools/javap/JavapTask.java --- a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java Tue Jul 28 11:00:05 2009 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java Wed Jul 29 13:26:26 2009 -0700 @@ -316,17 +316,17 @@ Iterable classes) { this(out, fileManager, diagnosticListener); + this.classes = new ArrayList(); + for (String classname: classes) { + classname.getClass(); // null-check + this.classes.add(classname); + } + try { handleOptions(options, false); } catch (BadArgs e) { throw new IllegalArgumentException(e.getMessage()); } - - this.classes = new ArrayList(); - for (String classname: classes) { - classname.getClass(); // null-check - this.classes.add(classname); - } } public void setLocale(Locale locale) { @@ -372,10 +372,18 @@ final PrintWriter pw = getPrintWriterForWriter(w); return new DiagnosticListener () { public void report(Diagnostic diagnostic) { - if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { + switch (diagnostic.getKind()) { + case ERROR: pw.print(getMessage("err.prefix")); - pw.print(" "); + break; + case WARNING: + pw.print(getMessage("warn.prefix")); + break; + case NOTE: + pw.print(getMessage("note.prefix")); + break; } + pw.print(" "); pw.println(diagnostic.getMessage(null)); } }; @@ -405,7 +413,7 @@ boolean ok = run(); return ok ? EXIT_OK : EXIT_ERROR; } catch (BadArgs e) { - diagnosticListener.report(createDiagnostic(e.key, e.args)); + reportError(e.key, e.args); if (e.showUsage) { log.println(getMessage("main.usage.summary", progname)); } @@ -419,7 +427,7 @@ e_args[0] = e.getCause(); System.arraycopy(e.args, 0, e_args, 1, e.args.length); } - diagnosticListener.report(createDiagnostic("err.internal.error", e_args)); + reportError("err.internal.error", e_args); return EXIT_ABNORMAL; } finally { log.flush(); @@ -531,7 +539,7 @@ StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager; fo = sfm.getJavaFileObjects(className).iterator().next(); } else { - diagnosticListener.report(createDiagnostic("err.not.standard.file.manager", className)); + reportError("err.not.standard.file.manager", className); ok = false; continue; } @@ -547,38 +555,42 @@ } } if (fo == null) { - diagnosticListener.report(createDiagnostic("err.class.not.found", className)); + reportError("err.class.not.found", className); ok = false; continue; } } attributeFactory.setCompat(options.compat); attributeFactory.setJSR277(options.jsr277); - - write(read(fo)); - + ClassFileInfo cfInfo = read(fo); + if (!className.endsWith(".class")) { + String cfName = cfInfo.cf.getName(); + if (!cfName.replaceAll("[/$]", ".").equals(className.replaceAll("[/$]", "."))) + reportWarning("warn.unexpected.class", className, cfName.replace('/', '.')); + } + write(cfInfo); } catch (ConstantPoolException e) { - diagnosticListener.report(createDiagnostic("err.bad.constant.pool", className, e.getLocalizedMessage())); + reportError("err.bad.constant.pool", className, e.getLocalizedMessage()); ok = false; } catch (EOFException e) { - diagnosticListener.report(createDiagnostic("err.end.of.file", className)); + reportError("err.end.of.file", className); ok = false; } catch (FileNotFoundException e) { - diagnosticListener.report(createDiagnostic("err.file.not.found", e.getLocalizedMessage())); + reportError("err.file.not.found", e.getLocalizedMessage()); ok = false; } catch (IOException e) { //e.printStackTrace(); Object msg = e.getLocalizedMessage(); if (msg == null) msg = e; - diagnosticListener.report(createDiagnostic("err.ioerror", className, msg)); + reportError("err.ioerror", className, msg); ok = false; } catch (Throwable t) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); t.printStackTrace(pw); pw.close(); - diagnosticListener.report(createDiagnostic("err.crash", t.toString(), sw.toString())); + reportError("err.crash", t.toString(), sw.toString()); ok = false; } } @@ -684,7 +696,7 @@ } private JavaFileManager getDefaultFileManager(final DiagnosticListener dl, PrintWriter log) { - return JavapFileManager.create(dl, log, options); + return JavapFileManager.create(dl, log); } private JavaFileObject getClassFileObject(String className) throws IOException { @@ -738,10 +750,23 @@ } } - private Diagnostic createDiagnostic(final String key, final Object... args) { + private void reportError(String key, Object... args) { + diagnosticListener.report(createDiagnostic(Diagnostic.Kind.ERROR, key, args)); + } + + private void reportNote(String key, Object... args) { + diagnosticListener.report(createDiagnostic(Diagnostic.Kind.NOTE, key, args)); + } + + private void reportWarning(String key, Object... args) { + diagnosticListener.report(createDiagnostic(Diagnostic.Kind.WARNING, key, args)); + } + + private Diagnostic createDiagnostic( + final Diagnostic.Kind kind, final String key, final Object... args) { return new Diagnostic() { public Kind getKind() { - return Diagnostic.Kind.ERROR; + return kind; } public JavaFileObject getSource() { @@ -776,6 +801,10 @@ return JavapTask.this.getMessage(locale, key, args); } + public String toString() { + return getClass().getName() + "[key=" + key + ",args=" + Arrays.asList(args) + "]"; + } + }; } diff -r 89c8080abf48 -r f2f87f1bc5ad langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties --- a/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties Tue Jul 28 11:00:05 2009 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties Wed Jul 29 13:26:26 2009 -0700 @@ -24,6 +24,15 @@ Usage: {0} \n\ use -help for a list of possible options +warn.prefix=Warning: +warn.unexpected.class=Binary file {0} contains {1} + +note.prefix=Note: + +main.usage.summary=\ +Usage: {0} \n\ +use -help for a list of possible options + main.usage=\ Usage: {0} \n\ where possible options include: diff -r 89c8080abf48 -r f2f87f1bc5ad langtools/test/tools/javap/T4777949.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javap/T4777949.java Wed Jul 29 13:26:26 2009 -0700 @@ -0,0 +1,111 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.io.*; +import java.util.*; +import javax.tools.*; +import com.sun.tools.javap.*; + +/* + * @test + * @bug 4777949 + * @summary Warn javap usage on package with simple name + */ +public class T4777949 { + public static void main(String... args) throws Exception { + new T4777949().run(); + } + + void run() throws Exception { + File javaFile = writeTestFile(); + File classFile = compileTestFile(javaFile); + + test(".", "p.q.r.Test", false); + test("p", "q.r.Test", true); + test("p/q", "r.Test", true); + test("p/q/r", "Test", true); + test(".", "p.q.r.Test.Inner", false); + test(".", "p.q.r.Test$Inner", false); + test("p", "q.r.Test.Inner", true); + test("p", "q.r.Test$Inner", true); + + if (errors > 0) + throw new Exception(errors + " errors found"); + } + + void test(String classPath, String className, boolean expectWarnings) { + List> diags = + javap(Arrays.asList("-classpath", classPath), Arrays.asList(className)); + boolean foundWarnings = false; + for (Diagnostic d: diags) { + if (d.getKind() == Diagnostic.Kind.WARNING) + foundWarnings = true; + } + } + + + File writeTestFile() throws IOException { + File f = new File("Test.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println("package p.q.r;"); + out.println("class Test { class Inner { } }"); + out.close(); + return f; + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-d", ".", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + List> javap(List args, List classes) { + DiagnosticCollector dc = new DiagnosticCollector(); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + JavaFileManager fm = JavapFileManager.create(dc, pw); + JavapTask t = new JavapTask(pw, fm, dc, args, classes); + boolean ok = t.run(); + + List> diags = dc.getDiagnostics(); + + if (!ok) + error("javap failed unexpectedly"); + + System.err.println("args=" + args + " classes=" + classes + "\n" + + diags + "\n" + + sw); + + return diags; + } + + void error(String msg) { + System.err.println("error: " + msg); + errors++; + } + + int errors; +} +