United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-6963934 : JCCompilationUnit.getImports does not report all imports

Details
Type:
Bug
Submit Date:
2010-06-24
Status:
Closed
Updated Date:
2012-03-20
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
tools
OS:
linux
Sub-Component:
javac
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
6u20
Fixed Versions:

Related Reports

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux <hostname> 2.6.24-gg804011-generic #1 SMP Tue Mar 30 18:11:30 UTC 2010 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
JCCompilationUnit.getImports does not report all imports if there is an extra semicolon after one of the import statements.

getImports stops after the first non-import statement. Empty statement makes it think there would be no other import statements to follow.



$ cat A.java
import java.util.List;; // note an extra semicolon here
import java.util.ArrayList;

public class A {}

$ cat Driver.java
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.ImportTree;
import com.sun.source.util.JavacTask;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

public class Driver {
  public static void main(String[] args) throws Exception {
    if (args.length < 1) return;

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
    JavacTask task = (JavacTask) compiler.getTask(null, fileManager, null, null, null,
                                                  fileManager.getJavaFileObjects(args[0]));
    CompilationUnitTree tree = task.parse().iterator().next();
    for (ImportTree importTree : tree.getImports()) {
      System.out.println(importTree);
    }
  }
}

$ javac A.java accepts the source file as valid

$ javac -cp /java/lib/tools.jar Driver.java
$ java -cp /java/lib/tools.jar:. Driver A.java

produces only the first import statement


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
$ javac -cp /java/lib/tools.jar Driver.java
$ java -cp /java/lib/tools.jar:. Driver A.java

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
import java.util.List;
import java.util.ArrayList;
ACTUAL -
import java.util.List;

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
$ cat A.java
import java.util.List;; // note an extra semicolon here
import java.util.ArrayList;

public class A {}

$ cat Driver.java
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.ImportTree;
import com.sun.source.util.JavacTask;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

public class Driver {
  public static void main(String[] args) throws Exception {
    if (args.length < 1) return;

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
    JavacTask task = (JavacTask) compiler.getTask(null, fileManager, null, null, null,
                                                  fileManager.getJavaFileObjects(args[0]));
    CompilationUnitTree tree = task.parse().iterator().next();
    for (ImportTree importTree : tree.getImports()) {
      System.out.println(importTree);
    }
  }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
My current workaround is to cast CompilationUnitTree to JCTree.JCCompilationUnit and filter the defs myself.

The getImports could be fixed for example by adding if (tree.getTag() == SKIP) continue;

        public List<JCImport> getImports() {
            ListBuffer<JCImport> imports = new ListBuffer<JCImport>();
            for (JCTree tree : defs) {
                if (tree.getTag() == SKIP) continue;
                else if (tree.getTag() == IMPORT)
                    imports.append((JCImport)tree);
                else
                    break;
            }
            return imports.toList();
        }

                                    

Comments
EVALUATION

verified b124.
                                     
2011-01-19



Hardware and Software, Engineered to Work Together