Re: [Py4j-users] How can I pass a List<short> or List<byte> from Python to Java?
Status: Beta
Brought to you by:
barthe
From: Dan O'R. <ore...@gm...> - 2015-07-15 16:17:27
|
Thanks for the quick response, Barthelemy! For now I'll pursue the shim route, but I'll keep an eye out of #163 to be resolved. On Tue, Jul 14, 2015 at 8:25 PM Barthelemy Dagenais <bar...@in...> wrote: > After some investigation, there is no easy or quick solution because of > the difference in the type systems and the autoboxing behavior of Java. > From a design perspective, I'm pretty sure converting primitives such as > short to Python int is saner than trying to track the original primitive > type. Preventing primitive wrapper (such as Byte and Short) from being > converted to Python int though makes a lot of sense, but requires a few non > trivial changes. > > It's doable and I have a plan, but it won't be available before a few > weeks, so your best bet on the short term is to rely on a Java shim or a > third party library. > > Link to Github issue for reference: > https://github.com/bartdag/py4j/issues/163 > > Barthelemy > > On Tue, Jul 14, 2015 at 2:26 PM Dan O'Reilly <ore...@gm...> wrote: > >> It seems that on the Python side, Py4J will automatically convert the >> java type short (and byte) to the Python type int, which means there's no >> way to pass a List<short> from Python to Java. Consider this example: >> >> import java.util.List; >> >> import py4j.GatewayServer; >> >> class Test { >> >> public void testByte(List<Byte> l) { >> Byte i = l.get(0); >> } >> >> public static void main(String[] args) { >> GatewayServer gw = new GatewayServer(new Test()); >> gw.start(); >> System.out.println("GatewayServer started..."); >> } >> } >> >> If I try to call testByte from the Python side, I seem to get an >> ClassCastException no matter what I try: >> >> >>> gw = JavaGateway() >> >>> z = ListConverter().convert([1,2], gw._gateway_client) >> >>> gw.entry_point.testByte(z) >> Traceback (most recent call last): >> File "<stdin>", line 1, in <module> >> File "/usr/local/lib/python2.7/dist-packages/py4j/java_gateway.py", >> line 538, in __call__ >> self.target_id, self.name) >> File "/usr/local/lib/python2.7/dist-packages/py4j/protocol.py", line >> 300, in get_return_value >> format(target_id, '.', name), value) >> py4j.protocol.Py4JJavaError: An error occurred while calling t.testByte. >> : java.lang.ClassCastException: java.lang.Integer cannot be cast to >> java.lang.Byte >> at Test.testByte(Test.java:8) >> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >> at >> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) >> at >> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) >> at java.lang.reflect.Method.invoke(Method.java:497) >> at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:231) >> at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:379) >> at py4j.Gateway.invoke(Gateway.java:259) >> at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:133) >> at py4j.commands.CallCommand.execute(CallCommand.java:79) >> at py4j.GatewayConnection.run(GatewayConnection.java:207) >> at java.lang.Thread.run(Thread.java:745) >> >> >> >>> z = >> ListConverter().convert([gw.jvm.java.lang.Byte(1),gw.jvm.java.lang.Byte(2)], >> gw._gateway_client) >> >>> gw.entry_point.testByte(z) >> Traceback (most recent call last): >> File "<stdin>", line 1, in <module> >> File "/usr/local/lib/python2.7/dist-packages/py4j/java_gateway.py", >> line 538, in __call__ >> self.target_id, self.name) >> File "/usr/local/lib/python2.7/dist-packages/py4j/protocol.py", line >> 300, in get_return_value >> format(target_id, '.', name), value) >> py4j.protocol.Py4JJavaError: An error occurred while calling t.testByte. >> : java.lang.ClassCastException: java.lang.Integer cannot be cast to >> java.lang.Byte >> at Test.testByte(Test.java:8) >> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >> at >> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) >> at >> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) >> at java.lang.reflect.Method.invoke(Method.java:497) >> at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:231) >> at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:379) >> at py4j.Gateway.invoke(Gateway.java:259) >> at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:133) >> at py4j.commands.CallCommand.execute(CallCommand.java:79) >> at py4j.GatewayConnection.run(GatewayConnection.java:207) >> at java.lang.Thread.run(Thread.java:745) >> >> Is there some way to work around this? Ideally there would be away >> without having to make changes on the Java-side, since for my actual >> use-case I'm trying to call into an API I don't control. I could probably >> make things work if I needed to call a Java shim instead, but I'd really >> like to avoid that. >> >> Thanks, >> Dan O'Reilly >> >> >> ------------------------------------------------------------------------------ >> Don't Limit Your Business. Reach for the Cloud. >> GigeNET's Cloud Solutions provide you with the tools and support that >> you need to offload your IT needs and focus on growing your business. >> Configured For All Businesses. Start Your Cloud Today. >> https://www.gigenetcloud.com/ >> _______________________________________________ >> Py4j-users mailing list >> Py4...@li... >> https://lists.sourceforge.net/lists/listinfo/py4j-users >> > > ------------------------------------------------------------------------------ > Don't Limit Your Business. Reach for the Cloud. > GigeNET's Cloud Solutions provide you with the tools and support that > you need to offload your IT needs and focus on growing your business. > Configured For All Businesses. Start Your Cloud Today. > https://www.gigenetcloud.com/ > _______________________________________________ > Py4j-users mailing list > Py4...@li... > https://lists.sourceforge.net/lists/listinfo/py4j-users > |