diff --git a/bundles/org.openhab.binding.mqtt/src/main/java/org/openhab/binding/mqtt/action/IMQTTActions.java b/bundles/org.openhab.binding.mqtt/src/main/java/org/openhab/binding/mqtt/action/IMQTTActions.java new file mode 100644 index 0000000000000..9cc1463a52e58 --- /dev/null +++ b/bundles/org.openhab.binding.mqtt/src/main/java/org/openhab/binding/mqtt/action/IMQTTActions.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.mqtt.action; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * The {@link IMQTTActions} defines the interface for all thing actions supported by the binding. + * + * @author Laurent Garnier - Initial contribution + */ +@NonNullByDefault +public interface IMQTTActions { + + public void publishMQTT(@Nullable String topic, @Nullable String value, @Nullable Boolean retain); +} diff --git a/bundles/org.openhab.binding.mqtt/src/main/java/org/openhab/binding/mqtt/action/MQTTActions.java b/bundles/org.openhab.binding.mqtt/src/main/java/org/openhab/binding/mqtt/action/MQTTActions.java index 28e34db36299b..fbcc174c64e79 100644 --- a/bundles/org.openhab.binding.mqtt/src/main/java/org/openhab/binding/mqtt/action/MQTTActions.java +++ b/bundles/org.openhab.binding.mqtt/src/main/java/org/openhab/binding/mqtt/action/MQTTActions.java @@ -12,6 +12,9 @@ */ package org.openhab.binding.mqtt.action; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.smarthome.core.thing.binding.ThingActions; @@ -25,14 +28,18 @@ import org.slf4j.LoggerFactory; /** - * This is the automation engine action handler service for the - * publishMQTT action. + * This is the automation engine action handler service for the publishMQTT action. + *
+ * Note:The static method invokeMethodOf handles the case where + * the test actions instanceof MQTTActions fails. This test can fail + * due to an issue in openHAB core v2.5.0 where the {@link MQTTActions} class + * can be loaded by a different classloader than the actions instance. * * @author David Graeff - Initial contribution */ @ThingActionsScope(name = "mqtt") @NonNullByDefault -public class MQTTActions implements ThingActions { +public class MQTTActions implements ThingActions, IMQTTActions { private final Logger logger = LoggerFactory.getLogger(MQTTActions.class); private @Nullable AbstractBrokerHandler handler; @@ -53,6 +60,7 @@ public void publishMQTT( publishMQTT(topic, value, null); } + @Override @RuleAction(label = "@text/actionLabel", description = "@text/actionDesc") public void publishMQTT( @ActionInput(name = "topic", label = "@text/actionInputTopicLabel", description = "@text/actionInputTopicDesc") @Nullable String topic, @@ -93,10 +101,25 @@ public static void publishMQTT(@Nullable ThingActions actions, @Nullable String public static void publishMQTT(@Nullable ThingActions actions, @Nullable String topic, @Nullable String value, @Nullable Boolean retain) { - if (actions instanceof MQTTActions) { - ((MQTTActions) actions).publishMQTT(topic, value, retain); - } else { - throw new IllegalArgumentException("Instance is not an MQTTActions class."); + invokeMethodOf(actions).publishMQTT(topic, value, retain); + } + + private static IMQTTActions invokeMethodOf(@Nullable ThingActions actions) { + if (actions == null) { + throw new IllegalArgumentException("actions cannot be null"); + } + if (actions.getClass().getName().equals(MQTTActions.class.getName())) { + if (actions instanceof IMQTTActions) { + return (IMQTTActions) actions; + } else { + return (IMQTTActions) Proxy.newProxyInstance(IMQTTActions.class.getClassLoader(), + new Class[] { IMQTTActions.class }, (Object proxy, Method method, Object[] args) -> { + Method m = actions.getClass().getDeclaredMethod(method.getName(), + method.getParameterTypes()); + return m.invoke(actions, args); + }); + } } + throw new IllegalArgumentException("Actions is not an instance of MQTTActions"); } }