hypfvieh / dbus-java

Improved version of java DBus library provided by freedesktop.org (https://dbus.freedesktop.org/doc/dbus-java/)
https://hypfvieh.github.io/dbus-java/
MIT License
185 stars 73 forks source link

FileDescriptor NullPointerException #155

Closed Killbrum closed 2 years ago

Killbrum commented 2 years ago

Hello, @hypfvieh ! I've found a crash/internal exception related to "org.freedesktop.dbus.FileDescriptor" and its usage. I'm developing an application that uses "org.freedesktop.login1.Manager". Especially method "Inhibit". I need to use this method to prevent system shutdown (more details about Inhibit method can be found here: https://www.freedesktop.org/software/systemd/man/org.freedesktop.login1.html). The application throws "java.lang.NullPointerException" exception even on your test sandbox (https://github.com/hypfvieh/sandbox). I've tried to pass different parameters, but I receive the same exception every time, no matter what.

Here is the output:

application@LPS-003128:~/DBusTest$ java -cp DBusTest.jar com.github.hypfvieh.sandbox.login1.LoginManager
Exception in thread "main" java.lang.NullPointerException
        at org.freedesktop.dbus.messages.Message.extractOne(Message.java:982)
        at org.freedesktop.dbus.messages.Message.extract(Message.java:1145)
        at org.freedesktop.dbus.messages.Message.extract(Message.java:1122)
        at org.freedesktop.dbus.messages.Message.getParameters(Message.java:1253)
        at org.freedesktop.dbus.RemoteInvocationHandler.executeRemoteMethod(RemoteInvocationHandler.java:156)
        at org.freedesktop.dbus.RemoteInvocationHandler.invoke(RemoteInvocationHandler.java:216)
        at com.sun.proxy.$Proxy19.Inhibit(Unknown Source)
        at com.github.hypfvieh.sandbox.login1.LoginManager.main(LoginManager.java:17)

The main source is a slightly modified sandbox example:

package com.github.hypfvieh.sandbox.login1;

import java.io.FileDescriptor;
import java.io.IOException;

import org.freedesktop.dbus.connections.impl.DBusConnection;
import org.freedesktop.dbus.connections.impl.DBusConnection.DBusBusType;
import org.freedesktop.dbus.exceptions.DBusException;
import org.freedesktop.login1.Manager;

public class LoginManager {

    public static void main(String[] args) throws DBusException, IOException {
        try (DBusConnection sysConn = DBusConnection.getConnection(DBusBusType.SYSTEM)) {
            Manager mgr = sysConn.getRemoteObject("org.freedesktop.login1", "/org/freedesktop/login1", org.freedesktop.login1.Manager.class);

            org.freedesktop.dbus.FileDescriptor fd = mgr.Inhibit("shutdown", "application", "cleanup", "delay");
        }
    }

}

Please check the attachments for the whole package. For my purposes, I use Java 11 (Azul) and DBus-3.3.1. dbus-java and sandbox sources were not modified except java version, dbus-java version, and one line of code related to "Inhibit" method. Personally, I believe that any call to "Inhibit" leads to NullPointer exception.

Please check and confirm the issue.

Thanks for your time!

DBusTest.zip

hypfvieh commented 2 years ago

There is no issue in dbus-java - using FileDescriptors is not possible without additional dependencies (due to some issue in jnr-unixsocket). If you want to use file-descriptors you have to add the dbus-java-nativefd library which provides a proper ISocketProvider which can handle FileDescriptors. (see: https://github.com/rm5248/dbus-java-nativefd)

Killbrum commented 2 years ago

Good time of the day! @hypfvieh , thank you for the rapid response! I've added the "dbus-java-nativefd" library to the project as per your recommendation. The include was added to the POM.xml file as is instructed in README. Also, a special pre-requisite to have a dependency on "dbus-java" 3.3.1 is met. Still, the application shows the same output with the null pointer exception as in my previous message. I've double-checked includes, files and dependencies.

Is there any need to call a special initializer for the "dbus-java-nativefd" library? Because, in my case, I simply added this library as a dependency

application@LPS-003128:~/DBusTest$ java -cp DBusTest.jar com.github.hypfvieh.sandbox.login1.LoginManager
Exception in thread "main" java.lang.NullPointerException
        at org.freedesktop.dbus.messages.Message.extractOne(Message.java:982)
        at org.freedesktop.dbus.messages.Message.extract(Message.java:1145)
        at org.freedesktop.dbus.messages.Message.extract(Message.java:1122)
        at org.freedesktop.dbus.messages.Message.getParameters(Message.java:1253)
        at org.freedesktop.dbus.RemoteInvocationHandler.executeRemoteMethod(RemoteInvocationHandler.java:156)
        at org.freedesktop.dbus.RemoteInvocationHandler.invoke(RemoteInvocationHandler.java:216)
        at com.sun.proxy.$Proxy19.Inhibit(Unknown Source)
        at com.github.hypfvieh.sandbox.login1.LoginManager.main(LoginManager.java:17)

Thanks for your time!

hypfvieh commented 2 years ago

Could you please share your updated pom? I tried it using your zip file. After adding the missing dependency the method call in main did pass without an exception (at least when running in eclipse). I have to admit that I did not check the resulting descriptor instance, but the exception in your case is thrown earlier.

Killbrum commented 2 years ago

I also didn't check the descriptor's validity since the problem occurrs earlier. Still, I have to admit that I use Azul JDK 11 with Ubuntu 14.04. I'll test this sample application with Debian 11. Maybe the problem is in OS.

Attached POM.xml file pom.zip

hypfvieh commented 2 years ago

I can't see any error in the pom or in dbus-java. When running your modified sandbox code with the updated pom using the commandline with all required dependencies it works like expected. I also don't think that it is related to the JVM manufacturer. I use the JVM build provided by adoptium (previously AdoptOpenJDK), but all of those JVMs should comply to the official JVM test kit, so I don't expect any issues here.

I changed the main method to print something when a FileDescriptor could be obtained:

public static void main(String[] args) throws DBusException, IOException {
        try (DBusConnection sysConn = DBusConnection.getConnection(DBusBusType.SYSTEM)) {
            Manager mgr = sysConn.getRemoteObject("org.freedesktop.login1", "/org/freedesktop/login1", org.freedesktop.login1.Manager.class);

            org.freedesktop.dbus.FileDescriptor fd = mgr.Inhibit("shutdown", "application", "cleanup", "delay");
            if (fd == null) {
                System.err.println("unexpected");
            } else {
                System.out.println("Got FD: " + fd);
            }
        }
    }

Using this commandline: java -cp target/sandbox-github-1.0-SNAPSHOT.jar:/home/hypfvieh/.m2/repository/com/github/hypfvieh/dbus-java/3.3.1/dbus-java-3.3.1.jar:/home/hypfvieh/.m2/repository/com/github/jnr/jnr-unixsocket/0.38.6/jnr-unixsocket-0.38.6.jar:/home/hypfvieh/.m2/repository/com/github/jnr/jnr-ffi/2.2.2/jnr-ffi-2.2.2.jar:/home/hypfvieh/.m2/repository/com/github/jnr/jffi/1.3.1/jffi-1.3.1.jar:/home/hypfvieh/.m2/repository/com/github/jnr/jffi/1.3.1/jffi-1.3.1-native.jar:/home/hypfvieh/.m2/repository/org/ow2/asm/asm/9.1/asm-9.1.jar:/home/hypfvieh/.m2/repository/org/ow2/asm/asm-commons/9.1/asm-commons-9.1.jar:/home/hypfvieh/.m2/repository/org/ow2/asm/asm-analysis/9.1/asm-analysis-9.1.jar:/home/hypfvieh/.m2/repository/org/ow2/asm/asm-tree/9.1/asm-tree-9.1.jar:/home/hypfvieh/.m2/repository/org/ow2/asm/asm-util/9.1/asm-util-9.1.jar:/home/hypfvieh/.m2/repository/com/github/jnr/jnr-a64asm/1.0.0/jnr-a64asm-1.0.0.jar:/home/hypfvieh/.m2/repository/com/github/jnr/jnr-x86asm/1.0.2/jnr-x86asm-1.0.2.jar:/home/hypfvieh/.m2/repository/com/github/jnr/jnr-constants/0.10.1/jnr-constants-0.10.1.jar:/home/hypfvieh/.m2/repository/com/github/jnr/jnr-enxio/0.32.4/jnr-enxio-0.32.4.jar:/home/hypfvieh/.m2/repository/com/github/jnr/jnr-posix/3.1.5/jnr-posix-3.1.5.jar:/home/hypfvieh/.m2/repository/com/rm5248/dbus-java-nativefd/1.0/dbus-java-nativefd-1.0.jar:/home/hypfvieh/.m2/repository/com/github/hypfvieh/java-utils/1.0.6/java-utils-1.0.6.jar:/home/hypfvieh/.m2/repository/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30.jar com.github.hypfvieh.sandbox.login1.LoginManager

The result is something like this (I omitted the warnings of slf4j): Got FD: org.freedesktop.dbus.FileDescriptor@14028087

In your sample above you call: java -cp DBusTest.jar com.github.hypfvieh.sandbox.login1.LoginManager which looks like a fat-jar because no additional dependencies are listed. If you create a fat-jar, please be sure to include the ServiceLoader information provided by dbus-java-nativefd (in META-INF folder) which will be used by the ServiceLoader mechanism of the JVM to load dbus-java-nativefd.

Killbrum commented 2 years ago

I apologize for such a delayed reply. Thank you so much for your help! The issue is solved. You were right about application compilation. Thanks for your time and great software!