I have been poking the JPL interface a bit, using Adopt OpenJKD 14 underneath.
A simple trial with a java.lang.String
object (which is Prologified into an atom automatically) and a java.util.GregorianCalendar
(which stays a Java Object referenced through a jref
) work well and out of the box once you have set your environment variables.
So I wanted to do something slightly more interesting and connect to libreoffice, trasncribing the simplest exercise possible:
public class FirstUnoContact {
public static void main(String[] args) {
try {
// get the remote office component context
com.sun.star.uno.XComponentContext xContext =
com.sun.star.comp.helper.Bootstrap.bootstrap();
System.out.println("Connected to a running office ...");
com.sun.star.lang.XMultiComponentFactory xMCF =
xContext.getServiceManager();
String available = (xMCF != null ? "available" : "not available");
System.out.println( "remote ServiceManager is " + available );
System.out.println();
}
catch (java.lang.Exception e){
e.printStackTrace();
}
finally {
System.exit(0);
}
}
}
So here it is (well, not yet fully complete):
first_uno_contact :-
use_module(library(jpl)), % SWI-Prolog: use_module/1 in predicate role, as the God of Logic Programming intended
% XComponentContext is an interface!
% Java: com.sun.star.uno.XComponentContext xContext = com.sun.star.comp.helper.Bootstrap.bootstrap();
jpl_call('com.sun.star.comp.helper.Bootstrap','bootstrap',[],XContext),
format("Connected to a running office with XContext = ~q\n",[XContext]),
(jpl_is_object(XContext) -> format("XContext is an object\n") ; format("XContext is NOT an object\n")),
write_class_inheritance_path_of_object(XContext),
% Java: com.sun.star.lang.XMultiComponentFactory xMCF = xContext.getServiceManager();
jpl_call(XContext,'getServiceManager',[],_XMcf). % THIS THROWS
write_class_inheritance_path_of_object(JObj) :-
assertion(jpl_is_object(JObj)),
jpl_object_to_class(JObj, JClass),
format("Object is of Class ~q\n",[JClass]),
write_class_inheritance_path(JClass).
write_class_inheritance_path(JX) :-
assertion(jpl_is_object(JX)), % it's an object
assertion((jpl_object_to_class(JX,JXClass),jpl_class_to_classname(JXClass,'java.lang.Class'))), % of type java.lang.Class
jpl_class_to_classname(JX, ClassName),
format("Class ~q has name ~q\n",[JX,ClassName]),
jpl_call(JX,'getSuperclass',[],JSuperClass),
(jpl_null(JSuperClass)
->
true
;
(format("Class ~q has superclass ~q\n",[JX,JSuperClass]),
write_class_inheritance_path(JSuperClass))).
When you run this, you get:
?- first_uno_contact.
Connected to a running office with XContext = <jref>(0x27c7330)
XContext is an object
Object is of Class <jref>(0x2602720)
Class <jref>(0x2602720) has name 'com.sun.proxy.$Proxy1'
Class <jref>(0x2602720) has superclass <jref>(0x27c7338)
Class <jref>(0x27c7338) has name 'java.lang.reflect.Proxy'
Class <jref>(0x27c7338) has superclass <jref>(0x2602710)
Class <jref>(0x2602710) has name 'java.lang.Object'
ERROR: Domain error: `object_or_class' expected, found `<jref>(0x27c7330)' (1st arg must be an object, classname, descriptor or type)
So, JPL says that
- the reference to the object
<jref>(0x27c7330)
- which implements
com.sun.star.uno.XComponentContext
(which is a Java interface, see here), - and is of actual class
com.sun.proxy.$Proxy1
, which is an object constructed at runtime
cannot be recognized as an object? Maybe? Is there something trivial I am overlooking?
(These exercise sometimes get you entangled in a basket of concepts … obejct, class, runtime, not runtime … then you remember, its all just text and text transformations and text retrieval, syntactic machines, nothing so see here, and you go on!)