Bug 32557

Summary: DependTest.testClosure fails under JDK 1.5
Product: Ant Reporter: Jesse Glick <jglick>
Component: Optional TasksAssignee: Ant Notifications List <notifications>
Status: RESOLVED FIXED    
Severity: normal CC: notifications
Priority: P2 Keywords: JDK1.5
Version: nightly   
Target Milestone: 1.7.0   
Hardware: PC   
OS: Linux   

Description Jesse Glick 2004-12-07 07:37:32 UTC
DependTest.testClosure passes for me if I run using JDK 1.4.2 (Linux) but fails
if run under JDK 1.5 (or a 1.6 alpha). The error message is

Depend did not leave correct number of files expected:<2> but was:<1>

If however I set source="1.2" on <javac> in depend.xml#compile, it passes (on
1.4, 1.5, and 1.6). I suspect that there is some difference in javac's bytecode
generation when using 1.5 source, though I don't know what exactly.
Comment 1 Stefan Bodewig 2004-12-21 16:00:15 UTC
I (and Gump ;-) can confirm that.
Comment 2 Conor MacNeill 2004-12-22 15:11:44 UTC
JDK 1.5 is much smarter when it comes to handling the code in one of the test
files. 
public class E {
    E() {
        System.out.println(A.class);
    }
}

In JDK 1.5, thie uses a class reference in the produced class file to A, rather
than a string reference as used in previous versions. The code for the above has
gone from:

{
static java.lang.Class class$A;
  Synthetic: true

E();
  Code:
   Stack=3, Locals=1, Args_size=1
   0:   aload_0
   1:   invokespecial   #6; //Method java/lang/Object."<init>":()V
   4:   getstatic       #7; //Field java/lang/System.out:Ljava/io/PrintStream;
   7:   getstatic       #8; //Field class$A:Ljava/lang/Class;
   10:  ifnonnull       25
   13:  ldc     #9; //String A
   15:  invokestatic    #10; //Method class$:(Ljava/lang/String;)Ljava/lang/Class;
   18:  dup
   19:  putstatic       #8; //Field class$A:Ljava/lang/Class;
   22:  goto    28
   25:  getstatic       #8; //Field class$A:Ljava/lang/Class;
   28:  invokevirtual   #11; //Method
java/io/PrintStream.println:(Ljava/lang/Object;)V
   31:  return

static java.lang.Class class$(java.lang.String);
  Code:
   Stack=3, Locals=2, Args_size=1
   0:   aload_0
   1:   invokestatic    #1; //Method
java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
   4:   areturn
   5:   astore_1
   6:   new     #3; //class java/lang/NoClassDefFoundError
   9:   dup
   10:  aload_1
   11:  invokevirtual   #4; //Method
java/lang/ClassNotFoundException.getMessage:()Ljava/lang/String;
   14:  invokespecial   #5; //Method
java/lang/NoClassDefFoundError."<init>":(Ljava/lang/String;)V
   17:  athrow
  Exception table:
   from   to  target type
     0     4     5   Class java/lang/ClassNotFoundException

  Synthetic: true

}


to


E();
  Code:
   Stack=2, Locals=1, Args_size=1
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   7:   ldc_w   #3; //class A
   10:  invokevirtual   #4; //Method
java/io/PrintStream.println:(Ljava/lang/Object;)V
   13:  return

}

Quite an improvment.
Comment 3 Jesse Glick 2004-12-22 17:14:52 UTC
Is it just the test that is fixed, or the task? If the latter, might be a good
1.6.3 candidate.
Comment 4 Conor MacNeill 2004-12-22 23:09:48 UTC
Only the test code has changed. 

The only implication of this bug is that under JDK 1.5+, the <depend> code, as
it currently stands, will perform a little bit better than under previous JDKs.
 A source file which contains a reference to a class of the form "A.class" will
generate a classfile with a class reference to A. Sice <depend> uses class
references to build its dependency model, under JDK 1.5, that model will be more
accurate.