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

CompletionFailure during traversal of Elements in annotation processor

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Cannot Reproduce
    • Icon: P3 P3
    • None
    • 7u40
    • tools
    • windows_8

      FULL PRODUCT VERSION :
      java version "1.8.0-ea"
      Java(TM) SE Runtime Environment (build 1.8.0-ea-b103)
      Java HotSpot(TM) 64-Bit Server VM (build 25.0-b45, mixed mode)

      Same behaviour in 1.7.0_25.

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.2.9200]
      (Windows 8)

      A DESCRIPTION OF THE PROBLEM :
      During annotation processing I traverse Element trees using Element.getEnclosedElements and DeclaredType.asElement(). For some Elements javac crashes with the following message:

      error: cannot access StringPrep
        class file for sun.net.idn.StringPrep not found
        Consult the following stack trace for details.
        com.sun.tools.javac.code.Symbol$CompletionFailure: class file for sun.net.idn.StringPrep not found


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Here is a source code example that reproduces the failure (3 classes, run Main).

      1. Main

      package completion_failure;
      import java.io.File;
      import java.util.ArrayList;
      import java.util.List;

      import javax.annotation.processing.Processor;
      import javax.tools.JavaCompiler;
      import javax.tools.JavaCompiler.CompilationTask;
      import javax.tools.JavaFileObject;
      import javax.tools.StandardJavaFileManager;
      import javax.tools.ToolProvider;

      public class Main
      {
      public static void main(String[] args)
        {
      List<String> options = new ArrayList<>();

      options.add("-proc:only");

      List<String> annotationProcessors = new ArrayList<>();
      annotationProcessors.add(AnnotationProcessor.class.getName());

      JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

      StandardJavaFileManager fileManager =
      compiler.getStandardFileManager(null, null, null);

      List<JavaFileObject> compilationUnits = new ArrayList<>();
      File file = new File("src/test/java/completion_failure/AnnotatedType.java");
      List<File> files = new ArrayList<>();
      files.add(file);
      compilationUnits.add(
      fileManager.getJavaFileObjectsFromFiles(files).iterator().next());

      CompilationTask compilationTask =
      compiler.getTask(
      null,
      fileManager,
      null,
      options,
      null,
      compilationUnits);

      List<Processor> processors = new ArrayList<>();
      processors.add(new AnnotationProcessor());

      compilationTask.setProcessors(processors);

      compilationTask.call();
      }
      }

      2. Annotation Processor

      package completion_failure;
      import java.util.HashSet;
      import java.util.Set;

      import javax.annotation.processing.AbstractProcessor;
      import javax.annotation.processing.RoundEnvironment;
      import javax.annotation.processing.SupportedAnnotationTypes;
      import javax.annotation.processing.SupportedSourceVersion;
      import javax.lang.model.SourceVersion;
      import javax.lang.model.element.Element;
      import javax.lang.model.element.TypeElement;
      import javax.lang.model.type.DeclaredType;
      import javax.lang.model.type.TypeMirror;


      @SupportedSourceVersion(SourceVersion.RELEASE_7)
      @SupportedAnnotationTypes("java.lang.SuppressWarnings")
      public class AnnotationProcessor extends AbstractProcessor
      {
      private Set<Element> elements = new HashSet<>();

      public Set<Element> getElements()
      {
      return elements;
      }

      private void populateElements(Element element, int depth)
      {
      if (elements.add(element))
      {
      TypeMirror mirror = element.asType();

      System.out.println(
      new String(new char[depth]).replace("\0", " ") +
      mirror.toString() + " " + element.getSimpleName());

      for (Element enclosedElement : element.getEnclosedElements())
      {
      populateElements(enclosedElement, depth + 1);
      }

      if (mirror instanceof DeclaredType)
      {
      DeclaredType declaredType = (DeclaredType) mirror;
      populateElements(declaredType.asElement(), depth + 1);
      }
      }
      }

      @Override
        public boolean process(
        Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)
        {
      System.out.println("starting processing round");

      if (false == roundEnv.processingOver())
      {
      populateElements(roundEnv.getRootElements().iterator().next(), 0);
      }

      return false;
        }
      }

      3. Annotated Element:

      package completion_failure;
      import java.net.IDN;

      public class AnnotatedType
      {
      @SuppressWarnings("unused")
        private IDN idn;
      }

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      no error
      ACTUAL -
      error


      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      error: cannot access StringPrep
        class file for sun.net.idn.StringPrep not found
        Consult the following stack trace for details.
        com.sun.tools.javac.code.Symbol$CompletionFailure: class file for sun.net.idn.StringPrep not found

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      Here is a source code example that reproduces the failure (3 classes, run Main).

      1. Main

      package completion_failure;
      import java.io.File;
      import java.util.ArrayList;
      import java.util.List;

      import javax.annotation.processing.Processor;
      import javax.tools.JavaCompiler;
      import javax.tools.JavaCompiler.CompilationTask;
      import javax.tools.JavaFileObject;
      import javax.tools.StandardJavaFileManager;
      import javax.tools.ToolProvider;

      public class Main
      {
      public static void main(String[] args)
        {
      List<String> options = new ArrayList<>();

      options.add("-proc:only");

      List<String> annotationProcessors = new ArrayList<>();
      annotationProcessors.add(AnnotationProcessor.class.getName());

      JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

      StandardJavaFileManager fileManager =
      compiler.getStandardFileManager(null, null, null);

      List<JavaFileObject> compilationUnits = new ArrayList<>();
      File file = new File("src/test/java/completion_failure/AnnotatedType.java");
      List<File> files = new ArrayList<>();
      files.add(file);
      compilationUnits.add(
      fileManager.getJavaFileObjectsFromFiles(files).iterator().next());

      CompilationTask compilationTask =
      compiler.getTask(
      null,
      fileManager,
      null,
      options,
      null,
      compilationUnits);

      List<Processor> processors = new ArrayList<>();
      processors.add(new AnnotationProcessor());

      compilationTask.setProcessors(processors);

      compilationTask.call();
      }
      }

      2. Annotation Processor

      package completion_failure;
      import java.util.HashSet;
      import java.util.Set;

      import javax.annotation.processing.AbstractProcessor;
      import javax.annotation.processing.RoundEnvironment;
      import javax.annotation.processing.SupportedAnnotationTypes;
      import javax.annotation.processing.SupportedSourceVersion;
      import javax.lang.model.SourceVersion;
      import javax.lang.model.element.Element;
      import javax.lang.model.element.TypeElement;
      import javax.lang.model.type.DeclaredType;
      import javax.lang.model.type.TypeMirror;


      @SupportedSourceVersion(SourceVersion.RELEASE_7)
      @SupportedAnnotationTypes("java.lang.SuppressWarnings")
      public class AnnotationProcessor extends AbstractProcessor
      {
      private Set<Element> elements = new HashSet<>();

      public Set<Element> getElements()
      {
      return elements;
      }

      private void populateElements(Element element, int depth)
      {
      if (elements.add(element))
      {
      TypeMirror mirror = element.asType();

      System.out.println(
      new String(new char[depth]).replace("\0", " ") +
      mirror.toString() + " " + element.getSimpleName());

      for (Element enclosedElement : element.getEnclosedElements())
      {
      populateElements(enclosedElement, depth + 1);
      }

      if (mirror instanceof DeclaredType)
      {
      DeclaredType declaredType = (DeclaredType) mirror;
      populateElements(declaredType.asElement(), depth + 1);
      }
      }
      }

      @Override
        public boolean process(
        Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)
        {
      System.out.println("starting processing round");

      if (false == roundEnv.processingOver())
      {
      populateElements(roundEnv.getRootElements().iterator().next(), 0);
      }

      return false;
        }
      }

      3. Annotated Element:

      package completion_failure;
      import java.net.IDN;

      public class AnnotatedType
      {
      @SuppressWarnings("unused")
        private IDN idn;
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      found none

            Unassigned Unassigned
            robm Robert Mckenna
            Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated:
              Resolved: