smarthomej / addons

SmartHome/J addons for openHAB
Eclipse Public License 2.0
59 stars 23 forks source link

[javarule] Initialization sequence problem #375

Closed clinique closed 1 year ago

clinique commented 2 years ago

I created a class with a rule triggered when the status of a thing changes :

import org.openhab.binding.telegram.internal.action.TelegramActions;
import org.openhab.core.model.script.actions.Log;
import org.openhab.core.thing.ThingUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.smarthomej.automation.javarule.Things;
import org.smarthomej.automation.javarule.JavaRule;
import org.smarthomej.automation.javarule.annotation.ThingStatusChangeTrigger;
import org.smarthomej.automation.javarule.annotation.Rule;

public class Telegram extends JavaRule {
    public TelegramActions botActions;

    @Rule(name = "Telegram | Bot status changed")
    @ThingStatusChangeTrigger(thingUID = Things.telegram_telegramBot_prod)
    public void telegramBotStatusChanged() {
        String methodName = new Object() {
        }.getClass().getEnclosingMethod().getName();

        ThingUID botUID = new ThingUID(Things.telegram_telegramBot_prod);
        Thing bot = things.get(botUID);
        ThingStatus status = bot.getStatus();

        switch (status) {
            case ONLINE:
                if (botActions != null) {
                    return;
                }
                botActions = (TelegramActions) actions.get("telegram", Things.telegram_telegramBot_prod);
                break;
            default:
                if (botActions == null) {
                    return;
                }
                botActions = null;
                break;
        }

        String extraMessage;
        if (botActions != null) {
            extraMessage = "Neo4 Telegram bot actions identified.";
            send(extraMessage);
        } else {
            extraMessage = "Telegram bot actions disposed.";
        }

        Log.logInfo(methodName, "Neo4 Telegram bot went {} : {}", status, extraMessage);
    }

    private void send(String message) {
        if (botActions != null) {
            botActions.sendTelegram(message);
        }
    }
}

The rule runs fine in normal conditions but after a server restart I have a bunch of errors :

2022-06-23 12:35:27.378 [ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error during evaluation of script 'file:/etc/openhab/automation/jsr223/Telegram.java': org.smarthomej.automation.javarule.internal.compiler.CompilerException: warning: unknown enum constant org.eclipse.jdt.annotation.DefaultLocation.PARAMETER
  reason: class file for org.eclipse.jdt.annotation.DefaultLocation not found
warning: unknown enum constant org.eclipse.jdt.annotation.DefaultLocation.RETURN_TYPE
warning: unknown enum constant org.eclipse.jdt.annotation.DefaultLocation.FIELD
warning: unknown enum constant org.eclipse.jdt.annotation.DefaultLocation.TYPE_ARGUMENT
/Telegram.java:1: error: package org.openhab.binding.telegram.internal.action does not exist
import org.openhab.binding.telegram.internal.action.TelegramActions;
                                                   ^
warning: unknown enum constant org.eclipse.jdt.annotation.DefaultLocation.PARAMETER
  reason: class file for org.eclipse.jdt.annotation.DefaultLocation not found
warning: unknown enum constant org.eclipse.jdt.annotation.DefaultLocation.RETURN_TYPE
warning: unknown enum constant org.eclipse.jdt.annotation.DefaultLocation.FIELD
warning: unknown enum constant org.eclipse.jdt.annotation.DefaultLocation.TYPE_ARGUMENT
/Telegram.java:12: error: cannot find symbol
    public TelegramActions botActions;
           ^
  symbol:   class TelegramActions
  location: class Telegram
/Telegram.java:15: error: cannot find symbol
    @ThingStatusChangeTrigger(thingUID = Things.telegram_telegramBot_prod)
                                               ^
  symbol:   variable telegram_telegramBot_prod
  location: class org.smarthomej.automation.javarule.Things
/Telegram.java:20: error: cannot find symbol
        ThingUID botUID = new ThingUID(Things.telegram_telegramBot_prod);
                                             ^
  symbol:   variable telegram_telegramBot_prod
  location: class org.smarthomej.automation.javarule.Things
/Telegram.java:29: error: cannot find symbol
                botActions = (TelegramActions) actions.get("telegram", Things.telegram_telegramBot_prod);
                              ^
  symbol:   class TelegramActions
  location: class Telegram
/Telegram.java:29: error: cannot find symbol
                botActions = (TelegramActions) actions.get("telegram", Things.telegram_telegramBot_prod);
                                                                             ^
  symbol:   variable telegram_telegramBot_prod
  location: class org.smarthomej.automation.javarule.Things

In order to make it work again, I need to touch the java file after the restart is done. I suspect a prerequisite sequence could be missing. Would you have any hint ?

clinique commented 2 years ago

After further searches, I think that the problem comes from this import : import org.openhab.binding.telegram.internal.action.TelegramActions;

The binding may not be loaded when the script engine tries to compile this class.

J-N-K commented 2 years ago

That's exactly issue. The import is needed to use the actions and for compiling the class the actions class must be available (or at least it's method signatures).

The problem is that they can only be obtained at runtime, because I need to generate a wrapper class (action classes are in an internal package, so I need to access them via reflection). This is done as soon as the actions class is registered in the system.

I thought about delaying rule compilation until the system is fully initialized but the drawback is that rules that run at earlier start level could not be used.

I'm a bit astonished that you need to touch the file to get it compiling. On my systems (a plain Debian and MacOS) the rules are automatically re-compiled when the actions class becomes available. What system do you run on? And which openHAB version?

clinique commented 2 years ago

I'm on ubuntu 22.04 and OH latest milestone. I need to make a modification on the file so it recompiles once launch is finalized.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.