Fork me on GitHub
#java
<
2020-11-17
>
emccue00:11:10

(gen-class
	:name "hello.DBusHelloWorldServer"
	:implements [DBusInterface]
	:state "state"
	:init "init"
    :methods [[helloWorld [String] void]
	:prefix "-")

(defn- -init []
  [[] (atom {::dbus-connection nil
             ::stop false})]

(defn- -isRemote [server]
  false)

(defn- -helloWorld [server name]
  (swap! (.state server) assoc ::stop true)
  (str "Hello World :" name))

(defn -start [server]
  (try 
    (let [dbus-connection (DBusConnection/getConnection DBusConnection/SESSION)]
      (.requestBusName "mon.premier.bus")
      (.exportObject "/Main" server)
      (while (not (::stop @(.state server))
        (try 
          (Thread/sleep 1000)
          (catch Exception e nil)))
        (.disconnect dbus-connection)))
    (catch DBusException e
      (.printStackTrace e))))

šŸ‘ 3
emccue00:11:20

@admin055 Thats a first stab at it

emccue00:11:42

this is admittedly one of the things clojure has trouble with

emccue00:11:56

since now you will have to add a build step to AOT compile this file

emccue00:11:12

and if you make changes you'll have to restart your repl

emccue00:11:39

but any time you need to make a method that isn't already on an interface you will run into gen-class

emccue00:11:03

you can sidestep that by making an interface for the methods like helloWorld

emccue00:11:32

but this is the direct translation of the java above, more or less

Michaƫl Salihi11:11:09

Thx @emccue for the help and for showing me the gen-class direction!

Michaƫl Salihi11:11:28

in your first draft, I don't see what to put for the server argument that the different functions take. I see swap and deref, so I should put server value in an atom..but how can I assoc the current class object who implements DBusInterface in it?

Michaƫl Salihi13:11:05

OK, I read the gen-class doc, the first param is the current object "this" as I understand. When I try to run start , I have this error:

user=> (def o (hello.DBusHelloWorldServer.))
#'user/o
user=> (.start o)
#object[hello.DBusHelloWorldServer 0x57e388c3 hello.DBusHelloWorldServer@57e388c3]
org.freedesktop.dbus.exceptions.DBusException: Exporting non-exportable type class java.lang.Object

Michaƫl Salihi13:11:20

Same error as with my tests with Reify. You can see the object on the REPL block above, I made a println.

Michaƫl Salihi15:11:04

Visibly the Clojure gen-class object return false when testing with isAssignableFrom

emccue16:11:24

> so I should put server value in an atom..but how can I assoc the current class object who implements DBusInterface in it?

emccue16:11:52

well, an atom is just one option, but here

emccue16:11:44

(defn -start [server]
  (try 
    (let [dbus-connection (DBusConnection/getConnection DBusConnection/SESSION)]
      (swap! (.state server) assoc ::dbus-connection dbus-connection)
      (.requestBusName "mon.premier.bus")
      (.exportObject "/Main" server)
      (while (not (::stop @(.state server))
        (try 
          (Thread/sleep 1000)
          (catch Exception e nil)))
        (.disconnect dbus-connection)))
    (catch DBusException e
      (.printStackTrace e))))

emccue16:11:50

you can swap it in

emccue16:11:06

and i might have named that kinda wierd

emccue16:11:16

(defn start [server]
  (try 
    (let [dbus-connection (DBusConnection/getConnection DBusConnection/SESSION)]
      (swap! (.state server) assoc ::dbus-connection dbus-connection)
      (.requestBusName "mon.premier.bus")
      (.exportObject "/Main" server)
      (while (not (::stop @(.state server))
        (try 
          (Thread/sleep 1000)
          (catch Exception e nil)))
        (.disconnect dbus-connection)))
    (catch DBusException e
      (.printStackTrace e))))

Michaƫl Salihi16:11:30

@emccue How can I run the start function?

emccue16:11:50

just like a normal function

emccue16:11:11

(def o (hello.DBusHelloWorldServer.))

emccue16:11:34

you need to be in the namespace where the function is or require it though

emccue16:11:53

so if you add a (require '[hello :refer :all]) to your repl session that works. You can also switch to the other ns after loading in the file (which will use in-ns but how to hot load is slightly dependent on your tool)

Michaƫl Salihi16:11:13

OK, thank you, I still have trouble thinking with interop šŸ™‚

Michaƫl Salihi16:11:34

I have always the same error:

emccue16:11:48

Honestly this is the absolute ugliest path with interop. It would maybe be more convenient to just write a java interface and implement in clojure

emccue16:11:06

okay so that wasn't an issue

emccue16:11:31

what does (ancestors hello.DBusHelloWorldServer) get you?

Michaƫl Salihi16:11:29

I get a set #{java.lang.Object org.freedesktop.dbus.DBusInterface}

Michaƫl Salihi16:11:48

@emccue Do you know how can I compare with the Java version? The ancestors object?

emccue17:11:29

ancestors can take any java class and give you that set

emccue17:11:05

so if you can compile and import your java version (in a diff package or whatever), then you can compare stuff about them

emccue17:11:16

i'm somewhat at a loss for whats going wrong

emccue17:11:17

since if it fails at that isAssignableFrom part, it doesn't make sense, since you do implement DBusInterface

emccue16:11:25

since I didn't intend start to actually be a method

emccue16:11:32

just a function in clojure

emccue16:11:10

try it without the - and see if it works - maybe gen-class tried to translate that as a method and it couldn't be exported?

emccue16:11:33

and the class implements DBusInterface

emccue16:11:42

CLASS_TO_ARGUMENTTYPE.put(DBusInterface.class, Message.ArgumentType.OBJECT_PATH);
        CLASS_TO_ARGUMENTTYPE.put(DBusPath.class, Message.ArgumentType.OBJECT_PATH);
        CLASS_TO_ARGUMENTTYPE.put(ObjectPath.class, Message.ArgumentType.OBJECT_PATH);
    }

emccue16:11:04

for (Entry<Class<?>, Byte> entry : CLASS_TO_ARGUMENTTYPE.entrySet()) {
                    if (entry.getKey().isAssignableFrom(dataTypeClazz)) {

emccue16:11:17

so it should be assignable to that

Michaƫl Salihi16:11:04

Thank again @emccue, I'll tried that. (y)