Views

D-Bus Development

This page summarizes information useful for implementing D-Bus support in Jajuk and for enhancing the existing support.

See D-Bus for general information about D-Bus support in Jajuk.

See http://trac.jajuk.info/ticket/439 for some more discussion about D-Bus in Jajuk.

Contents

[hide]

Current development state

We have now checked in a first set of changes for D-Bus support on trunk.

This is done by adding libdbus-java-2.6.jar, unix-0.5.jar, hexdump-0.2.jar, libunix-java.so to provide the platform support for D-Bus.

The interface DBusSupport defines all the methods that are provided via D-Bus. The class DBusSupportImpl contains the actual implementation (just invokes the respective Actions) and the connect()/disconnect() code. The connection is established in Main.java as last step of startup.

Also necessary changes in the build-files are done. Eclipse project file should be fine, for pom.xml I am not sure, I tried to add the two libraries, but am not sure as I do not know much about maven. Ant build seems to include the two new files correctly as well.

Additionally I tried to set the parameter "-Djava.library.path" for the jni-library in the start-script, but am not sure if that is done correctly as I start Jajuk differently for development usually.

Todo

  • I just noticed that I can only build libunix-java.so for 64-bit on my machine, so it won't work on 32-bit linux for now.
    • added both 32-bit and 64-bit JNI libraries and let the startup script decide which one to use
  • I am also not sure how to ensure that the .so library that I build works on other platforms, unfortunately there is no "pure java" version of it that I could find.
    • Found no way to do this, currently it will only work on x86 and x86_64.
  • As said, the startup script might need adjusting
    • I did some testing, it seems to work fine now
  • The "disconnect()" method is not called currently during shutdown, we probably should register a shutdown hook for it.
    • added shutdown hook
  • When adding new interfaces I once had to reboot the machine to make the new methods work, not sure if it was caused by the missing "disconnect()" and D-Bus had the methods still cached somewhere.
    • it did work now for new methods
  • Currently we just provide a few simple actions, usually information is also provided back, i.e. which track is currently playing, how far are we in the current track, ... This would just be more interface methods and implementations, so should not be complicated at all

Comments from Bertrand:

  • I think the "dbus" package should be moved into the "org.jajuk.services" one.
    • Moved
  • I don't like much this dependency between Main class and a DBusSupportImpl. Perhaps should we use a singleton located in org.jajuk.services.dbus package to make things isolated ? This singleton could startup and connect to DBUS in its constructor.
    • Added a DBusManager which is a singleton and resides in package org.jajuk.services.dbus and handles all communication with D-Bus
  • If several implementation of dbus are available, please create a bridge pattern [GOF] as we do for most services (tags and players for ie)
    • not implemented right now as there seems to be only one D-Bus Java Binding available.
  • If possible (depends on the sequence required), please instanciate this singleton in the StartupService class, especially in the asynchronous method called after collection loading if possible to avoid slowing down the startup.
    • Initializing DBusManager now in class StartupService as part of async startup.

Response from the author of dbus-java regarding need for JNI library

> Is there a way to avoid this dependency? As far as I see the JNI
> library is used for unix-style socket connections and would not be
> needed when using TCP. I expect the type of connection that is
> required is dictated by the D-Bus session via the environment
> variables which contain the address details so it will not be possible
> to simple "switch" to TCP for our application when we still want to
> talk to the general D-Bus daemon on the system, right?

You can at the moment use dbus-java without the JNI (you need the
unix-socket jar to compile against, but never the JNI and only the jar
at runtime) _if_ you are using a TCP bus. As you say however, the system
or session bus which you want to connect to will be listening on just
the unix socket address. It _is_ possible to have it listen on TCP as
well, but that requires a change in the system-level configuration and
it's not encouraged.

> Do you see any way of removing that dependency while still allowing us
> to use the default D-Bus daemon on KDE/Gnome to remotely control the
> application?
 
I'm afraid given the above constraint I don't think you are going to be
able to do that.

Given you are distributing this for Linux, what you should in general do
is assume that the distribution will package dbus-java (if not your
application) and that your users should install dbus-java via their
distribution. That way you don't have to worry about the JNI. I believe
most of the major distributions now package dbus-java (Certainly
Debian/Ubuntu, Gentoo, Arch and at least one of the RPM distros do,
don't know about others off the top of my head)

Information

Java binding:

Java D-Bus Implementation Documentation:

Some notes on building the Java binding

  • Copy and past these export lines (if there are not already defined) in your shell. Make sure your export to the correct place
export JAVA="/usr/lib/jvm/java-6-sun-1.6.0.00/jre/bin/java"
export JAVA_HOME="/usr/lib/jvm/java-6-sun-1.6.0.00/"
export JAVAUNIXJARDIR="/usr/share/java/libmatthew-java"
export JAVAUNIXLIBDIR="/usr/lib/libmatthew-java"
  • Make sure java javac javap javah are all set to the correct version
cd libmatthew-java-0.7.2
make
sudo make install

NOTE: If you want to simulate 'make install' (hence not installing anything) use the command 'make -n install'. If you don't want to install it globally on your system, you can just rename a few files, and don't forget to export correctly JAVAUNIXJARDIR and JAVAUNIXLIBDIR after.

cd libmatthew-java-0.7.2
ln -s unix-0.2.jar unix.jar    
ln -s debug-disable-1.1.jar debug-disable.jar  
ln -s hexdump-0.1.jar hexdump.jar
etc...
  • Building dbus jar
cd dbus-java-2.6
make
sudo make install

D-Bus example

  • To code, check out dbus-java-2.6/org/freedesktop/dbus/test/
  • To send dbus command to apps, e.g.: a quit message to application registered as "MediaPlayer":
$ qdbus org.freedesktop.MediaPlayer /Player org.freedesktop.MediaPlayer.Quit

Other player DBUS implementation

VLC D-Bus specification:

MPRIS

MPRIS (Media Player Remote Interface Specification)

See http://trac.jajuk.info/ticket/555

D-Bus

See D-Bus.

See also