Skip to content

Commit

Permalink
Issue #236: Updated documentation for exporting objects; Added exampl…
Browse files Browse the repository at this point in the history
…e code
  • Loading branch information
hypfvieh committed Oct 4, 2023
1 parent 82f8575 commit 2a0965f
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 44 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ The library will remain open source and MIT licensed and can still be used, fork
- Updated dependencies and maven plugins
- Updated minimum required Java version to 17
- Improved handling of listening connections to allow proper bootstrapping the connection before actually starting accepting new connections (thanks to [brett-smith](https://github.com/brett-smith) ([#213](https://github.com/hypfvieh/dbus-java/issues/213)))
- Updated export-object documentation ([#236](https://github.com/hypfvieh/dbus-java/issues/236))

##### Changes in 4.3.1 (2023-10-03):
- Provide classloader to ServiceLoader in TransportBuilder (for loading actual transports) and AbstractTransport (for loading IMessageReader/Writer implementations), thanks to [cthbleachbit](https://github.com/cthbleachbit) ([#210](https://github.com/hypfvieh/dbus-java/issues/210), [PR#211](https://github.com/hypfvieh/dbus-java/issues/211))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.github.hypfvieh.dbus.examples.export;

import org.freedesktop.dbus.connections.impl.DBusConnection;
import org.freedesktop.dbus.connections.impl.DBusConnectionBuilder;
import org.freedesktop.dbus.exceptions.DBusException;

import java.util.concurrent.CountDownLatch;

/**
* Sample code to demonstrate exporting of an object.<br>
* This is the code also found in {@code export-objects.md}
*
* @author hypfvieh
* @since 5.0.0 - 2023-10-04
*/
public class ExportExample implements ISampleExport {

private DBusConnection dbusConn;
private CountDownLatch waitClose;

ExportExample() throws DBusException, InterruptedException {
waitClose = new CountDownLatch(1);
// Get a connection to the session bus so we can request a bus name
dbusConn = DBusConnectionBuilder.forSessionBus().build();
// Request a unique bus name
dbusConn.requestBusName("test.dbusjava.export");
// Export this object onto the bus using the path '/'
dbusConn.exportObject(getObjectPath(), this);
// this will cause the countdown latch to wait until terminateApp() was called
// you probably want to do something more useful
waitClose.await();
System.out.println("bye bye");
}

@Override
public int add(int _a, int _b) {
return _a + _b;
}

@Override
public void terminateApp() {
waitClose.countDown();
}

@Override
public boolean isRemote() {
/* Whenever you are implementing an object, always return false */
return false;
}

@Override
public String getObjectPath() {
/*
* This is not strictly needed; it is a convenience method for housekeeping on your application side if you will
* be exporting and unexporting many times
*/
return "/";
}

public static void main(String[] _args) throws Exception {
new ExportExample();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.github.hypfvieh.dbus.examples.export;

import org.freedesktop.dbus.interfaces.DBusInterface;

/**
* Example interface used to demonstrate exporting of an object.
*
* @author hypfvieh
* @since 5.0.0 - 2023-10-04
*/
public interface ISampleExport extends DBusInterface {
/**
* Adds a to b and returns the result.
*
* @param _a first number
* @param _b second number
* @return sum of both numbers
*/
int add(int _a, int _b);

/**
* Terminate the running application remotely.
*/
void terminateApp();
}
119 changes: 75 additions & 44 deletions src/site/markdown/exporting-objects.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,65 @@
# Exporting Objects

_[Full Source](https://github.com/hypfvieh/dbus-java/tree/master/dbus-java-examples/src/main/java/com/github/hypfvieh/dbus/examples/export)_

In order for other programs to call a method, you must first export the object
onto the bus in order for other programs to see it. The object that is exported
must implement an interface which extends `DBusInterface`.

Here's a sample interface:

```
package com.foo;
```java
package com.github.hypfvieh.dbus.examples.export;

import org.freedesktop.dbus.interfaces.DBusInterface;

public interface IntInterface extends DBusInterface {
public interface ISampleExport extends DBusInterface {
int add(int _a, int _b);

public int add( int a, int b );
void terminateApp();
}
```

In order for other applications to call this interface, we need to create an
object that implements this interface and export it onto the bus. Here's the
full code that does that:

```
package com.foo;
```java
package com.github.hypfvieh.dbus.examples.export;

import org.freedesktop.dbus.connections.impl.DBusConnection;
import org.freedesktop.dbus.connections.impl.DBusConnectionBuilder;
import org.freedesktop.dbus.exceptions.DBusException;

public class ExportExample implements IntInterface {
private DBusConnection m_conn;
import java.util.concurrent.CountDownLatch;

public class ExportExample implements ISampleExport {

private DBusConnection dbusConn;
private CountDownLatch waitClose;

ExportExample() throws DBusException, InterruptedException {
waitClose = new CountDownLatch(1);
// Get a connection to the session bus so we can request a bus name
dbusConn = DBusConnectionBuilder.forSessionBus().build();
// Request a unique bus name
dbusConn.requestBusName("test.dbusjava.export");
// Export this object onto the bus using the path '/'
dbusConn.exportObject(getObjectPath(), this);
// this will cause the countdown latch to wait until terminateApp() was called
// you probably want to do something more useful
waitClose.await();
System.out.println("bye bye");
}

ExportExample() throws DBusException {
/* Get a connection to the session bus so we can request a bus name */
m_conn = DBusConnectionBuilder.forSessionBus().build();
/* Request a unique bus name */
m_conn.requestBusName( "test.dbusjava.export" );
/* Export this object onto the bus using the path '/' */
m_conn.exportObject( getObjectPath(), this );
@Override
public int add(int _a, int _b) {
return _a + _b;
}

@Override
public int add(int a, int b) {
return a + b;
public void terminateApp() {
waitClose.countDown();
}

@Override
Expand All @@ -54,48 +70,57 @@ public class ExportExample implements IntInterface {

@Override
public String getObjectPath() {
/* This is not strictly needed; it is a convenience method for housekeeping
* on your application side if you will be exporting and unexporting
* many times
/*
* This is not strictly needed;
* it is a convenience method for housekeeping on your application side if you will
* be exporting and unexporting many times
*/
return "/";
}

public static void main(String[] args) throws DBusException {
public static void main(String[] _args) throws Exception {
new ExportExample();
}

}
```

If you compile and run this program, you will be able to do two things at this
point: view the introspection data, and get the result of an addition.
If you compile and run this program, you will be able to do three things at this
point: view the introspection data get the result of an addition and terminate our application by
calling `terminateApp()`.

If we introspect our application like the following, we can see the
_automatically_ generated introspection XML document. This means that we can
define an entire interface without touching XML at all.

```
$ dbus-send --print-reply=literal --type=method_call --dest=test.dbusjava.export / org.freedesktop.DBus.Introspectable.Introspect
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node name="/">
<interface name="com.foo.IntInterface">
<method name="add" >
<arg type="i" direction="in"/>
<arg type="i" direction="in"/>
<arg type="i" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping">
</method>
</interface>
</node>
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection
1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node name="/">
<interface name="com.github.hypfvieh.dbus.examples.export.ISampleExport">
<method name="add" >
<arg type="i" direction="in"/>
<arg type="i" direction="in"/>
<arg type="i" direction="out"/>
</method>
<method name="terminateApp" >
</method>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect" >
<arg type="s" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping" >
</method>
<method name="GetMachineId" >
<arg type="s" direction="out"/>
</method>
</interface>
</node>
```

Next, we can go call the remote method using dbus-send and get the result of
Expand All @@ -104,4 +129,10 @@ the addition back:
```
$ dbus-send --print-reply=literal --type=method_call --dest=test.dbusjava.export / com.foo.IntInterface.add int32:5 int32:7
int32 12
```

Or we can use the `terminateApp()` method to stop our application:

```
$ dbus-send --print-reply=literal --type=method_call --dest=test.dbusjava.export / com.foo.IntInterface.terminateApp
```

0 comments on commit 2a0965f

Please sign in to comment.