Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7116676

RichDiagnosticFormatter throws NPE when formatMessage is called directly

    XMLWordPrintable

Details

    • b94
    • unknown
    • generic
    • Verified

    Description

      When using RDF.formatMessage, a NPE is thrown from

      com.sun.tools.javac.util.RichDiagnosticFormatter$RichPrinter.className(RichDiagnosticFormatter.java:377)

      The cause is that nameSimplifier is null (see testThroughFormatterFormat2).

      Test:

      /*
       * Copyright 2003-2004 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. Sun designates this
       * particular file as subject to the "Classpath" exception as provided
       * by Sun 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 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.
       */

      package global;

      import com.sun.source.util.JavacTask;
      import com.sun.tools.javac.api.ClientCodeWrapper.Trusted;
      import com.sun.tools.javac.api.DiagnosticFormatter;
      import com.sun.tools.javac.api.JavacTaskImpl;
      import com.sun.tools.javac.util.JCDiagnostic;
      import com.sun.tools.javac.util.Log;
      import java.io.IOException;
      import java.net.URI;
      import java.util.ArrayList;
      import java.util.Arrays;
      import java.util.List;
      import javax.tools.Diagnostic;
      import javax.tools.DiagnosticListener;
      import javax.tools.JavaCompiler;
      import javax.tools.JavaFileObject;
      import javax.tools.SimpleJavaFileObject;
      import javax.tools.ToolProvider;
      import junit.framework.TestCase;

      /**
       *
       * @author lahvac
       */
      public class RichDiagnosticTest extends TestCase {

          public RichDiagnosticTest(String name) {
              super(name);
          }

          static class MyFileObject extends SimpleJavaFileObject {
              private String text;
              public MyFileObject(String text) {
                  super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
                  this.text = text;
              }
              @Override
              public CharSequence getCharContent(boolean ignoreEncodingErrors) {
                  return text;
              }
          }

          public void testThroughFormatterFormat1() throws IOException {
              String code = "package test; public class Test { private void t(java.util.List<? extends String> l) { t(java.util.Collections.singleton(l)); } }";
              final String bootPath = System.getProperty("sun.boot.class.path"); //NOI18N
              final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
              assert tool != null;

              DiagnosticCollectorImpl<JavaFileObject> diagnostic = new DiagnosticCollectorImpl<JavaFileObject>();
              JavacTask ct = (JavacTask)tool.getTask(null, null, diagnostic, Arrays.asList("-bootclasspath", bootPath, "-source", "1.6", "-XDdiagsFormat=%L%m|%L%m|%L%m"), null, Arrays.asList(new MyFileObject(code)));

              ct.analyze();

              DiagnosticFormatter<JCDiagnostic> formatter = Log.instance(((JavacTaskImpl) ct).getContext()).getDiagnosticFormatter();
              StringBuilder result = new StringBuilder();

              for (Diagnostic<? extends JavaFileObject> d : diagnostic.getDiagnostics()) {
                  result.append("Diagnostic: ").append(d.getCode()).append("\n");
                  result.append(formatter.format((JCDiagnostic) d, null));
              }

              String errors = result.toString();

              assertEquals("Diagnostic: compiler.err.cant.apply.symbol.1\n" +
                           "method t in class Test cannot be applied to given types;\n" +
                           " required: List<? extends String>\n" +
                           " found: Set<List<CAP#1>>\n" +
                           " reason: actual argument Set<List<CAP#1>> cannot be converted to List<? extends String> by method invocation conversion\n" +
                           " where CAP#1 is a fresh type-variable:\n" +
                           " CAP#1 extends String from capture of ? extends String",
                           errors);
          }

          public void testThroughFormatterFormat2() throws IOException {
              String code = "package test; public class Test { private void t(java.util.List<? extends String> l) { t(java.util.Collections.singleton(l)); } }";
              final String bootPath = System.getProperty("sun.boot.class.path"); //NOI18N
              final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
              assert tool != null;

              DiagnosticCollectorImpl<JavaFileObject> diagnostic = new DiagnosticCollectorImpl<JavaFileObject>();
              JavacTask ct = (JavacTask)tool.getTask(null, null, diagnostic, Arrays.asList("-bootclasspath", bootPath, "-source", "1.6", "-XDdiagsFormat=%L%m|%L%m|%L%m"), null, Arrays.asList(new MyFileObject(code)));

              ct.analyze();

              DiagnosticFormatter<JCDiagnostic> formatter = Log.instance(((JavacTaskImpl) ct).getContext()).getDiagnosticFormatter();
              StringBuilder result = new StringBuilder();

              for (Diagnostic<? extends JavaFileObject> d : diagnostic.getDiagnostics()) {
                  result.append("Diagnostic: ").append(d.getCode()).append("\n");
                  result.append(formatter.formatMessage((JCDiagnostic) d, null));
              }

              String errors = result.toString();

              assertEquals("Diagnostic: compiler.err.cant.apply.symbol.1\n" +
                           "method t in class Test cannot be applied to given types;\n" +
                           " required: List<? extends String>\n" +
                           " found: Set<List<CAP#1>>\n" +
                           " reason: actual argument Set<List<CAP#1>> cannot be converted to List<? extends String> by method invocation conversion\n" +
                           " where CAP#1 is a fresh type-variable:\n" +
                           " CAP#1 extends String from capture of ? extends String",
                           errors);
          }

          @Trusted
          private static final class DiagnosticCollectorImpl<S> implements DiagnosticListener<S> {

              private final List<Diagnostic<? extends S>> diagnostics = new ArrayList<Diagnostic<? extends S>>();

              public void report(Diagnostic<? extends S> diagnostic) {
                  diagnostics.add(diagnostic);
              }

              public List<Diagnostic<? extends S>> getDiagnostics() {
                  return diagnostics;
              }

          }
      }

      Attachments

        Activity

          People

            mcimadamore Maurizio Cimadamore
            mcimadamore Maurizio Cimadamore
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: