Bug 137744 - [compiler] java.lang.ClassFormatError: test/B (Repetitive method name/signature)
Summary: [compiler] java.lang.ClassFormatError: test/B (Repetitive method name/signature)
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows 2000
: P3 minor (vote)
Target Milestone: 3.2 RC2   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 138428 (view as bug list)
Depends on:
Blocks:
 
Reported: 2006-04-20 10:55 EDT by Barthel Steckemetz CLA
Modified: 2006-04-28 14:41 EDT (History)
1 user (show)

See Also:


Attachments
The test case. (5.81 KB, application/zip)
2006-04-20 10:56 EDT, Barthel Steckemetz CLA
no flags Details
Proposed fix (971 bytes, patch)
2006-04-20 11:27 EDT, Olivier Thomann CLA
no flags Details | Diff
Better patch (1.87 KB, patch)
2006-04-20 11:38 EDT, Olivier Thomann CLA
no flags Details | Diff
New patch (2.15 KB, patch)
2006-04-20 12:01 EDT, Olivier Thomann CLA
no flags Details | Diff
Regression test (2.49 KB, patch)
2006-04-20 12:02 EDT, Olivier Thomann CLA
no flags Details | Diff
Final patch (6.54 KB, patch)
2006-04-21 06:32 EDT, Philipe Mulet CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Barthel Steckemetz CLA 2006-04-20 10:55:11 EDT
I am getting the following stacktrace,
when starting class test.Test.main:

java.lang.ClassFormatError: test/B (Repetitive method name/signature)
	at java.lang.ClassLoader.defineClass0(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:539)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:123)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:251)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:55)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:194)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:187)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:289)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:274)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
	at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302)
Exception in thread "main" 

I have attached a test case.
The decompiled class B using jad looks like this:


package test;


// Referenced classes of package test:
//            A, IA3, IA1

public abstract class B extends A
    implements IA3, IA1
{

    public B()
    {
    }

    public void test()
    {
    }

    public abstract boolean hasKursAt(int i);

    public abstract boolean hasKursAt(int i);

    int a;
}

The problem arises because of severel interfaces containing the
same method:
    public abstract boolean hasKursAt(int i);

I was not able to reduce the test case any further.
I am using jdk 1.4.2_08 as runtime.

This bug may be a duplicate:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=126423
Comment 1 Barthel Steckemetz CLA 2006-04-20 10:56:30 EDT
Created attachment 39037 [details]
The test case.
Comment 2 Olivier Thomann CLA 2006-04-20 10:58:43 EDT
I'll investigate it.
Comment 3 Barthel Steckemetz CLA 2006-04-20 11:00:58 EDT
I used Eclipse 3.2 RC 1.

We had no problems using 3.1.*
Comment 4 Olivier Thomann CLA 2006-04-20 11:05:00 EDT
I tried your test case and it doesn't fail. What VM are you using?
Could you please provide your compiler settings ?

Thanks.
Comment 5 Barthel Steckemetz CLA 2006-04-20 11:11:33 EDT
Some more info:

we use the following Java Compiler Preferences:

Compiler Compliance Level: 1.3
Generated Class Files compatibility: 1.1
Source Compatibility: 1.3

The problem vanished if I set all to 1.4.
Comment 6 Barthel Steckemetz CLA 2006-04-20 11:12:52 EDT
This certainly reduces the severity to minor.
We are using sun jdk 1.4.2_08.
Comment 7 Olivier Thomann CLA 2006-04-20 11:15:04 EDT
Reproduced if the compiler compliance is set to 1.3.
Thanks for the steps.
Comment 8 Olivier Thomann CLA 2006-04-20 11:20:09 EDT
If the compliance is 1.3, B.class looks like this:

