Wed, 29 Jul 2009 13:26:26 -0700
4777949: Javap Rewrite : Warn javap usage on package classes with simple name.
Reviewed-by: mcimadamore
1.1 --- a/src/share/classes/com/sun/tools/javap/JavapFileManager.java Tue Jul 28 11:00:05 2009 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javap/JavapFileManager.java Wed Jul 29 13:26:26 2009 -0700 1.3 @@ -41,13 +41,13 @@ 1.4 * This code and its internal interfaces are subject to change or 1.5 * deletion without notice.</b> 1.6 */ 1.7 -class JavapFileManager extends JavacFileManager { 1.8 +public class JavapFileManager extends JavacFileManager { 1.9 private JavapFileManager(Context context, Charset charset) { 1.10 super(context, true, charset); 1.11 setIgnoreSymbolFile(true); 1.12 } 1.13 1.14 - static JavapFileManager create(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log, Options options) { 1.15 + public static JavapFileManager create(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) { 1.16 Context javac_context = new Context(); 1.17 1.18 if (dl != null)
2.1 --- a/src/share/classes/com/sun/tools/javap/JavapTask.java Tue Jul 28 11:00:05 2009 -0700 2.2 +++ b/src/share/classes/com/sun/tools/javap/JavapTask.java Wed Jul 29 13:26:26 2009 -0700 2.3 @@ -316,17 +316,17 @@ 2.4 Iterable<String> classes) { 2.5 this(out, fileManager, diagnosticListener); 2.6 2.7 + this.classes = new ArrayList<String>(); 2.8 + for (String classname: classes) { 2.9 + classname.getClass(); // null-check 2.10 + this.classes.add(classname); 2.11 + } 2.12 + 2.13 try { 2.14 handleOptions(options, false); 2.15 } catch (BadArgs e) { 2.16 throw new IllegalArgumentException(e.getMessage()); 2.17 } 2.18 - 2.19 - this.classes = new ArrayList<String>(); 2.20 - for (String classname: classes) { 2.21 - classname.getClass(); // null-check 2.22 - this.classes.add(classname); 2.23 - } 2.24 } 2.25 2.26 public void setLocale(Locale locale) { 2.27 @@ -372,10 +372,18 @@ 2.28 final PrintWriter pw = getPrintWriterForWriter(w); 2.29 return new DiagnosticListener<JavaFileObject> () { 2.30 public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 2.31 - if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { 2.32 + switch (diagnostic.getKind()) { 2.33 + case ERROR: 2.34 pw.print(getMessage("err.prefix")); 2.35 - pw.print(" "); 2.36 + break; 2.37 + case WARNING: 2.38 + pw.print(getMessage("warn.prefix")); 2.39 + break; 2.40 + case NOTE: 2.41 + pw.print(getMessage("note.prefix")); 2.42 + break; 2.43 } 2.44 + pw.print(" "); 2.45 pw.println(diagnostic.getMessage(null)); 2.46 } 2.47 }; 2.48 @@ -405,7 +413,7 @@ 2.49 boolean ok = run(); 2.50 return ok ? EXIT_OK : EXIT_ERROR; 2.51 } catch (BadArgs e) { 2.52 - diagnosticListener.report(createDiagnostic(e.key, e.args)); 2.53 + reportError(e.key, e.args); 2.54 if (e.showUsage) { 2.55 log.println(getMessage("main.usage.summary", progname)); 2.56 } 2.57 @@ -419,7 +427,7 @@ 2.58 e_args[0] = e.getCause(); 2.59 System.arraycopy(e.args, 0, e_args, 1, e.args.length); 2.60 } 2.61 - diagnosticListener.report(createDiagnostic("err.internal.error", e_args)); 2.62 + reportError("err.internal.error", e_args); 2.63 return EXIT_ABNORMAL; 2.64 } finally { 2.65 log.flush(); 2.66 @@ -531,7 +539,7 @@ 2.67 StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager; 2.68 fo = sfm.getJavaFileObjects(className).iterator().next(); 2.69 } else { 2.70 - diagnosticListener.report(createDiagnostic("err.not.standard.file.manager", className)); 2.71 + reportError("err.not.standard.file.manager", className); 2.72 ok = false; 2.73 continue; 2.74 } 2.75 @@ -547,38 +555,42 @@ 2.76 } 2.77 } 2.78 if (fo == null) { 2.79 - diagnosticListener.report(createDiagnostic("err.class.not.found", className)); 2.80 + reportError("err.class.not.found", className); 2.81 ok = false; 2.82 continue; 2.83 } 2.84 } 2.85 attributeFactory.setCompat(options.compat); 2.86 attributeFactory.setJSR277(options.jsr277); 2.87 - 2.88 - write(read(fo)); 2.89 - 2.90 + ClassFileInfo cfInfo = read(fo); 2.91 + if (!className.endsWith(".class")) { 2.92 + String cfName = cfInfo.cf.getName(); 2.93 + if (!cfName.replaceAll("[/$]", ".").equals(className.replaceAll("[/$]", "."))) 2.94 + reportWarning("warn.unexpected.class", className, cfName.replace('/', '.')); 2.95 + } 2.96 + write(cfInfo); 2.97 } catch (ConstantPoolException e) { 2.98 - diagnosticListener.report(createDiagnostic("err.bad.constant.pool", className, e.getLocalizedMessage())); 2.99 + reportError("err.bad.constant.pool", className, e.getLocalizedMessage()); 2.100 ok = false; 2.101 } catch (EOFException e) { 2.102 - diagnosticListener.report(createDiagnostic("err.end.of.file", className)); 2.103 + reportError("err.end.of.file", className); 2.104 ok = false; 2.105 } catch (FileNotFoundException e) { 2.106 - diagnosticListener.report(createDiagnostic("err.file.not.found", e.getLocalizedMessage())); 2.107 + reportError("err.file.not.found", e.getLocalizedMessage()); 2.108 ok = false; 2.109 } catch (IOException e) { 2.110 //e.printStackTrace(); 2.111 Object msg = e.getLocalizedMessage(); 2.112 if (msg == null) 2.113 msg = e; 2.114 - diagnosticListener.report(createDiagnostic("err.ioerror", className, msg)); 2.115 + reportError("err.ioerror", className, msg); 2.116 ok = false; 2.117 } catch (Throwable t) { 2.118 StringWriter sw = new StringWriter(); 2.119 PrintWriter pw = new PrintWriter(sw); 2.120 t.printStackTrace(pw); 2.121 pw.close(); 2.122 - diagnosticListener.report(createDiagnostic("err.crash", t.toString(), sw.toString())); 2.123 + reportError("err.crash", t.toString(), sw.toString()); 2.124 ok = false; 2.125 } 2.126 } 2.127 @@ -684,7 +696,7 @@ 2.128 } 2.129 2.130 private JavaFileManager getDefaultFileManager(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) { 2.131 - return JavapFileManager.create(dl, log, options); 2.132 + return JavapFileManager.create(dl, log); 2.133 } 2.134 2.135 private JavaFileObject getClassFileObject(String className) throws IOException { 2.136 @@ -738,10 +750,23 @@ 2.137 } 2.138 } 2.139 2.140 - private Diagnostic<JavaFileObject> createDiagnostic(final String key, final Object... args) { 2.141 + private void reportError(String key, Object... args) { 2.142 + diagnosticListener.report(createDiagnostic(Diagnostic.Kind.ERROR, key, args)); 2.143 + } 2.144 + 2.145 + private void reportNote(String key, Object... args) { 2.146 + diagnosticListener.report(createDiagnostic(Diagnostic.Kind.NOTE, key, args)); 2.147 + } 2.148 + 2.149 + private void reportWarning(String key, Object... args) { 2.150 + diagnosticListener.report(createDiagnostic(Diagnostic.Kind.WARNING, key, args)); 2.151 + } 2.152 + 2.153 + private Diagnostic<JavaFileObject> createDiagnostic( 2.154 + final Diagnostic.Kind kind, final String key, final Object... args) { 2.155 return new Diagnostic<JavaFileObject>() { 2.156 public Kind getKind() { 2.157 - return Diagnostic.Kind.ERROR; 2.158 + return kind; 2.159 } 2.160 2.161 public JavaFileObject getSource() { 2.162 @@ -776,6 +801,10 @@ 2.163 return JavapTask.this.getMessage(locale, key, args); 2.164 } 2.165 2.166 + public String toString() { 2.167 + return getClass().getName() + "[key=" + key + ",args=" + Arrays.asList(args) + "]"; 2.168 + } 2.169 + 2.170 }; 2.171 2.172 }
3.1 --- a/src/share/classes/com/sun/tools/javap/resources/javap.properties Tue Jul 28 11:00:05 2009 -0700 3.2 +++ b/src/share/classes/com/sun/tools/javap/resources/javap.properties Wed Jul 29 13:26:26 2009 -0700 3.3 @@ -24,6 +24,15 @@ 3.4 Usage: {0} <options> <classes>\n\ 3.5 use -help for a list of possible options 3.6 3.7 +warn.prefix=Warning: 3.8 +warn.unexpected.class=Binary file {0} contains {1} 3.9 + 3.10 +note.prefix=Note: 3.11 + 3.12 +main.usage.summary=\ 3.13 +Usage: {0} <options> <classes>\n\ 3.14 +use -help for a list of possible options 3.15 + 3.16 main.usage=\ 3.17 Usage: {0} <options> <classes>\n\ 3.18 where possible options include:
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/tools/javap/T4777949.java Wed Jul 29 13:26:26 2009 -0700 4.3 @@ -0,0 +1,111 @@ 4.4 +/* 4.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. 4.11 + * 4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.15 + * version 2 for more details (a copy is included in the LICENSE file that 4.16 + * accompanied this code). 4.17 + * 4.18 + * You should have received a copy of the GNU General Public License version 4.19 + * 2 along with this work; if not, write to the Free Software Foundation, 4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.21 + * 4.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 4.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 4.24 + * have any questions. 4.25 + */ 4.26 + 4.27 +import java.io.*; 4.28 +import java.util.*; 4.29 +import javax.tools.*; 4.30 +import com.sun.tools.javap.*; 4.31 + 4.32 +/* 4.33 + * @test 4.34 + * @bug 4777949 4.35 + * @summary Warn javap usage on package with simple name 4.36 + */ 4.37 +public class T4777949 { 4.38 + public static void main(String... args) throws Exception { 4.39 + new T4777949().run(); 4.40 + } 4.41 + 4.42 + void run() throws Exception { 4.43 + File javaFile = writeTestFile(); 4.44 + File classFile = compileTestFile(javaFile); 4.45 + 4.46 + test(".", "p.q.r.Test", false); 4.47 + test("p", "q.r.Test", true); 4.48 + test("p/q", "r.Test", true); 4.49 + test("p/q/r", "Test", true); 4.50 + test(".", "p.q.r.Test.Inner", false); 4.51 + test(".", "p.q.r.Test$Inner", false); 4.52 + test("p", "q.r.Test.Inner", true); 4.53 + test("p", "q.r.Test$Inner", true); 4.54 + 4.55 + if (errors > 0) 4.56 + throw new Exception(errors + " errors found"); 4.57 + } 4.58 + 4.59 + void test(String classPath, String className, boolean expectWarnings) { 4.60 + List<Diagnostic<? extends JavaFileObject>> diags = 4.61 + javap(Arrays.asList("-classpath", classPath), Arrays.asList(className)); 4.62 + boolean foundWarnings = false; 4.63 + for (Diagnostic<? extends JavaFileObject> d: diags) { 4.64 + if (d.getKind() == Diagnostic.Kind.WARNING) 4.65 + foundWarnings = true; 4.66 + } 4.67 + } 4.68 + 4.69 + 4.70 + File writeTestFile() throws IOException { 4.71 + File f = new File("Test.java"); 4.72 + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); 4.73 + out.println("package p.q.r;"); 4.74 + out.println("class Test { class Inner { } }"); 4.75 + out.close(); 4.76 + return f; 4.77 + } 4.78 + 4.79 + File compileTestFile(File f) { 4.80 + int rc = com.sun.tools.javac.Main.compile(new String[] { "-d", ".", f.getPath() }); 4.81 + if (rc != 0) 4.82 + throw new Error("compilation failed. rc=" + rc); 4.83 + String path = f.getPath(); 4.84 + return new File(path.substring(0, path.length() - 5) + ".class"); 4.85 + } 4.86 + 4.87 + List<Diagnostic<? extends JavaFileObject>> javap(List<String> args, List<String> classes) { 4.88 + DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<JavaFileObject>(); 4.89 + StringWriter sw = new StringWriter(); 4.90 + PrintWriter pw = new PrintWriter(sw); 4.91 + JavaFileManager fm = JavapFileManager.create(dc, pw); 4.92 + JavapTask t = new JavapTask(pw, fm, dc, args, classes); 4.93 + boolean ok = t.run(); 4.94 + 4.95 + List<Diagnostic<? extends JavaFileObject>> diags = dc.getDiagnostics(); 4.96 + 4.97 + if (!ok) 4.98 + error("javap failed unexpectedly"); 4.99 + 4.100 + System.err.println("args=" + args + " classes=" + classes + "\n" 4.101 + + diags + "\n" 4.102 + + sw); 4.103 + 4.104 + return diags; 4.105 + } 4.106 + 4.107 + void error(String msg) { 4.108 + System.err.println("error: " + msg); 4.109 + errors++; 4.110 + } 4.111 + 4.112 + int errors; 4.113 +} 4.114 +