java

2020-11-16T19:06:18.056100Z

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);
     ...
}

2020-11-16T19:12:39.058100Z

I toying with Reify, Proxy but I can't figure out how to create the object to put at the exportObject method second argument.

alexmiller 2020-11-16T19:15:00.059100Z

reify methods all take "this" as the first argument

alexmiller 2020-11-16T19:15:42.059900Z

(reify DBusInterface (some-method [this conn] (.exportObject conn "/Main" this)))

👍 1
alexmiller 2020-11-16T19:16:12.060300Z

no reason to use proxy here afaict

2020-11-16T19:19:51.061400Z

Thx @alexmiller for the confirmation! I'm starting to see more clearly how to do it.

alexmiller 2020-11-16T19:24:11.062Z

if you want to utilize extending from AbstractConnection, that's where you'd need a proxy

👍 1
2020-11-16T19:28:57.062800Z

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();
    }
}

alexmiller 2020-11-16T19:31:19.063700Z

given that you have state (the stop field), I'd probably make a deftype that implemented DBusInterface

2020-11-16T19:33:08.065200Z

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))

alexmiller 2020-11-16T19:40:16.066Z

is this file the scope of what you're doing? making a main that starts an instance of the server?

alexmiller 2020-11-16T19:44:27.066600Z

who actually calls helloWorld() ?

2020-11-16T19:45:48.067600Z

Yes, I updated the snippet above with all the namespace.

2020-11-16T19:46:46.068300Z

And the ouput error: Execution error (DBusException) at org.freedesktop.dbus.Marshalling/recursiveGetDBusType (Marshalling.java:241). Exporting non-exportable type interface clojure.lang.IPersistentMap

2020-11-16T19:49:03.069700Z

For the moment, in the Clojure version, my test to interop helloWorld() was unsuccessful.

alexmiller 2020-11-16T19:49:47.070600Z

there's more going on here under the hood of that exportObject

2020-11-16T19:51:10.071600Z

As I understand, DBusInterface contains one method isRemote and with reify it's not possible to adding one, right?

alexmiller 2020-11-16T19:51:17.071800Z

right

alexmiller 2020-11-16T19:51:21.072Z

what does exporting do?

alexmiller 2020-11-16T19:51:59.072700Z

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

2020-11-16T19:54:53.073Z

@alexmiller thank you for the time you take:+1:

2020-11-16T19:54:58.073200Z

This is my first tests with the interop and I think I did not take the easiest haha

alexmiller 2020-11-16T19:56:56.074100Z

sounds like it's using java reflection on the object to map methods, which might run into some troubles

alexmiller 2020-11-16T19:58:00.074600Z

and it's expecting a known set of types

alexmiller 2020-11-16T19:58:38.075100Z

there may be some path through this but I suspect you'll need to understand what export does more deeply

alexmiller 2020-11-16T19:59:05.075400Z

hard for me to say what is most likely to work

2020-11-16T20:00:56.075900Z

> what does exporting do? Do you mean, we should look at the source code?

2020-11-16T20:02:54.077200Z

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'

alexmiller 2020-11-16T20:04:50.078Z

my impression is that export-object will inspect the Java object using reflection, find its methods and make them available to call

alexmiller 2020-11-16T20:05:16.078500Z

it's most likely finding stuff you don't want (and there is no actual method that you do want yet)

alexmiller 2020-11-16T20:06:10.079500Z

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

alexmiller 2020-11-16T20:06:29.079900Z

understanding exactly what export-object does would help guide that

alexmiller 2020-11-16T20:06:44.080200Z

not sure I can be any more help on this atm

2020-11-16T20:09:40.080600Z

You have already helped / guided me well, that's perfect. Thanks again Alex.