An error occurred while calling z:java.nio.file.Path.of. Method of([class java.lang.String]) does not exist

20 views
Skip to first unread message

Siddharth Jain

unread,
Nov 16, 2023, 5:39:32 PM11/16/23
to Py4J Support and Comments
hello

i am trying to create a Path object like this:

>>> gateway.jvm.java.nio.file.Path.of(file)

and get this error:

py4j.protocol.Py4JError: An error occurred while calling z:java.nio.file.Path.of. Trace:
py4j.Py4JException: Method of([class java.lang.String]) does not exist
at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:321)
at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:342)
at py4j.Gateway.invoke(Gateway.java:276)
at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)
at py4j.commands.CallCommand.execute(CallCommand.java:79)
at py4j.GatewayConnection.run(GatewayConnection.java:238)
at java.base/java.lang.Thread.run(Thread.java:1623)

for reference java.nio.file.Path.of(file) does work in Java and the method is documented here. So why is py4j complaining and how can I fix this? thanks.

Jonah Graham

unread,
Nov 16, 2023, 9:24:33 PM11/16/23
to py...@py4j.org
Hi,

The issue is that Path.of(String) method doesn't actually exist, your link was to Path.of(String, String...) which is syntactic sugar for a method with a signature of Path.of(String, String[]). So when you try to call Path.of(String) py4j correctly reports that there is no such method.

Therefore you need to pass an empty array as the second parameter like this:

>>> p = gateway.jvm.java.nio.file.Path.of("/tmp/my/../path", gateway.new_array(gateway.jvm.java.lang.String, 0))

And then you can call methods on p as expected.
>>> p.normalize().toString()
'/tmp/path'
>>> p.toString()
'/tmp/my/../path'


It follows that you can't do this either as there is no method with that signature either:

>>> p = gateway.jvm.java.nio.file.Path.of("/part1", "part2", "part3", "part4")

Instead do this:

>>> more = gateway.new_array(gateway.jvm.java.lang.String, 3)
>>> more[0] = "part2"
>>> more[1] = "part3"
>>> more[2] = "part4"
>>> p = gateway.jvm.java.nio.file.Path.of("/part1", more)
>>> p.toString()
'/part1/part2/part3/part4'



To slightly complicate matters, Java collections actually does have a List.of(E) method, and List.of(E, E), and List.of(E, E, E), etc and finally List.of(E[]). Which means you need to know a bit more details about the APIs when calling from Python than you would if you used Java directly:

>>> p = gateway.jvm.java.util.List.of("/part1", "part2", "part3", "part4")
>>> p.toString()
'[/part1, part2, part3, part4]'

But if you want to call the List.of(E[]) version you need to use an Object array:

>>> more = gateway.new_array(gateway.jvm.java.lang.Object, 3)
>>> more[0] = "part2"
>>> more[1] = "part3"
>>> more[2] = "part4"
>>> p = gateway.jvm.java.util.List.of(more)
>>> p.toString()
'[part2, part3, part4]'

HTH
Jonah



~~~
Jonah Graham (he/him)
Kichwa Coders
www.kichwacoders.com


--
You received this message because you are subscribed to the Google Groups "Py4J Support and Comments" group.
To unsubscribe from this group and stop receiving emails from it, send an email to py4j+uns...@py4j.org.
To view this discussion on the web visit https://groups.google.com/a/py4j.org/d/msgid/py4j/699be17d-66b3-4e4a-8a0b-cc7ba909600en%40py4j.org.
Reply all
Reply to author
Forward
0 new messages