Bug 81824 - A generic interface is allowed to be implemented more than once - contrary to Java language specification
Summary: A generic interface is allowed to be implemented more than once - contrary to...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.1 M5   Edit
Assignee: Kent Johnson CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 82287 85416 (view as bug list)
Depends on:
Blocks:
 
Reported: 2004-12-22 16:19 EST by Irfan Adilovic CLA
Modified: 2016-08-08 03:50 EDT (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Irfan Adilovic CLA 2004-12-22 16:19:04 EST
Implementing a generic interface with different type parameters is allowed by
the JDT compiler, however this should not be so. Loading such an implementing
class in the JVM causes:

java.lang.ClassFormatError: Repetitive interface name in class file X
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:620)

and so on...

(Note: I am assuming that the language specification disallows the described
behaviour just because I see the exception at runtime - I haven't really read
the specs)

The shortest code to reproduce the problem is:

interface I<T> {}
public class X implements I<Integer>, I<String> {
	public static void main(String... args) {} 
}

Just execute the main method to get the exception.

Note that compiling by the original javac yields:

X.java:2: I cannot be inherited with different arguments: <java.lang.Integer>
and <java.lang.String>
public class X implements I<Integer>, I<String> {
       ^
1 error

The problem was discovered in Eclipse 3.1M4 under Windows XP with Sun's JDK5.0
(javac 1.5.0-rc). Not tested on any other configuration, but /should/ be
Eclipse-specific, and presumably reproducible on other platforms with this
Eclipse build.

-- Irfy
Comment 1 Irfan Adilovic CLA 2004-12-22 16:56:31 EST
It is clear that erasure is the reason why the code cannot be allowed.

It comes down indirectly to the language specification - because obviously, the
bytecoded class (X from the original post above) contains two identical
interfaces implemented.

Perhaps this bug should have been named "JDT compiler does not consider problems
predictable at compile-time and caused by erasure"

-- Irfy
Comment 2 Kent Johnson CLA 2005-01-05 16:37:56 EST
Added GenericType test444
Comment 3 Olivier Thomann CLA 2005-01-05 17:17:29 EST
*** Bug 82287 has been marked as a duplicate of this bug. ***
Comment 4 David Audel CLA 2005-02-15 12:49:49 EST
Verified in I20050214-0927
Comment 5 Olivier Thomann CLA 2005-02-16 10:10:35 EST
*** Bug 85416 has been marked as a duplicate of this bug. ***
Comment 6 John Creighton CLA 2010-09-15 16:30:18 EDT
(In reply to comment #1)
> It is clear that erasure is the reason why the code cannot be allowed.
> 
> It comes down indirectly to the language specification - because obviously, the
> bytecoded class (X from the original post above) contains two identical
> interfaces implemented.
> 
> Perhaps this bug should have been named "JDT compiler does not consider problems
> predictable at compile-time and caused by erasure"
> 
> -- Irfy

If you create two separate subtypes of the interface then you should get two different interface names. However, doing this still gives the same error in eclipse.
Comment 7 Irfan Adilovic CLA 2010-09-16 09:09:11 EDT
(In reply to comment #6)
> If you create two separate subtypes of the interface then you should get two
> different interface names. However, doing this still gives the same error in
> eclipse.

My original concern was that the Eclipse compiler behaved differently than javac.

Concerning your comment with two separate subtypes, Eclipse behaves identically to javac, so I'm strongly assuming Eclipse behaves correctly.

interface I<T> {}
interface I1<T> extends I<T> {}
interface I2<T> extends I<T> {}
public class X implements I1<Integer>, I2<String> {}

*or*

interface I<T> {}
interface I1 extends I<Integer> {}
interface I2 extends I<String> {}
public class X implements I1, I2 {}

Eclipse:
The interface I cannot be implemented more than once with different arguments: I<String> and I<Integer>

Javac:
X.java:4: I cannot be inherited with different arguments: <java.lang.Integer> and <java.lang.String>
public class X implements I1<Integer>, I2<String> {}

p.s.
This bug has been fixed for five years now. It is generally preferable to open a new bug if you think something is in error.