Java method can be invoked from Run Macro but not from execute action

I’ve been able to add a new instance of the HelloWorld Java macro to LibreOffice (jar file and parcel-descriptor.xml), following the instructions at [https://wiki.documentfoundation.org/Documentation/DevGuide/Scripting_Framework#Java] (Writing Macros Java)
I am able to execute the macro using Tools>Macros>Run Macro. The Java method executes and produces the expected result

However, when I add the macro to the execute action on a button in a form (in base), a button click produces an error dialog with the message:

A Scripting Framework error occurred while running the Java script org.libreoffice.example.java_scripts.HelloWorld.printHelloWorld.
Message: java.lang.NoSuchMethodException: StrictResolver.getProxy: Can’t find method: printHelloWorld

There is a another version of HelloWorld that is deployed as part of the LibreOffice installation. It exhibits the same behaviour: Run Macro works as expected but Execute Action produces NoSuchMethodException.

There is an old reference to this issue at the end of [https://forum.openoffice.org/en/forum/viewtopic.php?t=1844]( [Java] OOo Writer and Calc macro examples) but the symptom and solution reported there are not believable.

Version: 24.2.3.2 (X86_64) / LibreOffice Community
Build ID: 433d9c2ded56988e8a90e6b2e771ee4e6a5ab2ba
CPU threads: 8; OS: Windows 10.0 Build 22631; UI render: Skia/Raster; VCL: win
Locale: en-CA (en_CA); UI: en-US
Calc: threaded

I’m using IntelliJ Idea with Java language level: 8, jdk: Eclipse Adoptium jdk-11.0.14.101

(cmdline) java --version reports
openjdk 11.0.14.1 2022-02-08
OpenJDK Runtime Environment Temurin-11.0.14.1+1 (build 11.0.14.1+1)
OpenJDK 64-Bit Server VM Temurin-11.0.14.1+1 (build 11.0.14.1+1, mixed mode)

so this is presumably what LibreOffice found upon installation.

I’m not aware how Java macros run, but in python and also in basic, the macros have to be call with an argument also if the argument is not used. Perhaps that could be your problem

* **Java**: The arguments are passed as an `Object[]` in the second parameter to the macro method

public void handleButtonPress( XScriptContext xScriptContext, Object[] args)

Is there a bug report about it? Without such a report, no amount of forum discussions would ever fix that.

@jucasaca Thank you for your observation. The Java method is currently defined as
public static void printHelloWorld(XScriptContext xScriptContext) {...}
This method runs from Run Macro but not as an execute action. When I add Object[] as the second parameter to the Java method, Run Macro is unable to find the function.

  • I have not found a way to pass an empty array as a parameter from Run Macro.
  • I have not found a way to pass an empty array as a parameter from an execute action
  • I have not found a way to pass an empty array as a parameter from Basic, and this, in any case, would defeat the usefulness of being able to call a Java method without involving a Basic Macro.

I would suggest the intent of public static void printHelloWorld(XScriptContext xScriptContext, Object[] param) is to emulate public static void printHelloWorld(XScriptContext xScriptContext, Object...param) which expects any number of Object parameters including zero. Surely this is what is happening in the Run Macro case.

@mikekaganski Thank you for the suggestion. I haven’t found a bug report on this topic. I believe it would be premature to file one before first attempting to find out from the community if anyone has any experience with this issue. However, I will do so if I can’t find an answer here.

Interestingly,

The Document Foundation estimates that there are 200 million active LibreOffice users worldwide, about 25% of whom are students and 10% are Linux users. Wikipedia

I find it hard to believe that I’m the first person to try to call Java from an execute action.

Just overload a variant with an unused second argument.

@mikekaganski Thank you. I’ll experiment with overloading the method. It’s curious that none of the documentation mentions this.

Our documentation is not a reference to the various programming languages - only about LibreOffice specifics. But improvements are always welcome.

@mikekaganski I tried adding an overloaded method as you suggested. No joy.

Looking at parcel-descriptor.xml, there is a line
<functionname value="org.libreoffice.example.java_scripts.HelloWorld.printHelloWorld"/>
which allows one to specify the package path and name of a static method, but not its parameters.

I have to push back just a wee bit on your comment about LibreOffice documentation not being a reference for various programming languages. The problem here is not the Java language, which is very well documented. It’s about the part of LibreOffice that specifies that Java methods can be called. The Java example I tried is in the distribution of LibreOffice and I would therefore expect the example to be documented on the LibreOffice side of things, say, here. I would be happy if someone would just say “you can’t call Java from an Execute Action” and I can stop wasting my time. Or indicate that I’m looking in the wrong part of the documentation by providing a reference to the right part. But I find finger pointing to be unhelpful and, frankly, dismissive.

It works.
I needed only to overload the method with the correct expected arguments. Indeed, that’s not Object[] args, because button click events take a com.sun.star.awt.ActionEvent argument (because the button listener implements com.sun.star.awt.XActionListener interface - see also general Events section in the manual).

So my simple Java looks like this (modified from the bundled example):

package org.libreoffice.example.java_scripts;

import com.sun.star.awt.ActionEvent;
import com.sun.star.script.provider.XScriptContext;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.text.XTextDocument;
import com.sun.star.text.XTextRange;
import com.sun.star.text.XText;

public class HelloWorld {
    private static void printHW_Impl(XScriptContext xSc, String string) {
        XTextDocument xtextdocument = (XTextDocument) UnoRuntime.queryInterface(
                                          XTextDocument.class, xSc.getDocument());
        XText xText = xtextdocument.getText();
        XTextRange xTextRange = xText.getEnd();
        xTextRange.setString(string);
    }

    public static void printHW(XScriptContext xSc) {
        printHW_Impl(xSc, "Hello World (in Java) - one-argument version");
    }

    public static void printHW(XScriptContext xSc, com.sun.star.awt.ActionEvent args) {
        printHW_Impl(xSc, "Hello World (in Java) - two-argument version");
    }
}

You are replying to a very specific answer, which I wrote to another very specific comment of yours, where you wrote specifically answering my other comment, that the information about overloading as a way to provide different variants of a function for different cases (some taking no arguments other than the script context, others taking some) is not mentioned in our documentation. So please, please, think twice before “pushing back”. If your super-short “this” in your “none of the documentation mentions this” meant something different than what my comment told, then it’s not my answer was “dismissive”, it’s your words were unclear. So please take this part as my symmetrical pushback.