// Compiled from B.java (version 1.1 : 45.3, super bit)
public abstract class test.B extends test.A implements test.IA3, test.IA1 {
  Constant pool:
    constant #1 class: #2 test/B
    constant #2 utf8: "test/B"
    constant #3 class: #4 test/A
    constant #4 utf8: "test/A"
    constant #5 class: #6 test/IA3
    constant #6 utf8: "test/IA3"
    constant #7 class: #8 test/IA1
    constant #8 utf8: "test/IA1"
    constant #9 utf8: "a"
    constant #10 utf8: "I"
    constant #11 utf8: "<init>"
    constant #12 utf8: "()V"
    constant #13 utf8: "Code"
    constant #14 method_ref: #3.#15 test/A.<init> ()V
    constant #15 name_and_type: #11.#12 <init> ()V
    constant #16 utf8: "LineNumberTable"
    constant #17 utf8: "LocalVariableTable"
    constant #18 utf8: "this"
    constant #19 utf8: "Ltest/B;"
    constant #20 utf8: "test"
    constant #21 utf8: "hasKursAt"
    constant #22 utf8: "(I)Z"
    constant #23 utf8: "SourceFile"
    constant #24 utf8: "B.java"
  
  // Field descriptor #10 I
  int a;
  
  // Method descriptor #12 ()V
  // Stack: 1, Locals: 1
  public B();
    0  aload_0 [this]
    1  invokespecial test.A() [14]
    4  return
      Line numbers:
        [pc: 0, line: 13]
        [pc: 4, line: 14]
      Local variable table:
        [pc: 0, pc: 5] local: this index: 0 type: test.B
  
  // Method descriptor #12 ()V
  // Stack: 0, Locals: 1
  public void test();
    0  return
      Line numbers:
        [pc: 0, line: 17]
      Local variable table:
        [pc: 0, pc: 1] local: this index: 0 type: test.B
  
  // Method descriptor #22 (I)Z
  public abstract boolean hasKursAt(int arg0);
  
  // Method descriptor #22 (I)Z
  public abstract boolean hasKursAt(int arg0);
}

We do have a duplicate method in it.
Comment 9 Olivier Thomann CLA 2006-04-20 11:25:27 EDT
The bug seems to come from the fact that the methods are not sorted once the default abstract method is added.
Then the call implementsMethod(method) might returns false even if the method is already in the list.
Comment 10 Olivier Thomann CLA 2006-04-20 11:27:17 EDT
Created attachment 39041 [details]
Proposed fix
Comment 11 Olivier Thomann CLA 2006-04-20 11:28:00 EDT
There might be a more efficient way to sort the method after the addition of a default abstract method.
Comment 12 Barthel Steckemetz CLA 2006-04-20 11:29:59 EDT
Thanks Olivier,

that was very fast!
Comment 13 Olivier Thomann CLA 2006-04-20 11:38:08 EDT
Created attachment 39047 [details]
Better patch

Might be a better patch.
Comment 14 Olivier Thomann CLA 2006-04-20 12:01:57 EDT
Created attachment 39058 [details]
New patch

No need to use a temp local to store the new array.
Also factorize the this.methods.length calls.
Comment 15 Olivier Thomann CLA 2006-04-20 12:02:11 EDT
Created attachment 39059 [details]
Regression test
Comment 16 Olivier Thomann CLA 2006-04-20 12:05:40 EDT
In fact -target 1.1 is enough to reproduce the failure. When target >= 1.2, there is no longer the addition of default abstract methods.
Compliance 1.3 sets the target to 1.1 by default.
Comment 17 Olivier Thomann CLA 2006-04-20 13:22:44 EDT
All tests passed with the latest patch.
Another solution would be to change isImplements(...) implementation to get rid of the assumption that the method bindings are sorted.

Then only one sort would be done at the end of the method that adds all default abstract methods followed by the line:
	this.tagBits |= TagBits.AreMethodsSorted;
Comment 18 Philipe Mulet CLA 2006-04-21 06:29:32 EDT
Additions of default abstracts along the checking process are definitely breaking the algorithm which relies on sorting.
Will rather separate default abstracts from the method array, and only inject them at the end. This avoids multiple sorts, and multiple array growing.

Comment 19 Philipe Mulet CLA 2006-04-21 06:30:11 EDT
Moved the regression test to LookupTest#test064.
Comment 20 Philipe Mulet CLA 2006-04-21 06:32:06 EDT
Created attachment 39155 [details]
Final patch
Comment 21 Philipe Mulet CLA 2006-04-21 06:55:27 EDT
Fix released
Comment 22 Philipe Mulet CLA 2006-04-26 11:39:11 EDT
*** Bug 138428 has been marked as a duplicate of this bug. ***
Comment 23 Olivier Thomann CLA 2006-04-28 14:41:12 EDT
Verified with I20060427-1600 for 3.2RC2