B4J Question Help building a jar file to call from B4J

cjpryor

Active Member
Licensed User
So, I have built a jar file named PrintPageReportWrapper.jar that I can execute from a command line with java -jar PrintPageReportWrapper.jar. Unfortunately, I have never had to go beyond this point in my java development other than deploying the jar file to desktop computers.

I am now trying to run one of the internal methods from B4J and can't seem to get past some java exceptions. Here are my B4X code attempts and the results. I have tried other combinations but I think one of these should work.

Can someone tell me what I am doing wrong (either in the java program and/or B4J)?

Of course I started by copying my jar file to the ... B4X\additionallibraries\B4X folder and adding the following to main:

#AdditionalJar: PrintPageReportWrapper

Not sure how to properly insert code in these posts ...

First approach:

{code}

Dim jo As JavaObject
jo = jo.InitializeStatic("net.nmcollector.printpagereportwrapper.PrintPageReportWrapper")

jo.RunMethod("openPrintPageReport", Array(sqlConnectionString, MainPage.selectedCollectionId, MainPage.selectedItemId, MainPage.selectedTab, MainPage.tabLabelsList.Get(MainPage.selectedTab) & ": " & B4XFloatTextFieldItemListValue.text))

{/code}

Stack Trace:

Error occurred on line: 389 (B4XFloatTextField)
java.lang.RuntimeException: Method: openPrintPageReport not matched.
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:130)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:676)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:240)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:108)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
at anywheresoftware.b4a.BA$1.run(BA.java:233)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)

Second approach:

{code}

Dim jo As JavaObject
jo = jo.InitializeStatic("net.nmcollector.printpagereportwrapper.PrintPageReportWrapper")

jo = jo.GetFieldJO("INSTANCE")

jo.RunMethod("openPrintPageReport", Array(sqlConnectionString, MainPage.selectedCollectionId, MainPage.selectedItemId, MainPage.selectedTab, MainPage.tabLabelsList.Get(MainPage.selectedTab) & ": " & B4XFloatTextFieldItemListValue.text))

{/code}

Stack Trace:

java.lang.RuntimeException: Field: INSTANCE not found in: net.nmcollector.printpagereportwrapper.PrintPageReportWrapper
at anywheresoftware.b4j.object.JavaObject$FieldCache.getField(JavaObject.java:307)
at anywheresoftware.b4j.object.JavaObject.GetField(JavaObject.java:182)
at anywheresoftware.b4j.object.JavaObject.GetFieldJO(JavaObject.java:189)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:632)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:234)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:108)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
at anywheresoftware.b4a.BA$1.run(BA.java:233)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:834)

Here is a peak at my class definition:

{code}

public class PrintPageReportWrapper {

public static final PrintPageReportWrapper INSTANCE = new PrintPageReportWrapper();

private PrintPageReportWrapper() {}

{/code}

Here is a link to a zip file with my entire IntelliJ project for the java program including source code and the generated jar file: https://nmcollectorsoftware.us/downloads/PrintPageReportWrapper.zip

Thanks!
 

stevel05

Expert
Licensed User
Longtime User
The error:

java.lang.RuntimeException: Method: openPrintPageReport not matched

suggests that it has found the class, but one of the variables passed to the method is of the wrong type. So the first thing to do is to check that the variables you are passing are of the correct type. There is no automatic casting in Java, so if for instance the MainPage.selectedCollectionId is a double and the method requires an Int, it will give you this error.
 
Upvote 0

cjpryor

Active Member
Licensed User
The error:

java.lang.RuntimeException: Method: openPrintPageReport not matched

suggests that it has found the class, but one of the variables passed to the method is of the wrong type. So the first thing to do is to check that the variables you are passing are of the correct type. There is no automatic casting in Java, so if for instance the MainPage.selectedCollectionId is a double and the method requires an Int, it will give you this error.
Thanks - should all be string but tried this to make it more explicit ... same error. I also verified that the number of arguments matched.

Dim argsArray(5) As String

argsArray(0) = sqlConnectionString
argsArray(1) = MainPage.selectedCollectionId
argsArray(2) = MainPage.selectedItemId
argsArray(3) = MainPage.selectedTab
argsArray(4) = MainPage.tabLabelsList.Get(MainPage.selectedTab) & ": " & B4XFloatTextFieldItemListValue.text

jo.RunMethod("openPrintPageReport", argsArray)

Given the stack trace I was wondering if it was a B4X internal error message ...

Any other suggestions? I am wondering if I am configuring something wrong in my jar file ...

Thanks again!
 
Upvote 0

cjpryor

Active Member
Licensed User
Tomorrow I will set up a method in the jar file that requires no parameters to see if I can get that to work.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
I don't have IntelliJ but found the java file within it. The method requires a string array it still needs to be wrapped in an object array when it is passed.

Try jo.RunMethod("openPrintPageReport", Array(argsArray))

or

jo.RunMethod("openPrintPageReport", Array(Array As String(sqlConnectionString, MainPage.selectedCollectionId, MainPage.selectedItemId, MainPage.selectedTab, MainPage.tabLabelsList.Get(MainPage.selectedTab) & ": " & B4XFloatTextFieldItemListValue.text)))
 
Last edited:
Upvote 0

cjpryor

Active Member
Licensed User
I don't have IntelliJ but found the java file within it. The method requires a string array it still needs to be wrapped in an object when it is passed.

Try jo.RunMethod("openPrintPageReport", Array(argsArray))

or

jo.RunMethod("openPrintPageReport", Array(Array As string(sqlConnectionString, MainPage.selectedCollectionId, MainPage.selectedItemId, MainPage.selectedTab, MainPage.tabLabelsList.Get(MainPage.selectedTab) & ": " & B4XFloatTextFieldItemListValue.text)))
That's it!!!! Thank you!!!! Sending donation now!

Clay
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Great I'm glad it works, and thanks for the donation.
 
Upvote 0

cjpryor

Active Member
Licensed User
So, I was working with a jar because I am experiencing a problem with using a purpose built Library. See https://www.b4x.com/android/forum/t...j-development-environment.135940/#post-859777

Unfortunately, I am seeing the exact same issue when I run my deployed B4J application using this stand alone jar as I do with the library.

I am going to update the original post rather then this one because the original has more context for the issue I am trying to resolve.

Thanks
 
Upvote 0
Top