bugGNU Octave - Bugs: bug #51804, java-9: java.base/java.lang.Double...

 
 

bug #51804: java-9: java.base/java.lang.Double cannot be cast to java.base/java.lang.Integer

Submitter:  Dmitri A. Sergatskov <dasergatskov>
Submitted:  Sun 20 Aug 2017 06:22:45 PM UTC
   
 
Category:  Test Suite Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Unexpected Error or Warning
Status:  Need Info Assigned to:  None
Originator Name:  Open/Closed:  * Open
Release:  * dev Operating System:  * GNU/Linux
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Sat 10 Oct 2020 04:00:42 PM UTC, comment #16: 

I added this bug number to that BIST here:
https://hg.savannah.gnu.org/hgweb/octave/rev/a2fbb2074436

Markus Mützel <mmuetzel>
Group administrator
Fri 09 Oct 2020 08:41:45 PM UTC, comment #15: 

With java 14 and 15 I now get:


 test libinterp/octave-value/ov-java.cc-tst
***** testif HAVE_JAVA; usejava ("jvm")
 n = javaObject ("java.lang.Float", 1.35);
 assert (n.compareTo (1.0), 1);
 assert (n.compareTo (1.35), 0);
 assert (n.compareTo (10), -1);
 assert (n.doubleValue (), 1.35, 1e7);
!!!!! test failed
[java] java.lang.ClassCastException: class java.lang.Double cannot be cast to class java.lang.Float (java.lang.Double and java.lang.Float are in module java.base of loader 'bootstrap')


Also:


octave:9> n = javaObject ("java.lang.Float", 1.35)
n =

<Java object: java.lang.Float>

octave:10> m = methods (n, '-full')
m =
{
  [1,1] = Float(java.lang.String) throws java.lang.NumberFormatException
  [2,1] = Float(double)
  [3,1] = Float(float)
  [4,1] = boolean equals(java.lang.Object)
  [5,1] = java.lang.String toString(float)
  [6,1] = java.lang.String toString()
  [7,1] = int hashCode()
  [8,1] = int hashCode(float)
  [9,1] = float min(float, float)
  [10,1] = float max(float, float)
  [11,1] = int floatToRawIntBits(float)
  [12,1] = int floatToIntBits(float)
  [13,1] = float intBitsToFloat(int)
  [14,1] = int compareTo(java.lang.Object)
  [15,1] = int compareTo(java.lang.Float)
  [16,1] = byte byteValue()
  [17,1] = short shortValue()
  [18,1] = int intValue()
  [19,1] = long longValue()
  [20,1] = float floatValue()
  [21,1] = double doubleValue()
  [22,1] = java.lang.Float valueOf(float)
  [23,1] = java.lang.Float valueOf(java.lang.String) throws java.lang.NumberFormatException
  [24,1] = java.lang.String toHexString(float)
  [25,1] = int compare(float, float)
  [26,1] = java.lang.Object resolveConstantDesc(java.lang.invoke.MethodHandles.Lookup) throws java.lang.ReflectiveOperationException
  [27,1] = java.lang.Float resolveConstantDesc(java.lang.invoke.MethodHandles.Lookup)
  [28,1] = java.util.Optional describeConstable()
  [29,1] = boolean isNaN(float)
  [30,1] = boolean isNaN()
  [31,1] = float parseFloat(java.lang.String) throws java.lang.NumberFormatException
  [32,1] = boolean isInfinite()
  [33,1] = boolean isInfinite(float)
  [34,1] = boolean isFinite(float)
  [35,1] = float sum(float, float)
  [36,1] = void wait(long, int) throws java.lang.InterruptedException
  [37,1] = void wait() throws java.lang.InterruptedException
  [38,1] = void wait(long) throws java.lang.InterruptedException
  [39,1] = java.lang.Class getClass()
  [40,1] = void notify()
  [41,1] = void notifyAll()
}


Should we change this test FAIL to XFAIL?

Dmitri.
--


Dmitri A. Sergatskov <dasergatskov>
Thu 19 Jul 2018 06:39:59 AM UTC, comment #14: 


> It's not documented, I can only guess that the Comparable<T> interface also defines a compareTo(Object) method that internally tries to cast the object to type T.


Basically, yes: That "compareTo(Object)" method is a "bridge method" implicitly synthesized by the Java compiler to support the "type erasure" mechanism of Java generics. Internally, it'll do the cast and pass the call on to the specialized "compareObject(Integer)" that the java.lang.Integer source code actually defines. See http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#FAQ102 if you care about the details.

