From 2a0965fb55e700c40e9d5208b96736672f62bbe0 Mon Sep 17 00:00:00 2001 From: David M Date: Wed, 4 Oct 2023 13:17:07 +0200 Subject: [PATCH] Issue #236: Updated documentation for exporting objects; Added example code --- README.md | 1 + .../dbus/examples/export/ExportExample.java | 64 ++++++++++ .../dbus/examples/export/ISampleExport.java | 25 ++++ src/site/markdown/exporting-objects.md | 119 +++++++++++------- 4 files changed, 165 insertions(+), 44 deletions(-) create mode 100644 dbus-java-examples/src/main/java/com/github/hypfvieh/dbus/examples/export/ExportExample.java create mode 100644 dbus-java-examples/src/main/java/com/github/hypfvieh/dbus/examples/export/ISampleExport.java diff --git a/README.md b/README.md index 67e141fb..f7b470cb 100644 --- a/README.md +++ b/README.md @@ -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)) diff --git a/dbus-java-examples/src/main/java/com/github/hypfvieh/dbus/examples/export/ExportExample.java b/dbus-java-examples/src/main/java/com/github/hypfvieh/dbus/examples/export/ExportExample.java new file mode 100644 index 00000000..0b35d383 --- /dev/null +++ b/dbus-java-examples/src/main/java/com/github/hypfvieh/dbus/examples/export/ExportExample.java @@ -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.
+ * 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(); + } + +} diff --git a/dbus-java-examples/src/main/java/com/github/hypfvieh/dbus/examples/export/ISampleExport.java b/dbus-java-examples/src/main/java/com/github/hypfvieh/dbus/examples/export/ISampleExport.java new file mode 100644 index 00000000..aa46895d --- /dev/null +++ b/dbus-java-examples/src/main/java/com/github/hypfvieh/dbus/examples/export/ISampleExport.java @@ -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(); +} diff --git a/src/site/markdown/exporting-objects.md b/src/site/markdown/exporting-objects.md index 27e24caf..76ea082c 100644 --- a/src/site/markdown/exporting-objects.md +++ b/src/site/markdown/exporting-objects.md @@ -1,19 +1,22 @@ # 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(); } ``` @@ -21,29 +24,42 @@ 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 @@ -54,22 +70,24 @@ 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 @@ -77,25 +95,32 @@ 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 - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + ``` Next, we can go call the remote method using dbus-send and get the result of @@ -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 ``` \ No newline at end of file