Skip to main content



      Home
Home » Eclipse Projects » Eclipse Platform » Compile bug in Eclipse 2.1?
Compile bug in Eclipse 2.1? [message #28287] Tue, 06 May 2003 13:53 Go to next message
Eclipse UserFriend
Originally posted by: eclipse.wingspread.fastmail.fm

In the process of importing some code from our VisualAge for Java
environment I ran across a situation where many of the classes which
compiled fine in VAJ had errors under Eclipse. The strange thing is that
the errors I was receiving didn't make any sense. After some
experimentation, I have come up with a minimal class which exhibits the
problem. Before I report this as an Eclipse bug, I would like to know if
I'm overlooking something stupid. First, here is the class I'm trying to
compile:

package test;

import junit.framework.TestCase;

public class Test extends TestCase{
public Test(String name) {
super(name);
}

final private static double TOLERANCE = 1.0e-9;

static public void assertEquals(double expected, double actual) {
double delta = Math.abs(expected * TOLERANCE);
assertEquals(expected, actual, delta);
}

public void testAssertEqualsWithInts() {
assertEquals( 3, 4);
}
}

I did a clean installation of Eclipse 2.1 SDK and have performed no other
modifications or configuration changes. I created a single Java project
called Test. The Test project has a directory called src which is where my
Java code lives. The .classpath file looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con"
path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="var"
path="ECLIPSE_HOME/plugins/org.junit_3.8.1/junit.jar"
sourcepath=" ECLIPSE_HOME/plugins/org.eclipse.jdt.source_2.1.0/src/org.ju nit_3.8.1/junitsrc.zip "/>
<classpathentry kind="output" path="bin"/>
</classpath>

The .project file looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Test</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>


When I rebuild the project, the compiler complains about the
assertEquals(3, 4) statement in the testAssertEqualsWithInts() method. The
compiler error says "The method assertEquals(double, double) is ambiguous
for the type Test". As far as I can tell, there is no ambiguity at all.
There is only one place where assertEquals(double, double) is defined and
that's in my class. Also, the line with the error isn't invoking
assertEquals(double, double), it's invoking assertEquals(int, int).
Finally, I've exported the code and compiled it with the JDK 1.4 compiler
without difficulty. This appears to me to be a bug in the Eclipse
compiler, but I'm willing to be convinced otherwise.

Thanks.



--
James Howe
Re: Compile bug in Eclipse 2.1? [message #28508 is a reply to message #28287] Tue, 06 May 2003 15:16 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: Olivier_Thomann.ca.ibm.comNOSPAM

On Tue, 06 May 2003 13:53:09 -0400, James Howe
<eclipse@wingspread.fastmail.fm> wrote:
>When I rebuild the project, the compiler complains about the
>assertEquals(3, 4) statement in the testAssertEqualsWithInts() method. The
>compiler error says "The method assertEquals(double, double) is ambiguous
>for the type Test". As far as I can tell, there is no ambiguity at all.
>There is only one place where assertEquals(double, double) is defined and
>that's in my class. Also, the line with the error isn't invoking
>assertEquals(double, double), it's invoking assertEquals(int, int).
>Finally, I've exported the code and compiled it with the JDK 1.4 compiler
>without difficulty. This appears to me to be a bug in the Eclipse
>compiler, but I'm willing to be convinced otherwise.
Because int can be converted to double using the method invocation
conversion rule, Assert.asserEquals(int, int) is actually ambiguous
with your test.Test.assertEquals(double, double).
See JLS:
http://java.sun.com/docs/books/jls/second_edition/html/conve rsions.doc.html#25214
and:
http://java.sun.com/docs/books/jls/second_edition/html/expre ssions.doc.html#20448
chap. 15.12.2.2.

Jikes 1.18 also reports an ambigous call with your test case.
JDK1.4.2 (b19) is failing to report the ambiguity. I will check the
latest b21.

HTH,
--
Olivier
Re: Compile bug in Eclipse 2.1? [message #28517 is a reply to message #28508] Tue, 06 May 2003 16:24 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: eclipse.wingspread.fastmail.fm

On Tue, 06 May 2003 15:16:30 -0400, Olivier Thomann
<Olivier_Thomann@ca.ibm.comNOSPAM> wrote:

> On Tue, 06 May 2003 13:53:09 -0400, James Howe
> <eclipse@wingspread.fastmail.fm> wrote:
>> When I rebuild the project, the compiler complains about the
>> assertEquals(3, 4) statement in the testAssertEqualsWithInts() method.
>> The compiler error says "The method assertEquals(double, double) is
>> ambiguous for the type Test". As far as I can tell, there is no
>> ambiguity at all. [...]
>
> Because int can be converted to double using the method invocation
> conversion rule, Assert.asserEquals(int, int) is actually ambiguous
> with your test.Test.assertEquals(double, double).
>
> See JLS:
> http://java.sun.com/docs/books/jls/second_edition/html/conve rsions.doc.html#25214
>
>
> and:
> http://java.sun.com/docs/books/jls/second_edition/html/expre ssions.doc.html#20448
>
>
> chap. 15.12.2.2.
>
> Jikes 1.18 also reports an ambigous call with your test case.
> JDK1.4.2 (b19) is failing to report the ambiguity. I will check the
> latest b21.
>
> HTH,
> --
> Olivier
>

Still seems like a bug to me. For example, this seems no different than if
a superclass defines

"static public void foo(Object obj) { ... do something ... }"

and the subclass defines

"static public void foo(String obj) { ... do something ... }"

and from the subclass I make two invocations:

foo(new Object()); /* use some non string object */
foo("this"); /* use a string object*/

In fact, I just tried this in Eclipse and not only did it compile, it
worked correctly as well. Calling the method with String in the signature
resulted in the String version being executed, whereas passing just an
Object resulted in the Object version being executed. Since my test code
was invoking assertEquals(int, int) and there existing an assertEquals(int,
int) it doesn't seem like there should be any ambiguity at all.

A colleague of mine just did some perusal of the spec and his
interpretation is that there is no ambiguity. The important bits come from
section 15.12.2.2 of the document mentioned above:

According to the spec:

"If more than one method declaration is both accessible and applicable to a
method invocation, it is necessary to choose one to provide the descriptor
for the run-time method dispatch. The Java programming language uses the
rule that the most specific method is chosen."

In the code I posted, assert(int, int) and assert(double, double) should
both be considered accessible and applicable due to the rule you mention
above about conversion. So this step is used to see if one is more
specific than the other to try and determin which method to call.

Continuing, the spec says:
"The informal intuition is that one method declaration is more specific
than another if any invocation handled by the first method could be passed
on to the other one without a compile-time type error."

So assert(int, int) could call assert(double, double) without casting.
However, the converse is not true - the double version would give an error
if it tried to call the int version. therefore the int version is more
specific and should be chosen.

Since there is a way to correctly determine which method to use, there is
no ambiguity and the code should compile cleanly. I think Jikes and the
Eclipse compiler are exhibiting the same bug.
--
James Howe
Re: Compile bug in Eclipse 2.1? [message #28586 is a reply to message #28517] Wed, 07 May 2003 07:19 Go to previous messageGo to next message
Eclipse UserFriend
James Howe <eclipse@wingspread.fastmail.fm> wrote:
> Still seems like a bug to me. For example, this seems no different than if
> a superclass defines
>
> "static public void foo(Object obj) { ... do something ... }"
>
> and the subclass defines
>
> "static public void foo(String obj) { ... do something ... }"
>
> and from the subclass I make two invocations:
>
> foo(new Object()); /* use some non string object */
> foo("this"); /* use a string object*/
>
> In fact, I just tried this in Eclipse and not only did it compile, it
> worked correctly as well.

That's because you've got them the wrong way round. Just as int can be
implicitly converted to double, String can be implicitly converted to
Object. Change them round so that the *superclass* defines foo(String
obj) and the *subclass* defines foo(Object obj) and you get a compile
time error.

<snip>

> Continuing, the spec says:
> "The informal intuition is that one method declaration is more specific
> than another if any invocation handled by the first method could be passed
> on to the other one without a compile-time type error."

Yes, that's the *informal intuition* though, rather than the detailed
rule.

> So assert(int, int) could call assert(double, double) without casting.
> However, the converse is not true - the double version would give an error
> if it tried to call the int version. therefore the int version is more
> specific and should be chosen.

No it's *not* more specific, because the exact rule for a method being
more specific than another requires that the type declaring the more
specific version can be converted to the type declaring the less
specific version by method. That's not the case here. The parameter
conversions go one way, as it were, and the declaring type conversion
goes the other way.

Javac gives exactly the same error when the methods aren't static, note
- but I don't see any reference to whether or not the method is static
being relevant in the choice of a maximally specific method.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too
Re: Compile bug in Eclipse 2.1? [message #28594 is a reply to message #28287] Wed, 07 May 2003 08:57 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: jvaldez.mail.com

The are assertEquals in the super class. I suspect assertEquals(float,
float). Since you are expecting the compiler to convert ints (3,4)
automatically it is complaining that it's unsure about the conversion.
Try assertEquals(3F,4F) and see if that fixes the prob.

James Howe wrote:
> In the process of importing some code from our VisualAge for Java
> environment I ran across a situation where many of the classes which
> compiled fine in VAJ had errors under Eclipse. The strange thing is
> that the errors I was receiving didn't make any sense. After some
> experimentation, I have come up with a minimal class which exhibits the
> problem. Before I report this as an Eclipse bug, I would like to know
> if I'm overlooking something stupid. First, here is the class I'm
> trying to compile:
>
> package test;
>
> import junit.framework.TestCase;
>
> public class Test extends TestCase{
> public Test(String name) {
> super(name);
> }
>
> final private static double TOLERANCE = 1.0e-9;
>
> static public void assertEquals(double expected, double actual) {
> double delta = Math.abs(expected * TOLERANCE);
> assertEquals(expected, actual, delta);
> }
>
> public void testAssertEqualsWithInts() {
> assertEquals( 3, 4);
> }
> }
>
> I did a clean installation of Eclipse 2.1 SDK and have performed no
> other modifications or configuration changes. I created a single Java
> project called Test. The Test project has a directory called src which
> is where my Java code lives. The .classpath file looks like this:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <classpath>
> <classpathentry kind="src" path="src"/>
> <classpathentry kind="con"
> path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
> <classpathentry kind="var"
> path="ECLIPSE_HOME/plugins/org.junit_3.8.1/junit.jar"
> sourcepath=" ECLIPSE_HOME/plugins/org.eclipse.jdt.source_2.1.0/src/org.ju nit_3.8.1/junitsrc.zip "/>
>
> <classpathentry kind="output" path="bin"/>
> </classpath>
>
> The .project file looks like this:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <projectDescription>
> <name>Test</name>
> <comment></comment>
> <projects>
> </projects>
> <buildSpec>
> <buildCommand>
> <name>org.eclipse.jdt.core.javabuilder</name>
> <arguments>
> </arguments>
> </buildCommand>
> </buildSpec>
> <natures>
> <nature>org.eclipse.jdt.core.javanature</nature>
> </natures>
> </projectDescription>
>
>
> When I rebuild the project, the compiler complains about the
> assertEquals(3, 4) statement in the testAssertEqualsWithInts() method.
> The compiler error says "The method assertEquals(double, double) is
> ambiguous for the type Test". As far as I can tell, there is no
> ambiguity at all. There is only one place where assertEquals(double,
> double) is defined and that's in my class. Also, the line with the
> error isn't invoking assertEquals(double, double), it's invoking
> assertEquals(int, int). Finally, I've exported the code and compiled it
> with the JDK 1.4 compiler without difficulty. This appears to me to be
> a bug in the Eclipse compiler, but I'm willing to be convinced otherwise.
>
> Thanks.
>
>
>
Re: Compile bug in Eclipse 2.1? [message #28617 is a reply to message #28586] Wed, 07 May 2003 10:09 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: eclipse.wingspread.fastmail.fm

On Wed, 7 May 2003 12:19:47 +0100, Jon Skeet <skeet@pobox.com> wrote:

> James Howe <eclipse@wingspread.fastmail.fm> wrote:
>> Still seems like a bug to me. For example, this seems no different than
>> if a superclass defines
>>
>> "static public void foo(Object obj) { ... do something ... }"
>>
>> and the subclass defines
>>
>> "static public void foo(String obj) { ... do something ... }"
>>
>> and from the subclass I make two invocations:
>> [...]
>
> That's because you've got them the wrong way round. Just as int can be
> implicitly converted to double, String can be implicitly converted to
> Object. Change them round so that the *superclass* defines foo(String
> obj) and the *subclass* defines foo(Object obj) and you get a compile
> time error.
>
> [...]
>
> No it's *not* more specific, because the exact rule for a method being
> more specific than another requires that the type declaring the more
> specific version can be converted to the type declaring the less specific
> version by method. That's not the case here. The parameter conversions go
> one way, as it were, and the declaring type conversion goes the other
> way.
>
> [...]
>

I guess the problem I'm having has to do with the fact that the spec
apparently wants to treat int as if it were a subclass of double. In the
Object hierarchy, Integer and Double are siblings with a common parent of
Number. Just another place in Java where things are inconsistent. It's
just wrong (in my opinion) that the compiler treats a reference to
method(int) as ambiguous with method(double). I would be much happier if I
had to manually cast an int to a double if I wanted to pass it to a method
which took a double as a parameter instead of an int.

--
James Howe
Re: Compile bug in Eclipse 2.1? [message #28619 is a reply to message #28617] Wed, 07 May 2003 10:14 Go to previous messageGo to next message
Eclipse UserFriend
James Howe <eclipse@wingspread.fastmail.fm> wrote:
> I guess the problem I'm having has to do with the fact that the spec
> apparently wants to treat int as if it were a subclass of double.

No it doesn't - it just wants to treat int as if it is implicitly
convertible to double, which it is.

> In the Object hierarchy, Integer and Double are siblings with a
> common parent of Number.
> Just another place in Java where things are inconsistent. It's
> just wrong (in my opinion) that the compiler treats a reference to
> method(int) as ambiguous with method(double). I would be much happier if I
> had to manually cast an int to a double if I wanted to pass it to a method
> which took a double as a parameter instead of an int.

But you'd be unhappy if you had to manually convert String to Object,
wouldn't you? Why is one any better than the other? Bear in mind that
*every* int is exactly representable as a double...

I'll see if I can find a bug parade entry for this against javac, and
if not I'll start one. I believe it *is* javac which is wrong on this
one.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too
Re: Compile bug in Eclipse 2.1? [message #28621 is a reply to message #28594] Wed, 07 May 2003 10:14 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: eclipse.wingspread.fastmail.fm

On Wed, 07 May 2003 06:57:45 -0600, Juan <jvaldez@mail.com> wrote:

> The are assertEquals in the super class. I suspect assertEquals(float,
> float). Since you are expecting the compiler to convert ints (3,4)
> automatically it is complaining that it's unsure about the conversion.
> Try assertEquals(3F,4F) and see if that fixes the prob.
>
> [...]

No, there is an assertEquals(int, int) in the superclass. The problem is
that we define an assertEquals(double, double) in a subclass which invokes
the assertEquals(double, double, double) method with an automatically
computed tolerance. Since we have defined assertEquals(double, double),
any reference to assertEquals(int, int) is apparently generating confusion
in the compiler because either the assertEquals(int, int) or the
assertEquals(double, double) could apply. I want the assertEquals(int,
int) to be invoked, that is why I'm sending two ints, but the compiler
wants to be 'helpful' by letting me also invoke assertEquals(double,
double) without doing any explicit casting.


--
James Howe
Re: Compile bug in Eclipse 2.1? [message #28629 is a reply to message #28619] Wed, 07 May 2003 11:12 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: eclipse.wingspread.fastmail.fm

On Wed, 7 May 2003 15:14:18 +0100, Jon Skeet <skeet@pobox.com> wrote:

> James Howe <eclipse@wingspread.fastmail.fm> wrote:
>> I guess the problem I'm having has to do with the fact that the spec
>> apparently wants to treat int as if it were a subclass of double.
>
> No it doesn't - it just wants to treat int as if it is implicitly
> convertible to double, which it is.
>
>> In the Object hierarchy, Integer and Double are siblings with a common
>> parent of Number.
>> Just another place in Java where things are inconsistent. It's just
>> wrong (in my opinion) that the compiler treats a reference to
>> method(int) as ambiguous with method(double). I would be much happier
>> if I had to manually cast an int to a double if I wanted to pass it to a
>> method which took a double as a parameter instead of an int.
>
> But you'd be unhappy if you had to manually convert String to Object,
> wouldn't you? Why is one any better than the other? Bear in mind that
> *every* int is exactly representable as a double...
>
> I'll see if I can find a bug parade entry for this against javac, and if
> not I'll start one. I believe it *is* javac which is wrong on this one.
>

I would be unhappy to manually convert String to Object because String *is*
an Object. It is a proper subclass of Object. I would not, however,
expect a manual conversion from Integer to Double because Integer is not a
subclass of Double. Integer is convertable to Double, but I wouldn't
expect it to happen automatically. Similarly I do not expect ints to be
automatically converted to doubles when I'm invoking a method. I don't
think of an int as being a double. It is only convertable to a double.
Therefore I should have to cast it to be a double if I'm passing it to a
method which expects a double.

As an alternative, I would be happy if Java provided a way to dis-ambiguate
a method call by an explicit cast. For example, if assertEquals(int, int)
is ambiguous with assertEquals(double, double) when invoked with
assertEquals(3, 5), I should be able to tell the compiler to use the
assertEquals(int, int) by doing assertEquals((int) 3, (int) 5). This
doesn't work, however.



--
James Howe
Re: Compile bug in Eclipse 2.1? [message #28654 is a reply to message #28629] Wed, 07 May 2003 12:40 Go to previous messageGo to next message
Eclipse UserFriend
James Howe <eclipse@wingspread.fastmail.fm> wrote:
> I would be unhappy to manually convert String to Object because String *is*
> an Object. It is a proper subclass of Object. I would not, however,
> expect a manual conversion from Integer to Double because Integer is not a
> subclass of Double. Integer is convertable to Double, but I wouldn't
> expect it to happen automatically.

No, Integer is *not* convertible to Double - at least not using
"conversion" in any sense that the spec usually talks about. You can't
cast from an Integer to a Double or vice versa, whereas you *can* cast
from a double to an int, and the reverse is available implicitly, as it
doesn't lose any data.

> Similarly I do not expect ints to be
> automatically converted to doubles when I'm invoking a method. I don't
> think of an int as being a double. It is only convertable to a double.
> Therefore I should have to cast it to be a double if I'm passing it to a
> method which expects a double.

Well, the Java specification disagrees - which I think is reasonable,
as every int *is* exactly representable as a double. The Integer and
Double classes have nothing to do with that. Personally I like it the
way it is, but there we go.

Either way, it's certainly not an Eclipse bug.

> As an alternative, I would be happy if Java provided a way to dis-ambiguate
> a method call by an explicit cast. For example, if assertEquals(int, int)
> is ambiguous with assertEquals(double, double) when invoked with
> assertEquals(3, 5), I should be able to tell the compiler to use the
> assertEquals(int, int) by doing assertEquals((int) 3, (int) 5). This
> doesn't work, however.

That is indeed a pity.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too
Re: Compile bug in Eclipse 2.1? [message #28660 is a reply to message #28654] Wed, 07 May 2003 13:10 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: eclipse.wingspread.fastmail.fm

On Wed, 7 May 2003 17:40:06 +0100, Jon Skeet <skeet@pobox.com> wrote:

> James Howe <eclipse@wingspread.fastmail.fm> wrote:
>> I would be unhappy to manually convert String to Object because String
>> *is* an Object. It is a proper subclass of Object. I would not,
>> however, expect a manual conversion from Integer to Double because
>> Integer is not a subclass of Double. Integer is convertable to Double,
>> but I wouldn't expect it to happen automatically.
>
> No, Integer is *not* convertible to Double - at least not using
> "conversion" in any sense that the spec usually talks about. You can't
> cast from an Integer to a Double or vice versa, whereas you *can* cast
> from a double to an int, and the reverse is available implicitly, as it
> doesn't lose any data.
>

Correct, you can't just cast Integer to Double and have it work. Which is
why I think it is strange that you *can* cast int to double and have it
work and worse yet, Java will do it automatically. Why is the object
behavior different than the primitive behavior? If Integer is an object
wrapper for int and Double is an object wrapper for double, why can't you
directly cast Integer to Double if you can directly cast int to double?

>  
> Either way, it's certainly not an Eclipse bug.
>

Agreed.

--
James Howe
Re: Compile bug in Eclipse 2.1? [message #28746 is a reply to message #28660] Thu, 08 May 2003 03:19 Go to previous messageGo to next message
Eclipse UserFriend
James Howe <eclipse@wingspread.fastmail.fm> wrote:
> Correct, you can't just cast Integer to Double and have it work. Which is
> why I think it is strange that you *can* cast int to double and have it
> work and worse yet, Java will do it automatically. Why is the object
> behavior different than the primitive behavior?

Because they're there for different reasons. The wrappers are meant to
be there in place of *exact* types, without notions of hierarchy, I
believe - but that's just off the top of my head. There's also the
problem of multiple inheritence here - Double would have to derive from
both Float and Integer, and neither Float nor Integer can derive from
each other.

> If Integer is an object
> wrapper for int and Double is an object wrapper for double, why can't you
> directly cast Integer to Double if you can directly cast int to double?

See above - but maybe if we had MI, it *would* be done that way. There
are probably better reasons I just can't think of though :)

btw, I thought of a way round your problem - just explicitly include
the classname:

TestCase.assertEquals (3, 4) can't match the subclass's method.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too
Re: Compile bug in Eclipse 2.1? [message #28778 is a reply to message #28746] Thu, 08 May 2003 09:34 Go to previous message
Eclipse UserFriend
Originally posted by: eclipse.wingspread.fastmail.fm

On Thu, 8 May 2003 08:19:01 +0100, Jon Skeet <skeet@pobox.com> wrote:

> James Howe <eclipse@wingspread.fastmail.fm> wrote:
> >[...]
>
> btw, I thought of a way round your problem - just explicitly include the
> classname:
>
> TestCase.assertEquals (3, 4) can't match the subclass's method.
>

Thanks. I hadn't thought of that.

--
James Howe
Previous Topic:Any good HOWTO on formatting java code from a plugin
Next Topic:Adding libraries to a plugin
Goto Forum:
  


Current Time: Thu Oct 23 03:21:48 EDT 2025

Powered by FUDForum. Page generated in 0.06345 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top