You can see the details using "javap" to disassemble the class files in the JRE's `rt.jar` if you're curious. Here's what `compareTo(Object)` looks like in JDK 8:


  public int compareTo(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #1                  // class java/lang/Integer
       5: invokevirtual #96                 // Method compareTo:(Ljava/lang/Integer;)I
       8: ireturn


I don't think you can rely on the ordering of the Java methods coming back from java.lang.Class's Reflection methods like getMethods() and getDeclaredMethods(). That's implementation-dependent. And it looks like the implementation-dependent ordering changed between JVM versions here.

From the documentation for java.lang.Class.getMethods :

> The elements in the returned array are not sorted and are not in any particular order.


You'll need to sort the methods by degree of specialization or matching to the input types to determine what sort of conversion to do and which method to call. Non-trivial.

Andrew Janke <apjanke>
Tue 24 Apr 2018 05:34:58 PM UTC, comment #13: 

In bug #53728, this same conversion error was reported for the Oracle Java 7 runtime, but with Short instead of Integer.

Mike Miller <mtmiller>
Group Member
Thu 22 Mar 2018 11:36:36 PM UTC, comment #12: 

I get pretty much the same with dev branch (47f25e164ab1):


octave:1> test libinterp/octave-value/ov-java.cc-tst
***** testif HAVE_JAVA; usejava ("jvm") <51804>
 n = javaObject ("java.lang.Integer", 1.35);
 assert (n.compareTo (0), 1);
 assert (n.compareTo (1), 0);
 assert (n.compareTo (2), -1);
!!!!! known bug: http://octave.org/testfailure/?51804
[java] java.lang.ClassCastException: java.base/java.lang.Double cannot be cast to java.base/java.lang.Integer
PASSES 15 out of 16 tests (1 known bug)
octave:2> n = javaObject ("java.lang.Integer", 1.35)
n =

<Java object: java.lang.Integer>

octave:3> assert (n.compareTo (0), 1)
error: [java] java.lang.ClassCastException: java.base/java.lang.Double cannot be cast to java.base/java.lang.Integer
octave:3> __octave_config_info__ ("hg_id")
ans = 47f25e164ab1
octave:4> frame = javaObject ("java.awt.Frame");
octave:5>


So it looks to me the difference is due to java version (revision).

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Thu 22 Mar 2018 11:18:41 PM UTC, comment #11: 

Is this with dev or with stable branch?

I can get fedora buildbots to build with java-9 as well (all I have to do is set JAVA_HOME) is this is of more interest.



Dmitri.

Dmitri A. Sergatskov <dasergatskov>
Thu 22 Mar 2018 11:16:22 PM UTC, comment #10: 

I just updated my buildbot to Java 9

http://buildbot.octave.org:8010/builders/gcc-6-debian/builds/1475/steps/test/logs/stdio

I get a different test failure, that is bug #53428.

But the test that used to fail for me now passes.


$ ./run-octave -q
>> n = javaObject ("java.lang.Integer", 1.35)
>> assert (n.compareTo (0), 1)
>> assert (n.compareTo (0), 1)
>> assert (n.compareTo (2), -1)


no errors.

Mike Miller <mtmiller>
Group Member
Thu 22 Mar 2018 11:10:00 PM UTC, comment #9: 

I still am getting this error with stable


octave:1> n = javaObject ("java.lang.Integer", 1.35)
n =

<Java object: java.lang.Integer>

octave:2> assert (n.compareTo (0), 1)
error: [java] java.lang.ClassCastException: java.base/java.lang.Double cannot be cast to java.base/java.lang.Integer
octave:2> __octave_config_info__ ("hg_id")
ans = 2b040946dc69


java-9-openjdk-9.0.4.11-4.fc27.x86_64

(so it also Xfails make check):


test libinterp/octave-value/ov-java.cc-tst
***** testif HAVE_JAVA; usejava ("jvm") <51804>
 n = javaObject ("java.lang.Integer", 1.35);
 assert (n.compareTo (0), 1);
 assert (n.compareTo (1), 0);
 assert (n.compareTo (2), -1);
!!!!! known bug: http://octave.org/testfailure/?51804
[java] java.lang.ClassCastException: java.base/java.lang.Double cannot be cast to java.base/java.lang.Integer
PASSES 15 out of 16 tests (1 known bug)
-verbaim-

Fedora buildbots still use java-8.

Dmitri.

Dmitri A. Sergatskov <dasergatskov>
Thu 22 Mar 2018 07:12:18 PM UTC, comment #8: 

I can't reproduce this test failure anymore with the version of Java 9 in Debian unstable (9.0.4+12-Debian-2).

Dmitri, is this error still occurring for you on Fedora with your version of Java?

Mike Miller <mtmiller>
Group Member
Sun 20 Aug 2017 09:12:58 PM UTC, comment #7: 

It's not documented, I can only guess that the Comparable<T> interface also defines a compareTo(Object) method that internally tries to cast the object to type T.

Mike Miller <mtmiller>
Group Member
Sun 20 Aug 2017 08:59:59 PM UTC, comment #6: 

Ok, this may be the problem


x = javaObject ("java.lang.Integer", 0)
methods (x)


With Java 8, the list contains


  [1,13] = int compareTo(java.lang.Integer)
  [1,14] = int compareTo(java.lang.Object)


in that order. So when Octave iterates through the available methods, it finds the Integer one first, and everything works as expected. With Java 9, I get the following


  [1,13] = int compareTo(java.lang.Object)
  [1,14] = int compareTo(java.lang.Integer)


in the opposite order. Octave finds the one that takes an Object first, assumes that that should work when given a double-valued argument, and calls it. If that method actually exists and works, then this should work. But it's like Java is reporting that this compareTo(Object) method exists, but when it's called it is actually calling the one that takes an Integer.

Mike Miller <mtmiller>
Group Member
Sun 20 Aug 2017 08:45:39 PM UTC, comment #5: 

I don't see any difference in the API, both Java 8 and 9 say that java.lang.Integer.compareTo takes java.lang.Integer as an argument. However, when Octave is inspecting the runtime for the method "compareTo", the result says that it takes an argument of type java.lang.Object, not Integer. Octave doesn't do any casting because it doesn't think it has to, but then when the method is called the exception is thrown.

Someone might want to look into the Java 9 runtime in more detail and find out why this is happening. I think it will take writing some Java code to iterate over the available methods in the Integer class and see what's different.

Mike Miller <mtmiller>
Group Member
Sun 20 Aug 2017 06:37:59 PM UTC, comment #4: 

Sorry -- the comments 1 and 2 crossed over in the ether.
I am looking at

https://docs.oracle.com/javase/9/whatsnew/toc.htm#JSNEW-GUID-0CA9D45F-31BE-4C5A-B85D-8A638B687617


but so far have not seen any relevant info.
I guess it could be a bug in the RC.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Sun 20 Aug 2017 06:30:04 PM UTC, comment #3: 

Sure, but I'd rather understand why the call isn't working the way it is.

In Java 9 I can construct an Integer with a double, and I can call compareTo with a double argument. I would like to know where Java 9 has changed something so that that is no longer possible. Particularly since Java 9 isn't actually released yet.

Mike Miller <mtmiller>
Group Member
Sun 20 Aug 2017 06:27:42 PM UTC, comment #2: 

Changing "assert(...)" call to:


assert (n.compareTo (int32(0)), 1)


makes it pass
(those are failing test in libinterp/octave-value/ov-java.cc-tst)

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Sun 20 Aug 2017 06:26:16 PM UTC, comment #1: 

I saw this also when trying to build with Java 9. Do you know where the relevant change in the Java 9 API is?

Mike Miller <mtmiller>
Group Member
Sun 20 Aug 2017 06:22:45 PM UTC, original submission:  

dev version compiled against java-9
(java-9-openjdk-9.0.0.181-1)

octave:1> n = javaObject ("java.lang.Integer", 1.35)
n =

<Java object: java.lang.Integer>

octave:2> assert (n.compareTo (0), 1)
error: [java] java.lang.ClassCastException: java.base/java.lang.Double cannot be cast to java.base/java.lang.Integer


Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Carbon-Copy List
  • -email is unavailable- added by mmuetzel (Posted a comment)
  • -email is unavailable- added by apjanke (Posted a comment)
  • -email is unavailable- added by dasergatskov (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 7 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2020-11-19 mtmiller Carbon-CopyRemoved 80942 -
    2020-10-09 mmuetzel Dependencies- bugs #59244 is dependent
    2020-09-09 mmuetzel Dependencies- bugs #59088 is dependent
    2020-01-17 mtmiller Dependencies- bugs #57619 is dependent
    2018-04-24 mtmiller Dependencies- bugs #53728 is dependent
    2017-08-20 mtmiller Item GroupNone Unexpected Error or Warning
        StatusNone Need Info

    Back to the top

    Powered by Savane 3.13-4448.
    Corresponding source code