JDK-6410653 : REGRESSION: javac crashes if -d or -s argument is a file
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2006-04-09
  • Updated: 2010-04-02
  • Resolved: 2006-04-14
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 b81Fixed
Related Reports
Relates :  
Description
Compiler will crash with -d if the argument is not a directory.

<code>
public class Foo {
}
</code>
<output>
E:\javatrails>javac Foo.java -d Foo.java
An exception has occurred in the compiler (1.6.0-auto). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport)  af
ter checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report.  Thank you.
java.lang.IllegalArgumentException: not a directory
        at com.sun.tools.javac.util.DefaultFileManager.getDirectory(DefaultFileManager.java:926)
        at com.sun.tools.javac.util.DefaultFileManager.setLocation(DefaultFileManager.java:903)
        at com.sun.tools.javac.util.DefaultFileManager.getClassOutDir(DefaultFileManager.java:941)
        at com.sun.tools.javac.util.DefaultFileManager.getFileForOutput(DefaultFileManager.java:869)
        at com.sun.tools.javac.util.DefaultFileManager.getJavaFileForOutput(DefaultFileManager.java:842)
        at com.sun.tools.javac.jvm.ClassWriter.writeClass(ClassWriter.java:1394)
        at com.sun.tools.javac.main.JavaCompiler.genCode(JavaCompiler.java:549)
        at com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1153)
        at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:667)
        at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:637)
        at com.sun.tools.javac.main.Main.compile(Main.java:333)
        at com.sun.tools.javac.main.Main.compile(Main.java:255)
        at com.sun.tools.javac.main.Main.compile(Main.java:246)
        at com.sun.tools.javac.Main.compile(Main.java:70)
        at com.sun.tools.javac.Main.main(Main.java:55)
</output>
<java-version>
E:\javatrails>java -version
java version "1.6.0-auto"
Java(TM) SE Runtime Environment (build 1.6.0-auto-087)
Java HotSpot(TM) Client VM (build 1.6.0-beta2-b78, mixed mode)
</java-version>

The same with tiger :
<output-tiger>
/home/sa151881/javatrails/Foo.java:1: error while writing Foo: /home/sa151881/javatrails/Foo.java/Foo.class (Not a directory)
public class Foo {
       ^
</output-tiger>
<tiger-version>
java version "1.5.0-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-rc-b63)
Java HotSpot(TM) Client VM (build 1.5.0-rc-b63, mixed mode)
</tiger-version>
Same the case with -sourcepath also.
<output>
E:\MustangTestDev\tools\jsr199\ToolTest\ToolTest02>javac -sourcepath Test.java ToolTest02.java
An exception has occurred in the compiler (1.6.0-auto). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport)  af
ter checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report.  Thank you.
java.lang.NullPointerException
        at com.sun.tools.javac.util.DefaultFileManager.listAll(DefaultFileManager.java:293)
        at com.sun.tools.javac.util.DefaultFileManager.list(DefaultFileManager.java:700)
        at com.sun.tools.javac.jvm.ClassReader.fillIn(ClassReader.java:1954)
        at com.sun.tools.javac.jvm.ClassReader.complete(ClassReader.java:1703)
        at com.sun.tools.javac.code.Symbol.complete(Symbol.java:380)
        at com.sun.tools.javac.comp.Enter.visitTopLevel(Enter.java:259)
        at com.sun.tools.javac.tree.JCTree$JCCompilationUnit.accept(JCTree.java:445)
        at com.sun.tools.javac.comp.Enter.classEnter(Enter.java:223)
        at com.sun.tools.javac.comp.Enter.classEnter(Enter.java:237)
        at com.sun.tools.javac.comp.Enter.complete(Enter.java:431)
        at com.sun.tools.javac.comp.Enter.main(Enter.java:416)
        at com.sun.tools.javac.main.JavaCompiler.enterTrees(JavaCompiler.java:727)
        at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:634)
        at com.sun.tools.javac.main.Main.compile(Main.java:333)
        at com.sun.tools.javac.main.Main.compile(Main.java:255)
        at com.sun.tools.javac.main.Main.compile(Main.java:246)
        at com.sun.tools.javac.Main.compile(Main.java:70)
        at com.sun.tools.javac.Main.main(Main.java:55)

</output>

Comments
EVALUATION To fix this issue we had to change the usage message output by javac. The usage message is now: javac: not a directory: Test.java Usage: javac <options> <source files> use -help for a list of possible options Previously the compiler would output a list of options. However, with the addition of annotation processing options, it became obvious that this isn't very userfriendly. For example, this usage message would require nearly two 24x80 screens: javac: not a directory: Test.java Usage: javac <options> <source files> where possible options include: -g Generate all debugging info -g:none Generate no debugging info -g:{lines,vars,source} Generate only some debugging info -nowarn Generate no warnings -verbose Output messages about what the compiler is doing -deprecation Output source locations where deprecated APIs are used -classpath <path> Specify where to find user class files and annotation processors -cp <path> Specify where to find user class files and annotation processors -sourcepath <path> Specify where to find input source files -bootclasspath <path> Override location of bootstrap class files -extdirs <dirs> Override location of installed extensions -endorseddirs <dirs> Override location of endorsed standards path -proc:{none, only} Control whether annotation processing and/or compilation is done. -processor <class1>[,<class2>,<class3>...]Names of the annotation processors to run; bypasses default discovery process -processorpath <path> Specify where to find annotation processors -d <directory> Specify where to place generated class files -s <directory> Specify where to place generated source files -encoding <encoding> Specify character encoding used by source files -source <release> Provide source compatibility with specified release -target <release> Generate class files for specific VM version -version Version information -help Print a synopsis of standard options -Akey[=value] Options to pass to annotation processors -X Print a synopsis of nonstandard options -J<flag> Pass <flag> directly to the runtime system
12-04-2006

EVALUATION -sourcepath is a different problem and was fixed in b79 (6407011). Notice that the stack trace is different and the exception is a null pointer exception, not illegal argument exception.
09-04-2006

SUGGESTED FIX --- /tmp/geta32054 2006-04-09 02:18:55.867356176 -0700 +++ RecognizedOptions.java 2006-04-09 02:02:31.836951536 -0700 @@ -21,6 +21,7 @@ import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Options; import com.sun.tools.javac.util.Version; +import java.io.File; import java.io.FileWriter; import java.io.PrintWriter; import java.util.EnumSet; @@ -343,8 +344,26 @@ }, new Option(PROCESSOR, "opt.arg.class.list", "opt.processor"), new Option(PROCESSORPATH, "opt.arg.path", "opt.processorpath"), - new Option(D, "opt.arg.directory", "opt.d"), - new Option(S, "opt.arg.directory", "opt.sourceDest"), + new Option(D, "opt.arg.directory", "opt.d") { + public boolean process(Options options, String option, String operand) { + File file = new File(operand); + if (file.exists() && !file.isDirectory()) { + helper.error("err.file.not.directory", operand); + return true; + } + return super.process(options, option, operand); + } + }, + new Option(S, "opt.arg.directory", "opt.sourceDest") { + public boolean process(Options options, String option, String operand) { + File file = new File(operand); + if (file.exists() && !file.isDirectory()) { + helper.error("err.file.not.directory", operand); + return true; + } + return super.process(options, option, operand); + } + }, new Option(ENCODING, "opt.arg.encoding", "opt.encoding"), new Option(SOURCE, "opt.arg.release", "opt.source") { public boolean process(Options options, String option, String operand) {
09-04-2006

EVALUATION A bug caused by JSR 199 in b78. Changed the compiler so that it checks the validity of -s and -d while processing options.
09-04-2006