Question

I've been bashing my head on this problem for a while now.

I'm dealing with properties setting using the DBus-java bindings for DBus. When Set is called, the value to set is wrapped in a org.freedesktop.types.Variant object from which I have to extract it. Normally if the data is a primitive I can use generics in the Set parameters and the bindings does the type conversion before calling the Set method.

However I am trying to set using a org.freedesktop.types.DBusStructType which is a complex type and which needs to be manually unpacked. So far I've gotten to the point where I can extract the type from the variant but I can't cast the value wrapped in the Variant to a DBusStructType even though it is clearly identified as a DBusStructType

The following code throws a ClassCastException: Cannot cast [Ljava.lang.Object; to org.freedesktop.dbus.types.DBusStructType when called with a DBus.Struct from a python dbus test. I have checked the variant signature is packed right, but I can't find a way to cast the object returned by the Variant.getValue() to the type specified by Variant.getType() and access the structure fields.

public void Set(String interface_name, String property_name, Variant new_value) throws Exception {
     Type t = new_value.getType();
     Object s = new_value.getValue();
     t.getClass().cast(s); 
     System.out.println("Object cast to "+s.getClass().getName());
}

Any pointers would be really appreciated, I have started digging more into reflection as I'm still new to it but there is probably something I am missing.

Was it helpful?

Solution

I have not used the Type Interface at all, but it looks like the only known implementing class is Class. I would suggest Casting it as a Class and then calling cast.

public void Set(String interface_name, String property_name, Variant new_value) throws Exception {
     Type t = new_value.getType();
     Object s = new_value.getValue();
     ((Class)t).cast(s); 
     System.out.println("Object cast to "+s.getClass().getName());
}

hope this helps.

OTHER TIPS

The Object returned by getValue() needs to be cast to the right type corresponding to the Dbus types. By digging a bit more into the DBusStructType and DBusStruct, the Object returned by Variant.getValue() is an Object[] in the case of a DBusStruct. Here is the working code:

public void Set(String interface_name, String property_name, Variant new_value) throws Exception {
    Object[] s = (Object[])new_value.getValue();                  
    System.out.println("client ID: " + (Long)s[0] + ", string: " + (String) s[1]);
}

Output:

client ID: 0, string: Hello, this is data.

Note that I do a signature check on the Variant in the final implementation before casting the Object[] or it will fail with other DBus types.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top