This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-11-17
Channels
- # architecture (115)
- # asami (64)
- # aws (2)
- # babashka (65)
- # beginners (91)
- # calva (21)
- # clara (3)
- # cljdoc (5)
- # cljsrn (1)
- # clojure (331)
- # clojure-australia (15)
- # clojure-europe (16)
- # clojure-italy (7)
- # clojure-nl (8)
- # clojure-uk (10)
- # clojurescript (10)
- # conjure (4)
- # core-typed (6)
- # cryogen (12)
- # data-science (1)
- # datomic (9)
- # depstar (2)
- # emacs (1)
- # events (1)
- # figwheel-main (1)
- # fulcro (2)
- # graalvm (9)
- # helix (4)
- # java (45)
- # kaocha (4)
- # malli (14)
- # meander (4)
- # membrane (34)
- # mid-cities-meetup (6)
- # pedestal (3)
- # re-frame (7)
- # reitit (4)
- # shadow-cljs (4)
- # spacemacs (5)
- # sql (29)
- # tools-deps (22)
(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))))
but any time you need to make a method that isn't already on an interface you will run into gen-class
Thx @emccue for the help and for showing me the gen-class direction!
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?
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
Same error as with my tests with Reify. You can see the object on the REPL block above, I made a println.
The thrown error come from here: https://github.com/hypfvieh/dbus-java/blob/223f9145ca87d55ad0b26c50a118c682124be18f/dbus-java/src/main/java/org/freedesktop/dbus/Marshalling.java#L305
Visibly the Clojure gen-class object return false when testing with isAssignableFrom
> so I should put server value in an atom..but how can I assoc the current class object who implements DBusInterface in it?
(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))))
(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))))
@emccue How can I run the start function?
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)
OK, thank you, I still have trouble thinking with interop š
I have always the same error:
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
I get a set #{java.lang.Object org.freedesktop.dbus.DBusInterface}
@emccue Do you know how can I compare with the Java version? The ancestors object?
so if you can compile and import your java version (in a diff package or whatever), then you can compare stuff about them
since if it fails at that isAssignableFrom
part, it doesn't make sense, since you do implement DBusInterface
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?
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);
}
for (Entry<Class<?>, Byte> entry : CLASS_TO_ARGUMENTTYPE.entrySet()) {
if (entry.getKey().isAssignableFrom(dataTypeClazz)) {
Thank again @emccue, I'll tried that. (y)