7 D-Bus Types

D-Bus supports a number of types in its messages, some which Java supports natively, and some which it doesn’t. This library provides a way of modelling the extra D-Bus Types in Java. The full list of types and what D-Bus type they map to is in table 1.

7.1 Basic Types

All of Java’s basic types are supported as parameters and return types to methods, and as parameters to signals. These can be used in either their primitive or wrapper types.

7.1.1 Unsigned Types

D-Bus, like C and similar languages, has a notion of unsigned numeric types. The library supplies UInt1614 , UInt32 and UInt64 classes to represent these new basic types.

7.2 Strings

D-Bus also supports sending Strings. When mentioned below, Strings count as a basic type.

7.2.1 String Comparisons

There may be some problems with comparing strings received over D-Bus with strings generated locally when using the String.equals method. This is due to how the Strings are generated from a UTF8 encoding. The recommended way to compare strings which have been sent over D-Bus is with the java.text.Collator class. Figure 10 demonstrates its use.


String rname = remote.getName();  
Collator col = Collator.getInstance();  
col.setDecomposition(Collator.FULL_DECOMPOSITION);  
col.setStrength(Collator.PRIMARY);  
if (0 != col.compare("Name", rname))  
   fail("getName return value incorrect");


Figure 10: Comparing strings with java.text.Collator.

7.3 Arrays

You can send arrays of any valid D-Bus Type over D-Bus. These can either be declared in Java as arrays (e.g. Integer[] or int[]) or as Lists (e.g. List<String>). All lists must be parameterised with their type in the source (reflection on this is used by the library to determine their type). Also note that arrays cannot be used as part of more complex type, only Lists (for example List<List<String>>).

7.4 Maps

D-Bus supports a dictionary type analogous to the Java Map type. This has the additional restriction that only basic types can be used as the key (including String). Any valid D-Bus type can be the value. As with lists, maps must be fully parameterised. (e.g. Map<Integer, String>).

7.5 Variants

D-Bus has support for a Variant type. This is similar to declaring that a method takes a parameter of type Object, in that a Variant may contain any other type. Variants can either be declared using the Variant15 class, or as a Type Variable. In the latter case the value is automatically unwrapped and passed to the function. Variants in compound types (Arrays, Maps, etc) must be declared using the Variant class with the full type passed to the Variant constructor and manually unwrapped.

Both these methods use variants:

public void display(Variant v);  
public <T> int hash(T v);

7.6 Structs

D-Bus has a struct type, which is a collection of other types. Java does not have an analogue of this other than fields in classes, and due to the limitation of Java reflection this is not sufficient. The library declares a Struct16 class which can be used to create structs. To define a struct you extend the Struct class and define fields for each member of the struct. These fields then need to be annotated in the order which they appear in the struct (class fields do not have a defined order). You must also define a single constructor which takes the contents of he struct in order. This is best demonstrated by an example. Figure 11 shows a Struct definition, and figure 12 shows this being used as a parameter to a method.


package org.freedesktop.dbus.test;  
 
import org.freedesktop.dbus.DBusException;  
import org.freedesktop.dbus.Position;  
import org.freedesktop.dbus.Struct;  
 
public final class TestStruct extends Struct  
{  
   @Position(0)  
   public final String a;  
   @Position(1)  
   public final int b;  
   @Position(2)  
   public final String c;  
   public Struct3(String a, int b, String c)  
   {  
      this.a = a;  
      this.b = b;  
      this.c = c;  
   }  
}


Figure 11: A Struct with three elements


public void do(TestStruct data);


Figure 12: A struct as a parameter to a method

Section 10 describes how these can be automatically generated from D-Bus introspection data.

7.7 Objects

You can pass references to exportable objects round using their object paths. To do this in Java you declare a type of DBusInterface. When the library receive- an object path it will automatically convert it into the object you are exporting with that object path. You can pass remote objects back to their processes in a similar fashion.

Using a parameter of type DBusInterface can cause the automatic creation of a proxy object using introspection. If the remote app does not support introspection, or the object does not exist at the time you receive the message then this will fail. In that case the parameter can be declared to be of type Path. In this case no automatic creation will be performed and you can get the path as a string with either the getPath or toString methods on the Path object.

7.8 Multiple Return Values

D-Bus also allows functions to return multiple values, a concept not supported by Java. This has been solved in a fashion similar to the struct, using a Tuple17 class. Tuples are defined as generic tuples which can be parameterised for different types and just need to be defined of the appropriate length. This can be seen in figure 13 and a call in figure 14. Again, these can be automatically generated from introspection data.


import org.freedesktop.dbus.Tuple;  
 
public final class TestTuple<A, B, C> extends Tuple  
{  
   public final A a;  
   public final B b;  
   public final C c;  
   public TestTuple(A a, B b, C c)  
   {  
      this.a = a;  
      this.b = b;  
      this.c = c;  
   }  
}


Figure 13: A 3-tuple


public ThreeTuple<String, Integer, Boolean> status(int item);


Figure 14: A Tuple being returned from a method

7.9 Full list of types

Table 1 contains a full list of all the Java types and their corresponding D-Bus types.


Java Type D-Bus Type


Byte DBUS_TYPE_BYTE
byte DBUS_TYPE_BYTE
Boolean DBUS_TYPE_BOOLEAN
boolean DBUS_TYPE_BOOLEAN
Short DBUS_TYPE_INT16
short DBUS_TYPE_INT16
UInt16 DBUS_TYPE_UINT16
int DBUS_TYPE_INT32
Integer DBUS_TYPE_INT32
UInt32 DBUS_TYPE_UINT32
long DBUS_TYPE_INT64
Long DBUS_TYPE_INT64
UInt64 DBUS_TYPE_UINT64
double DBUS_TYPE_DOUBLE
Double DBUS_TYPE_DOUBLE
String DBUS_TYPE_STRING
Path DBUS_TYPE_OBJECT_PATH
<T> DBUS_TYPE_VARIANT
Variant DBUS_TYPE_VARIANT
? extends Struct DBUS_TYPE_STRUCT
?[ ] DBUS_TYPE_ARRAY
? extends List DBUS_TYPE_ARRAY
? extends Map DBUS_TYPE_DICT
? extends DBusInterfaceDBUS_TYPE_OBJECT_PATH
Type[ ] DBUS_TYPE_SIGNATURE

Table 1: Mapping between Java types and D-Bus types

7.9.1 float

Currently the D-Bus reference implementation does not support a native single-precision floating point type. Along with the C# implementation of the protocol, the Java implementation supports this extension to the protocol. By default, however, the library operates in compatibility mode and converts all floats to the double type. To disable compatibility mode export the environment variable DBUS_JAVA_FLOATS=true.