Drucken

Java, Linux und D-Bus - geht das?

Zunächst einmal: ja - und wie! Man muß aber unter Umständen zunächst die eine oder andere Hürde überwinden.

D-Bus


Was ist D-Bus ? D-Bus ist eine Softwareplattform, die eine einfache Möglichkeit zur Verfügung stellt, damit Anwendungen sich gegenseitig Botschaften senden können. Abstrakt gesprochen kann man dieses Protokoll also als Interprozess-Kommunikationsprotokoll bezeichnen, das von der Benutzung her durchaus ein wenig an Corba und WebServices erinnert, da es ebenfalls sprachunabhängig ist - egal in welcher Programmiersprache die Anwendungen geschrieben sind - der D-Bus läßt sie miteinander reden.

Die Schnittstelle zu Java

Da der D-Bus unabhängig von der eingesetzten Programmiersprache benutzt werden kann, muß er sich auch an Java  ankoppeln lassen? Das geschieht durch die Benutzung der Klassen im Namensraum
org.freedesktop.dbus
Diese Klassen sind auf der Webseite dbus.freedesktop.org erhältlich. Voraussetzung, das hier beschriebene Vorgehen nachzuvollziehen ist die Benutzung des Java Development Kit ab Version 1.5.
Die praktische Arbeit

Um nun selber Botschaften über den D-Bus absenden zu können, sind nur wenige Handgriffe nötig:
Die Verbindung

Eine Verbindung zum Session-Bus baut man etwa wie folgt auf:
DBusConnection conn=DBusConnection.getConnection(DBusConnection.SESSION);
Geschlossen wird eine solche Verbindung so:
conn.disconnect();

Die Schnittstelle


Zur Kommunikation mit einer beliebigen Anwendung müssen nun lediglich noch Interfaces geschrieben werden, deren Methoden denen der D-Bus-Schnittstellen der gewünschten Kommunikationspartner entsprechen. Diese Schnittstellen lassen sich (unter Linux) übrigens ganz hervorragend mit dem Werkzeug d-feet analysieren.

Gimp

Hier als Beispiel eine Schnittstelle mit einer Methode, die das Graphikprogramm Gimp anweist, eine Datei zu öffnen:

@DBusInterfaceName("org.gimpGIMP.UI")
public interface Gimp extends DBusInterface
{
    public Boolean Open(String uri);
}

Tomboy

Hier als Beispiel eine Schnittstelle mit einer Methode, die den elektronischen Notizblock Tomboy anweist, eine neue Notiz anzulegen (und entsprechend zu benennen):

@DBusInterfaceName("org.gnome.Tomboy.RemoteControl")
public interface Tomboy extends DBusInterface
{
    public String CreateNote();
    public String CreateNamedNote(java.lang.String title);
}

Und jetzt alle zusammen!

Zur Benutzung - zum Beispiel zum Öffnen einer Bilddatei in Gimp - muß man nun die entsprechende Methode am Proxy nur noch aufrufen:

String GObjectPath = "/org/gimp/GIMP/UI";
String GServiceBusName = "org.gimp.GIMP.UI";
DBusInterface c =conn.getRemoteObject(GServiceBusName, GObjectPath);
Proxy p=(Proxy)c;
java.lang.reflect.Method m=Gimp.class.getMethod("Open",java.lang.String.class);
Proxy.getInvocationHandler(p).invoke
(p, m, new java.lang.Object[]{"/tmp/ein_Bild.jpg"}); 
Voila - der Gimp öffnet das Bild!

Und wenn es nicht funktioniert?

Eine dynamische Bibliothek fehlt

Der D-Bus nutzt verschiedene Protokolle zur Übermittlung der Botschaften - wenn die zugrundeliegende Implementierung dazu Unix-Sockets verwendet, muß man noch die Bibliothek libunix-java.so in ein Verzeichnis packen, in dem es die Java-Laufzeitumgebung auch findet. Das geht normalerweise mit dem Paket-Management-Werkzeug deines Vertrauens

Ich kann libunix-java.so nicht benutzen: der Rechner stammelt irgendwas von

wrong ELF class: ELFCLASS64

Das ist zum Beispiel dann der Fall, wenn die Architektur AMD64 ist, aus irgendwelchen Gründen aber nur eione 32-Bit-Variante von Linux aktiv ist. Also entweder auf 64-Bit aufrüsten oder die Bibliothek einfach für 32Bit aus dem Quelltext selbst erzeugen.

Dazu müssen nur zwei Änderungen im Makefile der Bibliothek vorgenommen werden:

CFLAGS+=-Wall -Os -pedantic -Werror -m32
LDSHAREFLAGS+=-fpic -shared -m32

Die CFLAGS und die LDSHAREFLAGS werden also einfach um -m32 ergänzt, damit 32-Bit-Code entsteht. Gegebenenfalls muß man noch die Version der C-Lib installieren, die benötigt wird, um auf AMD64-Systemen 32-Bit-Programme zu erzeugen:

sudo apt-get install libc6-dev-i386

Danach kann man die Bibliothek als 32-Bit-Version erzeugen und endlich nach Herzenslust mit dem D-Bus spielen!