This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-11-16
Channels
- # aleph (3)
- # announcements (14)
- # babashka (16)
- # beginners (85)
- # calva (6)
- # cider (9)
- # clojure (42)
- # clojure-australia (8)
- # clojure-europe (30)
- # clojure-nl (4)
- # clojure-uk (29)
- # clojuredesign-podcast (7)
- # clojurescript (25)
- # cursive (4)
- # data-science (1)
- # datomic (31)
- # emacs (1)
- # events (1)
- # fulcro (16)
- # instaparse (2)
- # java (37)
- # kaocha (3)
- # malli (3)
- # meander (19)
- # membrane (7)
- # off-topic (13)
- # pathom (4)
- # pedestal (10)
- # re-frame (17)
- # reveal (3)
- # rewrite-clj (1)
- # ring (9)
- # shadow-cljs (17)
- # spacemacs (2)
- # sql (34)
- # tools-deps (88)
- # vim (4)
Hi everybody!
I tried to figurate out to how interop with java-dbus
library.
Which options Clojure offers for converting this Java snippet to Clojure:
import org.freedesktop.dbus.DBusInterface;
public class DBusHelloWorldServer implements DBusInterface {
...
dbusConnection.exportObject("/Main", this);
...
}
I toying with Reify, Proxy but I can't figure out how to create the object to put at the exportObject
method second argument.
reify methods all take "this" as the first argument
(reify DBusInterface (some-method [this conn] (.exportObject conn "/Main" this)))
no reason to use proxy here afaict
Here the doc: https://dbus.freedesktop.org/doc/dbus-java/api/org/freedesktop/dbus/AbstractConnection.html#exportObject(java.lang.String,%20org.freedesktop.dbus.DBusInterface) The second parameter must be the DBusInterface object.
Thx @alexmiller for the confirmation! I'm starting to see more clearly how to do it.
if you want to utilize extending from AbstractConnection, that's where you'd need a proxy
I put all the java code here for the context:
package hello;
import org.freedesktop.dbus.DBusInterface;
import org.freedesktop.dbus.DBusConnection;
import org.freedesktop.dbus.exceptions.DBusException;
public class DBusHelloWorldServer implements DBusInterface
{
private DBusConnection dbusConnection;
public boolean isRemote()
{
return false;
}
private boolean stop=false;
public String helloWorld(String name)
{
stop=true;
return "Hello World : "+name;
}
public void start()
{
try
{
dbusConnection = DBusConnection.getConnection(DBusConnection.SESSION);
dbusConnection.requestBusName("mon.premier.bus");
dbusConnection.exportObject("/Main", this);
while (!stop)
{
try {
Thread.sleep(1000);
} catch (Exception e) {}
}
dbusConnection.disconnect();
}
catch (DBusException e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
new DBusHelloWorldServer().start();
}
}
given that you have state (the stop field), I'd probably make a deftype that implemented DBusInterface
For the moment, I struggle with this interop code which of course does not work and gives me an error on the object to pass as argument:
(ns main.core
(:import (org.freedesktop.dbus DBusConnection DBusInterface)))
(defn start []
(let [dbus-conn (. DBusConnection getConnection DBusConnection/SESSION)
dbus-hello-world-server (reify DBusInterface
(isRemote [this] false))]
(doto dbus-conn
(.requestBusName "mon.premier.bus")
(.exportObject "/Main" dbus-hello-world-server))))
(defn -main []
(start))
is this file the scope of what you're doing? making a main that starts an instance of the server?
who actually calls helloWorld() ?
Yes, I updated the snippet above with all the namespace.
And the ouput error: Execution error (DBusException) at org.freedesktop.dbus.Marshalling/recursiveGetDBusType (Marshalling.java:241). Exporting non-exportable type interface clojure.lang.IPersistentMap
For the moment, in the Clojure version, my test to interop helloWorld() was unsuccessful.
there's more going on here under the hood of that exportObject
As I understand, DBusInterface contains one method isRemote and with reify it's not possible to adding one, right?
what does exporting do?
I assume it's making some assumptions about the object being exported that presumably Clojure is not meeting, but the docs don't say anything useful that I saw
@alexmiller thank you for the time you take:+1:
This is my first tests with the interop and I think I did not take the easiest haha
sounds like it's using java reflection on the object to map methods, which might run into some troubles
and it's expecting a known set of types
there may be some path through this but I suspect you'll need to understand what export does more deeply
hard for me to say what is most likely to work
> what does exporting do? Do you mean, we should look at the source code?
Maybe it can help, client side I use this dbus-send cli to talk with the server:
dbus-send --print-reply --dest='mon.premier.bus' /Main mon.premier.bus.helloWorld string:'Mike'
my impression is that export-object will inspect the Java object using reflection, find its methods and make them available to call
it's most likely finding stuff you don't want (and there is no actual method that you do want yet)
so reify is probably not the answer - you'll most likely need gen-class to generate the class with the methods you want to call, but you might also need to use definterface or gen-interface to construct the interface that instance implements
understanding exactly what export-object does would help guide that
@alexmiller I found a maintained dbus-java lib with good doc: https://github.com/hypfvieh/dbus-java/blob/e238251aed3414cb39e6ee97aff6cd57e147ab42/src/site/markdown/exporting-objects.md
not sure I can be any more help on this atm
You have already helped / guided me well, that's perfect. Thanks again Alex.