从 DBUS org.freedesktop.dbus 和 java 获取数据 - org.freedesktop.DBus$Error$UnknownMethod: 方法不存在
Get data from DBUS org.freedesktop.dbus and java - org.freedesktop.DBus$Error$UnknownMethod: Method doesn't exist
我尝试从 dbus 服务获取一些数据并在 Java 中使用它。
我可以通过以下命令获取cli中的信息:
dbus-send --print-reply --system --dest=com.victronenergy.solarcharger.ttyUSB0 /Dc/0/Voltage com.victronenergy.BusItem.GetValue
结果是:
method return time=1538903662.321580 sender=:1.14 -> destination=:1.806 serial=335692 reply_serial=2
variant double 13.43
我试图在 Java 中获取此数据的是:
经过几个小时的阅读,我创建了一个界面。
package javadbus;
import java.util.Map;
import org.freedesktop.dbus.DBusInterface;
import org.freedesktop.dbus.DBusSignal;
import org.freedesktop.dbus.Variant;
import org.freedesktop.dbus.exceptions.DBusException;
public interface BusItem extends DBusInterface
{
public static class PropertiesChanged extends DBusSignal
{
public final Map<String,Variant> changes;
public PropertiesChanged(String path, Map<String,Variant> changes) throws DBusException
{
super(path, changes);
this.changes = changes;
}
}
public String GetDescription(String language, int length);
public Variant GetValue();
public String GetText();
public int SetValue(Variant value);
public Variant GetMin();
public Variant GetMax();
public int SetDefault();
public Variant GetDefault();
}
这里我成功调用了getConnection()和getRemoteObject()
package javadbus;
import org.freedesktop.dbus.DBusConnection;
import org.freedesktop.dbus.exceptions.DBusException;
import org.freedesktop.dbus.Variant;
public class VictronEnergyDBusSolarCharger {
private String port;
private DBusConnection conn;
public VictronEnergyDBusSolarCharger(String port) {
this.port = port;
try {
this.conn = DBusConnection.getConnection(DBusConnection.SYSTEM);
} catch (DBusException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private String getData(String item) {
BusItem bi;
String data = null;
Variant vData = null;
try {
bi = (BusItem)conn.getRemoteObject("com.victronenergy.solarcharger." + this.port, item, BusItem.class);
vData = bi.GetValue();
//data = bi.GetText();
} catch (DBusException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return data;
}
...
}
解决所有依赖关系并编译代码是一项艰巨的任务。但最终我做到了。因此,javac 现在可以正常运行。
但是如果我尝试调用方法 GetValue(),我会得到以下异常:
[Sender] INFO org.freedesktop.dbus.MessageWriter - <= MethodCall(0,1) { Path=>/org/freedesktop/DBus, Interface=>org.freedesktop.DBus, Member=>Hello, Destination=>org.freedesktop.DBus } { }
[Sender] INFO org.freedesktop.dbus.MessageWriter - <= MethodCall(0,3) { Path=>/Dc/0/Voltage, Interface=>javadbus.BusItem, Member=>GetValue, Destination=>com.victronenergy.solarcharger.ttyUSB0 } { }
Exception in thread "main" org.freedesktop.DBus$Error$UnknownMethod: Method "GetValue" with signature "" on interface "javadbus.BusItem" doesn't exist
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.freedesktop.dbus.Error.getException(Error.java:141)
at org.freedesktop.dbus.Error.throwException(Error.java:171)
at org.freedesktop.dbus.RemoteInvocationHandler.executeRemoteMethod(RemoteInvocationHandler.java:158)
at org.freedesktop.dbus.RemoteInvocationHandler.invoke(RemoteInvocationHandler.java:222)
at com.sun.proxy.$Proxy1.GetValue(Unknown Source)
at javadbus.VictronEnergyDBusSolarCharger.getData(VictronEnergyDBusSolarCharger.java:28)
at javadbus.VictronEnergyDBusSolarCharger.getDcV(VictronEnergyDBusSolarCharger.java:38)
at javadbus.MainClass.main(MainClass.java:7)
是否需要实现此方法GetValue?但是为什么例如我该怎么做?我只想获取此信息,而不是像服务器一样提供它。
为什么获取所有依赖项是一项艰巨的任务?
dbus-java 库和依赖项都可以在 maven central 获得,所以一个合适的 maven 项目应该开箱即用。
返回主题:
您不必实施 GetValue()
,但您需要一个适合 BusItem
的 java 接口。
据我在 victronerynergy (https://www.victronenergy.com/live/open_source:ccgx:d-bus) 的文档中看到的,您的界面不正确。
您提供了 SetDefault()
/GetDefault()
方法,这些方法仅在 com.victronenergy.settings
对象上可用,但您想要检索一个 com.victronenergy.BusItem
(com.victronenergy.settings
包)。
这是一个错误。第二个错误是:你为 BusItem
class.
使用了错误的包名
在您的情况下,DBus 将尝试解析路径为 javadbus.BusItem
的对象,该路径不是由连接的 BusAddress com.victronenergy.solarcharger.ttyUSB0
.
提供的
BusItem
class 必须在包 com.victronenergy
中,否则您必须使用注释 @DBusInterfaceName("com.victronenergy.BusItem")
.
注释将告诉 DBus 库忽略 java package/class 名称并使用注释中提供的名称。
Interface BusItem 是由 CreateInterface-Script 从 https://dbus.freedesktop.org/doc/dbus-java/dbus-java/dbus-javase10.html 创建的,XML 来自 Introspect()
但是你解决了我真正的问题。我现在使用注释@DBusInterfaceName("com.victronenergy.BusItem")。不再例外,我从我的太阳能充电器获取数据。非常感谢!
我尝试从 dbus 服务获取一些数据并在 Java 中使用它。
我可以通过以下命令获取cli中的信息:
dbus-send --print-reply --system --dest=com.victronenergy.solarcharger.ttyUSB0 /Dc/0/Voltage com.victronenergy.BusItem.GetValue
结果是:
method return time=1538903662.321580 sender=:1.14 -> destination=:1.806 serial=335692 reply_serial=2
variant double 13.43
我试图在 Java 中获取此数据的是:
经过几个小时的阅读,我创建了一个界面。
package javadbus;
import java.util.Map;
import org.freedesktop.dbus.DBusInterface;
import org.freedesktop.dbus.DBusSignal;
import org.freedesktop.dbus.Variant;
import org.freedesktop.dbus.exceptions.DBusException;
public interface BusItem extends DBusInterface
{
public static class PropertiesChanged extends DBusSignal
{
public final Map<String,Variant> changes;
public PropertiesChanged(String path, Map<String,Variant> changes) throws DBusException
{
super(path, changes);
this.changes = changes;
}
}
public String GetDescription(String language, int length);
public Variant GetValue();
public String GetText();
public int SetValue(Variant value);
public Variant GetMin();
public Variant GetMax();
public int SetDefault();
public Variant GetDefault();
}
这里我成功调用了getConnection()和getRemoteObject()
package javadbus;
import org.freedesktop.dbus.DBusConnection;
import org.freedesktop.dbus.exceptions.DBusException;
import org.freedesktop.dbus.Variant;
public class VictronEnergyDBusSolarCharger {
private String port;
private DBusConnection conn;
public VictronEnergyDBusSolarCharger(String port) {
this.port = port;
try {
this.conn = DBusConnection.getConnection(DBusConnection.SYSTEM);
} catch (DBusException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private String getData(String item) {
BusItem bi;
String data = null;
Variant vData = null;
try {
bi = (BusItem)conn.getRemoteObject("com.victronenergy.solarcharger." + this.port, item, BusItem.class);
vData = bi.GetValue();
//data = bi.GetText();
} catch (DBusException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return data;
}
...
}
解决所有依赖关系并编译代码是一项艰巨的任务。但最终我做到了。因此,javac 现在可以正常运行。
但是如果我尝试调用方法 GetValue(),我会得到以下异常:
[Sender] INFO org.freedesktop.dbus.MessageWriter - <= MethodCall(0,1) { Path=>/org/freedesktop/DBus, Interface=>org.freedesktop.DBus, Member=>Hello, Destination=>org.freedesktop.DBus } { }
[Sender] INFO org.freedesktop.dbus.MessageWriter - <= MethodCall(0,3) { Path=>/Dc/0/Voltage, Interface=>javadbus.BusItem, Member=>GetValue, Destination=>com.victronenergy.solarcharger.ttyUSB0 } { }
Exception in thread "main" org.freedesktop.DBus$Error$UnknownMethod: Method "GetValue" with signature "" on interface "javadbus.BusItem" doesn't exist
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.freedesktop.dbus.Error.getException(Error.java:141)
at org.freedesktop.dbus.Error.throwException(Error.java:171)
at org.freedesktop.dbus.RemoteInvocationHandler.executeRemoteMethod(RemoteInvocationHandler.java:158)
at org.freedesktop.dbus.RemoteInvocationHandler.invoke(RemoteInvocationHandler.java:222)
at com.sun.proxy.$Proxy1.GetValue(Unknown Source)
at javadbus.VictronEnergyDBusSolarCharger.getData(VictronEnergyDBusSolarCharger.java:28)
at javadbus.VictronEnergyDBusSolarCharger.getDcV(VictronEnergyDBusSolarCharger.java:38)
at javadbus.MainClass.main(MainClass.java:7)
是否需要实现此方法GetValue?但是为什么例如我该怎么做?我只想获取此信息,而不是像服务器一样提供它。
为什么获取所有依赖项是一项艰巨的任务? dbus-java 库和依赖项都可以在 maven central 获得,所以一个合适的 maven 项目应该开箱即用。
返回主题:
您不必实施 GetValue()
,但您需要一个适合 BusItem
的 java 接口。
据我在 victronerynergy (https://www.victronenergy.com/live/open_source:ccgx:d-bus) 的文档中看到的,您的界面不正确。
您提供了 SetDefault()
/GetDefault()
方法,这些方法仅在 com.victronenergy.settings
对象上可用,但您想要检索一个 com.victronenergy.BusItem
(com.victronenergy.settings
包)。
这是一个错误。第二个错误是:你为 BusItem
class.
在您的情况下,DBus 将尝试解析路径为 javadbus.BusItem
的对象,该路径不是由连接的 BusAddress com.victronenergy.solarcharger.ttyUSB0
.
BusItem
class 必须在包 com.victronenergy
中,否则您必须使用注释 @DBusInterfaceName("com.victronenergy.BusItem")
.
注释将告诉 DBus 库忽略 java package/class 名称并使用注释中提供的名称。
Interface BusItem 是由 CreateInterface-Script 从 https://dbus.freedesktop.org/doc/dbus-java/dbus-java/dbus-javase10.html 创建的,XML 来自 Introspect()
但是你解决了我真正的问题。我现在使用注释@DBusInterfaceName("com.victronenergy.BusItem")。不再例外,我从我的太阳能充电器获取数据。非常感谢!