Based on the above, it seems that Jav223 does the opposite as JS Scripting and it creates a separate Script Engine for each transformation but reuses the same one for the rules.
I demonstrated what happens, if a sitemap contains three distinct inline transformations. If I create the file openhab/transformations/u.java with content return "Rere"; and a sitemap with content:
sitemap b label="B4" {
Text item=x label="U1a [JAVA(u.java):%s]"
Text item=x label="U2d [JAVA(u.java):%s]"
Text item=x label="U3d [JAVA(u.java):%s]"
}
then the Java223ScriptEngineFactory.createScriptEngine() is executed once and the constructor of Java223ScriptEngine is also executed once. In this case the three (identical) transformations from the sitemap are executed within the same ScriptEngine instance.
My feeling is that a new ScriptEngine instance is created for each new input: for each new file (e.g. under transformations/ or under automation/jsr223/) and each new inline data (e.g. inline transformation as in Text item=x label="U [JAVA(|return \"A\";):%s]"). If a file under automation/jsr223/ installs with ScriptedAutomationManager automationManager 100 rules, all of these rules will be executed in a single ScriptEngine instance. If there was an equivalent ScriptedTransformationManager transformationManager and the very same file has installed 100 transformations, all 100 rules and all 100 transformations would have been executed in the same ScriptEngine instance.
The current behavior for pythonscripting is that for each script file a new PythonScriptEngine is created. A python script inside the folder automation/pythonjsr223 will processed using the eval function. This is the moment when the lock is acquired and stays active until the script engine is closed on script reload. During this livetime, just the python context exists. If you created rules inside these script file, they are registered as class and function objects inside the rule automation manager. All follow up processing happens asynchron in the same thread context as the initial event was triggered. If I remember correctly, there is also somewhere a config option to specify the amount of queue threads. If you create Timer or Thread objects, they run asynchron too.
The behavior of a transformation script is a bit different. Here, for each script file a new PythonScriptEngine is created. If more then one transformation is using the same script file, they “share” the script context. The first time that the lock is acquired, is during the initial processing. Instead of calling eval, we call compile and cache the result. Now, each time a transformation happens, the eval is called again on the compiled version. Here is the possible situation where a script is not running asynchron.
But of course, asynchron in python, means its using the Global Interpreter Lock.
Yes, allowInstanceReuse, has you guessed, is irrelevant in automation/jsr223/.java files (the scripts are executed only once). And so, irrelevant for rules defined inside.
That said, with the help of all these comments, and some tests, it is now clearer for me.
I my previous warning in the README, I extrapolated erroneously from an isolated incident to a broader context, and I had a wrong view of concurrency issues in openHAB scripting. Turns out it is way more narrow than I thought first. Now I think that (in the case of the Java223 bundle) the potential race or concurrence issue, and the corresponding need for lock, may arise ONLY if several rules share the same script and use the same class field. All other cases are guarded by openHAB
(except of course when users create thread or timer themselves)
So, I added some precisions in the README. (Sorry for last time, I didn’t push my modifications so you couldn’t see them. I rewrote and force pushed today).
As Rich already answer, yes: openHAB prevent the rule from running twice at the same time, but timers or code running in other thread are not limited. So without locking, the other thread (or timer) can be relaunched, even if the other is still running.
Rich seems to say that it is still the case. I don’t know, but anyway, the answer is shared by all JSR223 langages, as Java223 doesn’t have anything to say in that matter, and doesn’t add protection.
I disagree. For me, it doesn’t add any difficulty, but it adds options.
Sharing value between executions allows having ‘state’, which is a great deal for many use case. Rules does have it (by nature, as their “action” part always run on the same instance), and this options allows transformations/profile to also have it and store data. And from what I’m reading, sharing value between execution is in fact the default behaviour for JS, as said here:
And now that the subject of lock is clearer, unless I miss something again, we saw that concurrency issue may arise ONLY with SEVERAL rules defined in the same script (so, exactly when allowInstanceReuse doesn’t do anything)
All others way of running a script concurrently seems to be guarded against.
This watch event handler is for a very specific use case: it is only used to know if a file has been deleted or modified manually, for the library generation process to recreate or overwrite it the next time it is called.. The “creation” part is already handled by the sourceHasChange method (name is not very precise, I will change it for sourceHasChangeOrIsNew)
No. Only a single thread can enter/use a ScriptEngine at any time, but every ScriptAction or ScriptCondition gets its own ScriptEngine instance, so the synchronisation only ensures that this single action or condition does not run in parallel. For JSR223 (.js files), every file gets its own script engine, so only one rule from a single file can execute at a given time. Since rule executions usually are really fast, this is usually no problem, though I would not recommend putting all your JSR223 rules into a single file.
From my experience there is no noticeable bottleneck there, having a file that contains several rules querying persistence (and therefore blocking for some time).
I answered there. I agree that the current behaviour is not optimal, but I think the issue is a bit different.
I would suspect that the JSR223 Java binding does not properly handle changes to transformations files.
I think the lock is applied there as well. Script Actions and Conditions basically have no other way of running then through their execute method, and in there is the locking logic.
But until openHAB 4.2 or something like that that statement would have been correct.
See my statement before citing you.
Running multiple is safe and they normally are fully independent of each other. In case of GraalVM, your ScriptEngine implementation is wrapping a Graal Polyglot Context, and multiple Polyglot Contexts might share one underlying Polyglot Engine. Sharing a Polyglot Engine is safe even in multiple threads.
Wrt to creation and memory consumption: There is some overhead to be expected, though I haven‘t seen anyone running into serious trouble there. But that‘s an important reason to keep helper libraries, or at least the part of them that is automatically loaded, small (few hundred KBs). For example, if we would load JS-Joda Locales by default (they are pretty huge) that would cause a measurable heap usage with many engines. Now with injection caching in JS Scripting I am not sure if the helper library actually consumes per engine or only once.
Exactly. SCRIPT transformations are entirely handled by core, the automation add-ons only provide a ScriptEngine to handle a language. How the script engine handles locking, amount of engines etc. is the „decision“ of core.
I have the feeling though that each transformation script and each unique inline transformation gets its own engine. That‘s based on the value of oh.engine-identifier (unique for an engine) corresponds to the hash code of inline scripts.
But wrt to the SCRIPT transformation I am far from expert, but if you have questions about rule and scripts, feel free to ask. I have touched most of the relevant core code.
With this test, when creating/modifying the file in automation/jsr223/m.java, openHAB and the java223 bundle compile your code (alongside the libraries found in the lib dir), and execute it.
During execution, your code registers a Rule with an execute method that makes use of the library. The library is in the classloader dedicated for the script and CANNOT be changed.
It means that if your library is modified, then a recompilation must occurs, and the rule must be fully deleted/recreated. And it means that the source file openHAB script in automation/jsr223/m.java has to be recompiled and executed by openHAB, again.
AFAIK, openHAB doesn’t have a way to recompile and reexecute files in automation/jsr223/ after the first execution. So you have to force openHAB to do so by “touching” the files defining the rule.
I don’t know if other JSR223 langages have a way around this limitation ?
AFAIK, the openHAB JSR223 dependency tracker system is NOT used for transformations (transformations are not recompiled/recreated when a dependency changes).
Does it work for js scripting ? If so, how ?
That’s a case where the rule is called directly. Other cases include when a rule calls another ruler (e.g. rules.runRule() in JS) and I think also when the rule is manually run, though MainUI might have some additional protections here (i.e. it won’t let you manually run a rule if it’s already running).
Another option and I think the preferred way to store state like that is using the cache. The private cache is useful for a rule that needs state just for itself and the shared cache for cases where multiple rules need the same data.
However, in JS that opens up a problem as Objects placed into the shared cache cannot be accessed by multiple threads so the shared cache is really only suitable for primitives for JS at least.
The cache has the advantage in that timers are automatically cancelled when the rule is unloaded instead of leaving them orphaned only to throw an exception later when they try to run but the rule context is gone.
Are you really sure about this? That’s not what it looks to me that ScriptEngineManager is doing, it will only hold one instance for each “type” of ScriptEngine. That said, I see now it disposes of the one it already holds if it’s asked to create a new one, so I guess it’s possible to use to create new ones all the time.
I find it all puzzling to be honest, I don’t know how the rules are for the other JSR223 implementations (I just discovered that GraalVM isn’t really JSR223 either), but GraalVM keeps claiming that you don’t need to use different script engines as long as you keep the contexts separate. But, then it wouldn’t work to use the default context of course. It looks to me like this could be handled quite differently than it is, with better performance and flexibility, but I still don’t have to full picture, so I might be missing pieces of the puzzle.
When it comes to helper libraries, I read something about GraalVM where you could share “Sources” (aka helper libraries) between contexts, as long as they ran on the same script engine. That might be an optimalization that would be available if new script engines weren’t created all the time.
But woulnd’t that mean that no two JS scripts could run at the same time? It would be like putting all your JS rules in one file as described above. Engineering is always finding a balance but I suspect that if only one JS script could run at a time the latency for even modest openHAB configurations would become too great.
With the currently implemented engine lock, yes. But, I don’t think it’s needed or that’s the way GraalVM is intended to be used. I think the protections should be around the context instead, and that would allow sharing the libs, from what I can understand when reading about GraalVM.
By the way, I read yesterday that GraalVM in its current form is being discontinued after Java 24. Just the kind of BS that makes it hopeless to use any of these “modern technologies”, they last about as long as a firefly.
From the little I understood among all the marketing jargon and hype words is that the “community edition part” of GraalVM will be moved to OpenJDK itself, so what OH is using will probably still be available in some form, but there will probably be yet more incompatibility between Java versions and how to access it all/what it’s called.
The Java223 automation bundle, in conjunction with openHAB, works like this:
receives a .java script
compiles it (if not already done). openHAB will then store the compilation unit for further (and fastest) reuse.
Can a received .java file already be compiled, only if it is in automation/lib/java ? Does the above say, than unused .java files from automation/lib/java are kept compiled in memory?
openHAB prevents several executions of the same script at the same time.
This is also the case for transformations/profile (the second transformation will wait for the first to finish). This can be an issue, especially if your script takes some non-negligible time to execute.
Why does openHAB-core prevent execution of one and the same transformation in parallel? Let’s say if many channels use the same transformation (the same file under transformation/), or many items use the same transformation, or many items in a sitemap label=[…] use the same trasformation, to increase parallelism does one have to create identical copies of the transformation? E.g. in file based transformation, create a copies of the file, and then call alternating the original transformation or its copy?
Back to allowInstanceReuse
I understand what this option means, but I cannot think of use cases, where it makes sense to use or not to utilize it. With the parallelism questions now clarified, can you add an example, explaining why for this example it is good to have allowInstanceReuse false. And another example, explaining why for it is advantegeous when allowInstanceReuse is enabled.
(from org.openhab.automation.java223/src/main/resources/OH-INF/addon/addon.xml): Reuse a script instance if found in the cache. Allow sharing data between subsequent executions. Note: Beware of concurrency issues
Now I think that (in the case of the Java223 bundle) the potential race or concurrence issue, and the corresponding need for lock, may arise ONLY if several rules share the same script and use the same class field. All other cases are guarded by openHAB. (except of course when users create thread or timer themselves)
And now that the subject of lock is clearer, unless I miss something again, we saw that concurrency issue may arise ONLY with SEVERAL rules defined in the same script (so, exactly when allowInstanceReuse doesn’t do anything)
Can at least the “Note: Beware of concurrency issues” above be removed?
All the other OH automation add-ons do not have similar option, even if they have the same notion of ScriptEngine instances. Can you provide arguments, why the other OH Automation add-ons should implement similar instance reuse option?
Dependency tracking
What the other automation add-ons have, which Java223 lacks, is whether to enable or disable dependency tracking for imported files.
AFAIK, openHAB doesn’t have a way to recompile and reexecute files in automation/jsr223/ after the first execution. So you have to force openHAB to do so by “touching” the files defining the rule.
Can the dependency be converted to bytecode and then the class loader of the jsr223/.java file updated, to provide the updated bytecode of the dependency, without recompiling the jsr223/.java file?
Does Java223 have any form of dependency tracking, which can be demonstrated by a working example?
Many .rules files
Are these ScriptEngine instances also relevant for .rules files? Does creating more openhab/rules/.rules files use more ScriptEngine instances, compared to putting the same input in a single rules/.rules file?
I have the feeling though that each transformation script and each unique inline transformation gets its own engine.
I have the same feeling. Each distinct input source, e.a. a snippet/subobject in jsondb, creates a separate ScriptEngine instance.
Where are the JSR223 Java transformations stored?
In openhab/transform/*.java or inline with JAVA(|...):%s.
About automation/lib/java
All other automation addons use automation/python, automation/js, automation/groovy, so the lib/ from automation/lib/java can be skipped.
When I create a file, Java223 logs:
2025-10-01 13:42:50.876 [TRACE] [internal.codegeneration.SourceWriter] - Received ‘CREATE’ for path ‘/etc/openhab/automation/lib/java/z.java’ - ignoring (wrong extension or unused event kind)
z.java is later correctly utilized, when used from a jsr223/.java file. I find it misleading to log, that a file is ignored, especially in case it is compiled and cached, and in fact the file is not ignored, when it is used (or changed).
That’s not what it looks to me that ScriptEngineManager is doing, it will only hold one instance for each “type” of ScriptEngine. That said, I see now it disposes of the one it already holds if it’s asked to create a new one, so I guess it’s possible to use to create new ones all the time.
You can set a log, which triggers whenever …Factory.createScriptEngine() / new …ScriptEngine() is called. I tried it, a ScriptEngineFactory calls many times new …ScriptEngine().
Not all of them. The old ones, i.e. Nashorn JS and Jython, use automation/jsr223/js and autiomation/jsr223/python IIRC. And automation/lib was where the helper libraries and other stuff needed for either of these went. If this add-on is following this standard using automation/lib.java is not out of the norm, particularly for a jsr223 automation add-on.
I haven‘t looked what ScriptEngineManager does, but the AbstractScriptModuleHandler asks the ScriptEnginerManager to create an engine for the script type and uses a random UUID as the engine identifier, so (as longs as there is no UUID collision, which is highly unlikely) each ScriptActionHandler and each ScriptConditionHandler uses its own script engine.
As openHAB‘s scripting architecture is designed around the ScriptEngine interface, it makes sense to simply provide a ScriptEngine implementation based on GraalJS. And the general script engine architecture is there since the experimental rule engine was added in openHAB 2.4 or something like that IIRC.
The GraalJSScriptEngine is basically a wrapper around a GraalVM Polyglot Context, and the GraalVM Polylot Engine used under the hood is already shared across all GraalJSScriptEngines. FYI, Python Scripting provides no ScriptEngine implementation, so @holger_hees simply build one around the GraalVM Polyglot Context.
And as we need separate contexts, we can also keep separate engines.
I think you refer to what I implemented in https://github.com/openhab/openhab-addons/pull/14135. We load the helper library into a org.graalvm.polyglot.Source, which then is shared across all places where we inject the helper library. Since we share the underlying Polyglot Engine, there is some caching and sharing, which also speeds up helper library injection.
Please note the difference between a ScriptEngine and a GraalVM Polyglot Engine. I know the wording is quite confusing, but ScriptEngine is the interface and expected by openHAB Core, GraalVM Polyglot Engine is something used internally by Graal to run the code.
They are around that. Python Scripting is only wrapping a context to provide a ScriptEngine compliant implementation, for JS Graal was so kind to do that.
Yes, it seems you’re right. I don’t quite get the point of “managing” them if new ones are created for everything, but this might have been handled differently in the past. This seems very wasteful to me though, but I don’t know the real cost of creating all these script engines.
Sure, it is accessed through JSR223/ScriptEngine and that’s fine, but as I understand it, that’s not where the “synchronization requirements” come from? Other JSR223 languages can run fine without isolating every script engine instance, as far as I understand.
Ah, so “context” and “context” are different concepts? There is a JSR223 “context” concept, and there is also GraalVM Polyglot Context, which is effectively wrapped in a ScriptEngine? That certainly complicates things, if the concepts work so differently for GraalVM and non-GraalVM languages. Have you (or anybody else) look at how this will be organized when it’s moved to OpenJDK?
Yes, the concepts are very confusing. OH Core use JSR223 and its concepts, while GraalVM doesn’t really do that, and have just made some “cheap adapter” to JSR223 to speed up adoption, while at the same time arguing that people shouldn’t use it this way.
I don’t have the necessary overview to evaluate this at all, but it might be that things would be easier if GraalVM wasn’t accessed through JSR223, and that support for GraalVM was made directly in Core instead, as an alternative to JRS223.
edit: I’ve created this topic for this instead of “polluting spaces where it doesn’t belong”:
Have you looked at how this will be organized when it’s moved to OpenJDK?
Move what to OpenJDK? The GraalVM implementations of JavaScript and Python cannot be moved out of GraalVM.
it might be that things would be easier if GraalVM wasn’t accessed through JSR223, and that support for GraalVM was made directly in code instead, as an alternative to JRS223.
I assume “code” above means “core”. Currently GraalVM is installed indirectly, when an add-on uses it — MQTT/HomeAssistant, JavaScript or Python. org.openhab.transform.jinja is also a candidate for GraalVM in order to use the Jinja Python implementation, as MQTT/HomeAssistand does, instead of jinjava.
openhab-core provides the necessary interfaces and the add-ons fit there. Integrating GraalVM somehow directly in openhab-core would increase additionally the size of openhab-core with services, which might not be needed by the user, but the user will have to load the services anyway when starting openHAB. The question is rather to move more things out of openhab-core into add-ons: as all the .ide bundles together with the Language Server, or the DSL implementation itself.
All .class compiled beforehand and inside a .jar in automation/lib/java are added to a special classloader named JarClassLoader.
Classloaders are hierarchical, and the JarClassloader is the parent (or child ? I don’t remember the direction or semantic) of each and every other dedicated classloader (one for for each script).
Unused .java files are indeed compiled in memory alongside each script. I don’t know how the JVM works after that. Are they pruned/garbage collected if no code can reach them ?
Yes, it’s a waste, but guessing in advance if a script will be needed is an impossible task.
There is room for improvement (for example, compiling all .java files located in lib, ahead of time and in a dedicated and reusable classloader ?). I personnaly won’t do it, because I spent way too much time on this bundle, and it’s IMHO a too small performance improvement . But I’m open for PR !
It is indeed what I understand from my tests. There is a lock preventing the same transformation to be executed in //, even in different context.
It seems sub optimal, but I guess it prevents some side effect I’m not aware of. For discussing this, the main contributors are a way better fit than me.
I don’t know if you mean “add a general use case” or " add a code example in the README", but I personally don’t want to provide full example for this in the README. Because it is more related to a way of coding than a real ‘feature’.
But I don’t have a strong opinion on this matter, so it’s OK if someone wants to
Don’t know if it what you want, but I will provide what I think are real use cases:
Imagine a complex transformation script with many lines of code. The user cuts his code into methods, but use class fields as shared value between them, because why not.
But he doesn’t want those computed value to alter the next transformation execution. So with instanceReuse false, a new “clean” instance will be created next time.
Imagine a transformation, but the user wants to keep some previous value. Maybe for aggregation of time series ? Or some kind of debounce ? So setting allowInstanceReuse to true helps him to keep an easy storage for next execution.
Yes he can use the openHAB shared cache. But why not using a field if he wants to ? Seems more “natural” and local.
In this bundle, one of my lead directive is to let many options available to the end-user, depending on his way of coding. For example, this is why injection of openHAB value can happen in field, method argument, or even constructor.
Indeed, good catch, I forgot this one. As this discussion made it clear, it is wrong, there is no concurrency issues and this note should be removed.
No, because it’s a coding possibility, language related. If a language gives me a possibility, I think having it is better than not having it. But it’s not mandatory, it’s just like some kind of syntactic sugar.
I read here that JS scripting keep values in variables between execution of a profile script (similar, in a way, to instanceReuse). And I won’t be surprised if other language does not. But it’s OK, because it is the way the language is designed, with its own constraints.
With the way the Java jsr223 works, the bundle HAS to instantiate a class before executing something. Because it’s how java (which is not a script langage) works. And so the possibility is derived from this implementation question : instantiate each time or one time and store it ? I prefer to let the user choose.
Other languages are more fit for writing “script” than Java, and I think they don’t need to do this instantiation thing. So having this is not a good idea for them.
TLDR : it’s not really a feature, but more of a language related quirk that we can use at our advantage.
AFAIK, no. ClassLoader prevents this : you cannot modify/update a class once it is loaded.
There may have some crazy workaround, like OSGi did with its bundle architecture and hot reload etc., but I don’t know how, and it seems overkill.
[quote=“dpa-openhab, post:72, topic:159853”]Does Java223 have any form of dependency tracking, which can be demonstrated by a working example?
[/quote]
Yes, it has the dependency tracking system implemented by openHAB.
Create a JAVA script in the GUI ‘script’ section. Make it use some code in the library.
Click run. It will compile and run. (Next executions won’t need compilation)
Modify the library. (internally, it will trigger a reset for all java ScriptEngine)
Click run. It will compile again and run with the updated lib.
(you can also use the script as the ‘action’ part of a rule, the tracking system will work the same)
It doesn’t work for transformation and profile. Seems to be an openHAB limitation.
(Ironically, the custom tracking and caching system I made, before switching to the openHAB one or two week ago, worked for everything, including transformations )
I will change the log (but as I said before, it is a trace log. IMO, trace logs are for the developer. and shouldn’t be for the end user and for normal use)
“Received ‘{}’ for path ‘{}’ - ignoring it for the purpose of tracing autogenerated source modification (wrong extension, or unused event kind)”
Thanks Rich. Indeed, I followed some other old bundle way of doing.
Don’t you all think nonetheless that a clear guideline for all JSR223 bundle should be good ? I’m not in a position to give one, but if some maintainer is willing to, I will happily comply.
Because concurrency, as always This is very sloppy programming, if you don’t want the values to apply to future runs, don’t use class fields - and if you do, protect them with locks.
Just using class fields as some kind of “global variables” to transfer information between methods is a terrible practice IMO. Pass the information needed between the methods instead.
Even if you know that the code in question won’t be accessed concurrently in the current scenario, I would be hesitant to use class fields as a lazy way to pass information between methods. This way of thinking never ends well in the long run, in my experience.
But, I see your point, people will probably do it anyway.
I saw you submitted a PR to add this to the distribution, so I decided to give it a try. After installation, I immediately ran into a problem trying to compile the most basic script from your examples. Not sure if I did something wrong.
And this version of the binding from the Marketplace:
358 │ Active │ 80 │ 5.0.0.202512301527 │ org.openhab.automation.java223
Using your SimpleClass example…
public class SimpleClass {
public void main() {
int sum = 2 + 2;
}
}
I immediately got this error in my logs…
2026-04-17 09:55:26.896 [INFO ] [ort.loader.AbstractScriptFileWatcher] - (Re-)Loading script '/opt/openhab5/conf/automation/jsr223/SimpleClass.java'
2026-04-17 09:55:26.918 [ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error during evaluation of script '/opt/openhab5/conf/automation/jsr223/SimpleClass.java': /TelegramActions.java:45: error: <identifier> expected
public boolean sendTelegramAnswer(Long replyId, String message, Long , String ) {
^
/TelegramActions.java:45: error: <identifier> expected
public boolean sendTelegramAnswer(Long replyId, String message, Long , String ) {
^
/TelegramActions.java:56: error: illegal start of expression
Object returnValue = method.invoke(thingActions, replyId, message, , );
^
/TelegramActions.java:56: error: illegal start of expression
Object returnValue = method.invoke(thingActions, replyId, message, , );
***** numerous other similar errors for Telegram and other bindings *****
/LGWebOSActions.java:148: error: <identifier> expected
public void launchApplication(String appId, String ) {
^
/LGWebOSActions.java:159: error: illegal start of expression
method.invoke(thingActions, appId, );
^
2026-04-17 09:55:26.918 [WARN ] [ort.loader.AbstractScriptFileWatcher] - Script loading error, ignoring file '/opt/openhab5/conf/automation/jsr223/SimpleClass.java'
I see in the generated code in lib/java/helper/generated/telegram/TelegramActions.java, that the method signatures are missing parameter names. For example…
/**
* Send a Telegram answer using the Telegram API.
* @param replyId
* @param message
* @param
* @param
* @return result -
*/
public boolean sendTelegramAnswer(Long replyId, String message, Long , String ) {
if (thingActions == null) {
thingActions = scriptThingActions.get(SCOPE, thingUID);
if (thingActions == null) {
throw new Java223Exception("Action is null. Thing " + thingUID + " may be of the wrong type, or not initialized ?");
}
}
try {
Class<?> thingActionClass = thingActions.getClass();
Method method = thingActionClass.getMethod("sendTelegramAnswer", Long.class, String.class, Long.class, String.class);
Object returnValue = method.invoke(thingActions, replyId, message, , );
return (boolean) returnValue;
} catch (NoSuchMethodException | SecurityException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException e) {
throw new Java223Exception("Error running action sendTelegramAnswer", e);
}
}
I also see numerous of these errors in my log, which I assume are from the Java223 code generator…
2026-04-17 10:54:08.261 [WARN ] [ernal.codegeneration.SourceGenerator] - Inputs found in module registry and real Action class doesn't have the same parameter number!
2026-04-17 10:54:08.262 [WARN ] [ernal.codegeneration.SourceGenerator] - Inputs found in module registry and real Action class doesn't have the same parameter number!
2026-04-17 10:54:08.262 [WARN ] [ernal.codegeneration.SourceGenerator] - Inputs found in module registry and real Action class doesn't have the same parameter number!
2026-04-17 10:54:08.266 [WARN ] [ernal.codegeneration.SourceGenerator] - Inputs found in module registry and real Action class doesn't have the same parameter number!
And in SourceGenerator here, it looks like you detect a problem, but you still add the parameters?
Edit: I hope I posted this in the right place. I see the last comment on this thread was a half year ago.