#67 number overflow (Linux only) when passing long

open
5
2010-01-18
2010-01-18
Anonymous
No

The attached test passes fails on Linux (ubuntu) and passes on Windows. We use python 2.6 and Jpype 0.5.4.

We calculate a large integer value in python, then pass this into the java.util.Date(long millis) constructor. On Windows, the correct date is constructed, on Linux the long value overflows to a negative value, constructing the wrong date.

We have a work around: formatting the date in Python then parsing the String in Java, with the implied overhead.

import unittest
import datetime
import jpype

class JpypeKdbTests(unittest.TestCase):
def test_javadate(self):
jpype.startJVM(jpype.getDefaultJVMPath())
param = datetime.date(2007,1,1)

## note millis needs to be passed in as a java 'long'
daysSince1970 = param.toordinal() - 719163
millis = daysSince1970 * 1000*60*60*24
print '\n'
print millis

## should print 'Mon Jan 01 00:00:00 GMT 2007'
jdate = jpype.java.util.Date(millis)
print jdate.getTime()
print jdate

## try formatting in Java
df = jpype.java.text.SimpleDateFormat('yyyy-MM-dd')
df.setTimeZone(jpype.java.util.TimeZone.getTimeZone('Europe/London'))
datestr = df.format(jpype.JObject(jdate, 'java.util.Date'))
print datestr
self.assertEqual('2007-01-01', datestr)

if __name__ == '__main__':
unittest.main()

Test results (Linux)
test_javadate (test_timeslinuxbug.JpypeKdbTests) ...
1167609600000
-621504512
Wed Dec 24 20:21:35 GMT 1969
1969-12-24
FAIL

Test results (Windows)
test_javadate (gsa.test_timeslinuxbug.JpypeKdbTests) ...
1167609600000
1167609600000
Mon Jan 01 00:00:00 GMT 2007
2007-01-01
ok

----------------------------------------------------------------------
Ran 1 test in 0.078s

Discussion

  • Comment has been marked as spam. 
    Undo

    You can see all pending comments posted by this user  here

    Anonymous - 2010-01-18

    test case

     
  • Comment has been marked as spam. 
    Undo

    You can see all pending comments posted by this user  here

    Anonymous - 2010-01-18
    • summary: number overflow, not passed as long --> number overflow (Linux only) when passing long
     
    Last edit: Anonymous 2013-05-05
  • Alexander Tyutyunnik

    I guess a simpler workaround would be:
    jdate = jpype.java.util.Date(long(millis))

    By the way, is your Linux 64 bit? I noticed that on all Unix 64 bit platforms (while Win 64 is fine).

    Here:
    bash-3.00$ python
    Python 2.5.1 (r251:54863, Oct 4 2007, 10:50:52) [C] on aix5
    Type "help", "copyright", "credits" or "license" for more information.
    >>> type(1167609600000)
    <type 'long'>
    >>>

    bash-3.00$ python64
    Python 2.5.1 (r251:54863, Oct 2 2007, 12:02:12) [C] on aix5
    Type "help", "copyright", "credits" or "license" for more information.
    >>> type(1167609600000)
    <type 'int'>
    >>>

    It looks to be a Python's problem, though JPype should handle this, too.

     
  • Alexander Tyutyunnik

    The following patch sort of makes it work:
    --- XEngine/src/java/JPype-0.5.2.1/src/native/common/jp_primitivetypes.cpp (revision 7205)
    +++ XEngine/src/java/JPype-0.5.2.1/src/native/common/jp_primitivetypes.cpp (working copy)
    @@ -464,7 +464,7 @@
    jvalue res;
    if (JPEnv::getHost()->isInt(obj))
    {
    - res.j = (jlong)JPEnv::getHost()->intAsInt(obj);
    + res.j = (jlong)JPEnv::getHost()->longAsLong(obj);
    }
    else if (JPEnv::getHost()->isLong(obj))
    {

     
  • Alexander Tyutyunnik

    The following fix might be better instead of the previous, since JPyInt::asLong() returns long rather than int.

    Index: src/native/python/py_hostenv.cpp

    --- src/native/python/py_hostenv.cpp (revision 7205)
    +++ src/native/python/py_hostenv.cpp (working copy)
    @@ -253,7 +253,7 @@
    return new HostRef(JPyInt::fromLong(v), false);
    }

    -jint PythonHostEnvironment::intAsInt(HostRef* res)
    +jlong PythonHostEnvironment::intAsInt(HostRef* res)
    {
    return JPyInt::asLong(UNWRAP(res));
    }
    Index: src/native/python/include/py_hostenv.h
    ===================================================================
    --- src/native/python/include/py_hostenv.h (revision 7205)
    +++ src/native/python/include/py_hostenv.h (working copy)
    @@ -105,7 +105,7 @@

    virtual bool isInt(HostRef*);
    virtual HostRef* newInt(jint);
    - virtual jint intAsInt(HostRef*);
    + virtual jlong intAsInt(HostRef*);

    virtual bool isLong(HostRef*);
    virtual HostRef* newLong(jlong);
    Index: src/native/common/include/jp_hostenv.h
    ===================================================================
    --- src/native/common/include/jp_hostenv.h (revision 7205)
    +++ src/native/common/include/jp_hostenv.h (working copy)
    @@ -85,7 +85,7 @@

    virtual bool isInt(HostRef*) = 0;
    virtual HostRef* newInt(jint) = 0;
    - virtual jint intAsInt(HostRef*) = 0;
    + virtual jlong intAsInt(HostRef*) = 0;

    virtual bool isLong(HostRef*) = 0;
    virtual HostRef* newLong(jlong) = 0;

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.





No, thanks