SWI-Prolog / issues

Dummy repository for issue tracking
7 stars 3 forks source link

jpl_new syntax for nested classes is highly awkward #6

Open timobaumann opened 9 years ago

timobaumann commented 9 years ago

JPL does not name nested (static) classes the way that Java does. As expected,

?- jpl_new('java.awt.geom.GeneralPath', [], P).
P = @'J#00000000000034949976'.

but

?- jpl_new('java.awt.geom.Path2D.Float', [], P).
ERROR: Java exception: java.lang.NoClassDefFoundError: java/awt/geom/Path2D/Float

(Path2D is an abstract class which has two inner classes (Float and Double), and GeneralPath extends Path2D.Float but is defined in its own .java/.class file.)

It is possible to create an instance of a nested (static) class by calling

?- jpl_new('java.awt.geom.Path2D$Float', [], P).
P = @'J#00000140300878088832'.

presumably because that's the name of the class file (java/awt/geom/Path2D$Float.class). It would certainly be nicer to be able to use the Java class-naming convention rather than rely on how javac stores class definitions in the filesystem. In any case, it's not well documented and non-obvious.

sebgod commented 9 years ago

The Java language might use the dot uniformly, but as you know the JVM does use the $. As the JPL is technically only bound to the JVM and not Java, you willl observe the differences here. It is the same when programming in JNI, where you must use the classloader and method signatures used in the JVM as well. It would be far from trivial to replicate the behaviour of the Java language to the JPL plugin from my perspective.

timobaumann commented 9 years ago

Well, maybe the bug is just in the documentation of JPL. It's simply not clear to most JPL users what has happened when they get the NoClassDefFoundError and will not find the solution.

JanWielemaker commented 4 years ago

This issue has been mentioned on SWI-Prolog. There might be relevant details there:

https://swi-prolog.discourse.group/t/jpl-guru-needed-jpl-throws-when-calling-a-method-on-an-interface/2400/6

ghost commented 4 years ago

The problem is from just looking at the Java program name, you don’t know where you need to replace dots by $. This needs some algorithm relative to the class path.

I got such a prototypical algorithm in my system. It doesn’t need to know the insides of a compilable unit, and thus tolerates misspelling of inner classes:

?- absolute_file_name(foreign(java/awt/geom/'Path2D'/'Float'), X).
X = 'java/awt/geom/Path2D.class$Float'
?- absolute_file_name(foreign(java/awt/geom/'Path2D'/'Foo'), X).
X = 'java/awt/geom/Path2D.class$Foo'

But I am not sure whether its a fast one. It inserts unorthodoxically .class and replaces dots by / where the compilable unit starts, so that I can look at it as if it were a file name.

JanWielemaker commented 4 years ago

This issue has been mentioned on SWI-Prolog. There might be relevant details there:

https://swi-prolog.discourse.group/t/jpl-guru-needed-jpl-throws-when-calling-a-method-on-an-interface/2400/8