Improved version of Java-DBus library provided by freedesktop.org with support for Java 17+.
The new major is no drop-in replacement for earlier versions! It requires code changes and at least Java 17.
When migrating from 4.x to 5.x you have to fix/replace all usages of deprecated method calls and class usages. Everything deprecated in a previous major version (4.x/3.x) and marked "forRemoval" is gone in 5.x.
When migrating from 3.x, the main difference is the separation of dbus-java into multi module project. The base artifact is dbus-java-core and requires at least one additional transport artifact. A transport provides the code to connect to DBus daemon on various ways (e.g. unix socket or TCP).
When updating to 4.x you have to add at least one transport to your project. If you add a unix socket transport, you have to choose between jnr-unixsocket and native-unixsocket. The jnr implementation will pull in jnr-unixsocket, jnr-posix etc. to your project. It will also provide support for abstract unixsockets and is required if you want to use file descriptor passing. If you need file descriptors as well you also have to add a proper implementation for that (see below).
If you don't know what abstract unixsockets are and you don't need file descriptors you'll probably you can use native-unixsockets.
Upgrading to 5.1.0 should be no problem in most cases.
Beginning with 5.1.0 the behavior of Variant<?>
has been altered to get a more consistent behavior.
More about that can be found here .
If you used DBusMap
before, you should use LinkedHashMap
instead.
All methods previously returned instances of DBusMap
will now return LinkedHashMap
.
This is transparent if you didn't use DBusMap
directly but using Map
interface instead.
In this version the broken hashCode()
implementation has been fixed in DBusPath
allowing proper usage
of DBusPath
as Map
key. Before equal objects did not create the same hashCode()
breaking the contract of hashCode()
and equals()
.
If you have used the SPI to extend the MessageReader/Writer of dbus-java before dbus-java 4.x, you have to update your code. Old providers will not work with dbus-java 4.x/5.x because of changed SPI interfaces (sorry!).
The changes were required due to the support of native-unixsocket which is using java.nio, while the old dbus-java code uses the old java.io socket API.
With dbus-java 4.x (and 5.x as well), java.nio is used for all transports and therefore required changes on the SPI.
ISocketProvider
will now use SocketChannel
instead of Socket
in the exported methods.
If you previously used a custom transport you have to update your code when switching to dbus-java 5.x.
The AbstractTransport
base class has been changed and now provides different methods to separate client and listening
(server) connections.
Additionally there is a new method called closeTransport()
which must be implemented to ensure all used resources
(e.g. SocketChannel
or ServerSocketChannel
instance) are properly closed.
Previously a transport should have overridden close()
and call super.close()
after closing the transport.
This is now longer needed (close()
is now final and cannot be overriden) and is replaced by closeTransport()
.
The connectImpl()
was previously existing and will now only be called for client side connections.
The new methods bindImpl()
, acceptImpl()
and isBound()
are used for server connections and has been added in dbus-java 5.x.
The reason to provide separate methods was to allow bootstrapping server connections before accepting connections.
In the old implementation accept()
was usually called in connectImpl()
and therefore blocked the method until
a client was connected. This blocked setting up the server side before the first client was connecting.
This forced the user to use some random sleep times to wait for the server setup after first client connects.
With the separation no more sleep waits are required.
With the new methods, everything related to setup the server socket should be done in bindImpl()
including the binding
of the listening socket (calling bind()
on the server socket). Everything done in this method should not block.
You mustn't call accept()
on your server socket in bindImpl()
!
In acceptImpl()
it is expected that the transport calls accept()
on its server socket and therefore this method will block.
It must return the SocketChannel
for each client connected (like connectImpl()
does).
The isBound()
method must return the bind status of the server socket. This means for example
server socket is not null
and server socket is opened.
This method is used by AbstractTransport
to determine if bindImpl()
was called before and if the server socket is ready to accept
connections.
In DBus-Java version below < 4.3.1 file descriptor usage was not supported out of the box and required a third party libary (see below). Starting with version 4.3.1 file descriptors are supported when using junixsocket-transport.
When trying to use file descriptors in dbus-java 3.x and not providing a implementation for this feature, you may see weird NullPointerExceptions thrown in Message class. In dbus-java < 4.3.1 you should see error messages indicating that file descriptors are not supported.
To use file descriptors with dbus-java version 4.x before 4.3.1 you have to do the following:
When using dbus-java-nativefd, you have to use version 2.x when using dbus-java 4.x/5.x and 1.x if you use dbus-java 3.x. DBus-java will automatically detect dbus-java-nativefd and will then provide access to file descriptors.
If you are using version 4.3.1 or higher, you may simple switch to dbus-java-transport-junixsocket
(instead of dbus-java-transport-jnr-unixsocket
or dbus-java-transport-native-unixsocket
).
You do this by adding dbus-java-transport-junixsocket
to your classpath.
Remember to remove the other unixsocket implementations because you are not allowed to have multiple implementations of the same protocol at once.
When adding dbus-java-transport-junixsocket
to your classpath, you will also pull-in some artifacts of junixsocket project.
It is also possible that junixsocket will not work on your platform (depends on which platform and architecture you are using).
They provide a lot of ready-to-use artifacts for different platforms and architectures, but certainly not for all possible combinations out there.
In case your platform is not supported, you may try dbus-java-transport-jnr-unixsocket
with com.rm5248:dbus-java-nativefd, compile
junixsocket yourself or open a ticket at junixsocket asking for help.
See the list in our Wiki
This project receives code contributions and donations from LogonBox.
However LogonBox is not responsible for this project and does not take influence in the development.
The library will remain open source and MIT licensed and can still be used, forked or modified for free.
VariantBuilder
to allow creating Variants which contain Maps or Collections without messing with the required DBus type argumentsMarshalling.getDBusType
(#265)InterfaceCodeGenerator
(to e. g. allow generating code using similar code style like dbus-java with prefixing every argument with _
)InterfaceCodeGenerator
was always null
InterfaceCodeGenerator
to prevent creating multiple empty linesEmitsChangedSignal
(PR#267), thanks to GeVa2072var
keywordCollection
when used in signal constructors (#268)Tuple
return type caused ClassCastException
(#271)ObjectPath
, use DBusPath
insteadof(String...)
factory method to DBusPath
getRemoteObject
methods which uses DBusPath
as argument@DBusBoundProperty
annotation (#253), (PR#252)GetAll
on Properites using Annotations (#258)GetAll
method in Properties
interface. More information DBusMap
- all methods previously used or returned DBusMap
will now return a LinkedHashMap
hashCode()
and equals()
method in DBusPath
(hashCode()
was completely wrong and violating the hashCode()
contract when e.g. used as key in maps)WeakHashMap
for imported objects (configurable by DBusConnectionBuilder
), default behavior of using a ConcurrentHashMap
is not changed (yet) (#261)ExportedObject.isExcluded(Method)
now returns true for bridge, default and synthetic methods, reported by brett-smith (#240)connect()
method to AbstractTransport
to allow connecting the underlying transport manually, thanks to brett-smith (#212)DBusDaemon
, thanks to brett-smith (#225)ExecutorService
for DBus-Sender-Threads (#234)getParameter(String)
method (#202)SASL
addCookie()
/findCookie()
methods (#205)PrintStream
file writing with Files.write
(#205)System.currentMillis()
for locking and waiting due to possible issues when NTP changes time during lock/wait (#206)System.out.print
and friends in unit tests (use a proper logger instead)EmbeddedDBusDaemon.startInBackgroundAndWait(long)
did not properly wait for the sender thread to be started (#208)MessageWriter
/MessageReader
provided on classpath (always used the default implementation)AbstractTransport
to support listener connections properly (you have to use listen()
method now, this allows proper usage of detected MessageReader
/MessageWriter
implementation)@DBusInterfaceName("XX")
on signal interface classes (#186)TransportBuilder.isListening(boolean)
as method name signals that a boolean
is returned but TransportBuilder
is returned. Please use TransportBuilder.listening(boolean)
instead. Old method will be removed in 4.3.0DBusConnectionBuilder.getSystemEndianness()
and DirectConnectionBuilder.getSystemEndianness()
, use BaseConnectionBuilder.getSystemEndianness()
insteadDBusConnectionBuilder
and DirectConnectionBuilder
to use same base class BaseConnectionBuilder
to reduce duplicated codeBaseConnectionBuilder
to ReceivingServiceConfigBuilder
to configure receiving thread-pools e.g. use DBusConnectionBuilder.forSessionBus().receivingThreadConfig().withXXX
and continue either with .buildConnection()
to get the connection object or .connectionConfig()
to get back to the chosen connection builderwithXXXThreadPriority
methods to ReceivingServiceConfigBuilder
to allow changing the thread priority set for ReceivingService
thread pool threads (#173)ReceivingService
using the builderReceivingService
will now throw IllegalThreadPoolStateException
(subclass of IllegalStateException
) instead of IllegalStateException
directlyBusAddress
internally instead of StringsBusAddress
in Tcp/UnixTransportisBusType(String)
to BusAddress
class which allows checking which kind of transport is used case-insensitive and null-safeTransportBuilder
, this will also deprecate a lot of methods (withXXX
) which were moved to configure()
(which returns a TransportConfigBuilder
)DBusConnectionBuilder
or DirectConnectionBuilder
(by using e.g. DBusConnectionBuilder.forSession().transportConfig()
)TransportConfig
supports additional configuration by providing a Map<String,Object>
which allows passing arbitrary values to the transportITransportProvider
which now takes a TransportConfig
object instead of the timeout int. For compatibility the old method is still present (and will be delegated), but should be considered deprecated and will be removed in the futureIOException
.
In case the disconnect is forced by an exception the remaining messages will be omitted. Otherwise connection may block because of waiting for a replies for MethodCall
s.
It is assumed that a disconnection caused by an exception might have closed the transport already so no further messages may be send or received.AbstractConnection.TCP_ADDRESS_PROPERTY
as this was a special behavior for using/testing DBusDaemon
EmbeddedDBusDaemon
will no longer set AbstractConnection.TCP_ADDRESS_PROPERTY
, instead you have to handle the address you used for construction of EmbeddedDBusDaemon
yourselfDBusConnectionBuilder.forSessionBus()
will use the same validation applied to system addressesSignalTuple
classInputMessageStreamReader
to use a final socket channel and some more final member variables for constant size buffers (#183)Message
class to not create superflous Variant
objects to populate message header (#184)DBusInterface
to be exported on the bus (#157)DBusConnection.newConnection
/DBusConnection.getConnection
, please use DBusConnectionBuilderDirectConnection
, please use DirectConnectionBuilder