I have completed the development of a custom Library for my own internal usage. Thanks @Erel !!!
It works great in all modes on all platforms including the deployed packages EXCEPT when it is deployed to Linux. In that case I am stuck on the following error even though I added the necessary argument to the release_java_modules.txt file of my B4JPackager11 Project.
More details:
My java code:
My B4JPackager11 release_java_modules.txt contents
Only issues I encounter are on Linux ... as follows:
When running on Linux Using B4J Bridge
- with #PackagerProperty: VMArgs = --add-opens b4j/net.sf.jasperreports.engine.fill=ALL-UNNAMED in B4J Main
- Reports work running in Debug, Release, and Release (obfuscated) Modes with following warning
- (java:2474): Gdk-WARNING **: 16:50:09.054: XSetErrorHandler() called with a GDK error trap pushed. Don't do that.
- which is logged after return from call to ReportWrapperLibrary
- similar issue found here: https://stackoverflow.com/questions/55446534/how-to-fix-java22494-gdk-warning
When running release on Linux
- Built from standalone package built in B4J
- Using B4JPackager11 project from within B4J pointing to jar on Linux
I saw a post where adding --add-opens b4j/net.sf.jasperreports.engine.fill=ALL-UNNAMED to another persons release_java_modules.txt file solved the "module b4j does not export net.sf.jasperreports.engine.fill to unnamed module @0x5219dd7f" error for them but it does not seem to be working for me.
Thanks in advance for any help!
It works great in all modes on all platforms including the deployed packages EXCEPT when it is deployed to Linux. In that case I am stuck on the following error even though I added the necessary argument to the release_java_modules.txt file of my B4JPackager11 Project.
More details:
My java code:
Java:
package net.nmcollector.reportwrapper;
import anywheresoftware.b4a.BA.DependsOn;
import anywheresoftware.b4a.BA.ShortName;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.view.JasperViewer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.HashMap;
@ShortName("ReportWrapper")
@DependsOn(values= {
"jasperreports-6.17.0.jar",
"jasperreports-fonts-6.17.0.jar",
"commons-collections4-4.4.jar",
"commons-digester-2.1.jar",
"commons-logging-1.2.1.1.jar",
"sqlite-jdbc-3.23.1.jar"
})
public class ReportWrapper {
public static void main(String[] args) {
System.out.println("Hello from net.nmcollector.cpReports main");
for (int i = 0; i < args.length; i++) {
System.out.println(("main - value of args( " + i + "): " + args[i]) );
}
String[] str = new String[5];
if (args.length==0){
//Windows Development Machine
str[0] = "C:\\Users\\cjpry\\AppData\\Roaming\\nmcollector\\nmcswDB.sqlite";
str[1] = "C:\\Users\\cjpry\\AppData\\Roaming\\nmcollector\\Reports\\";
//generic widnows machine after copying files
//str[0] = "C:\\data\\database\\nmcswDB.sqlite";
//str[1] = "C:\\data\\reports\\MyReports\\";
//Linux
//str[0] = "/home/nmcollector/tempjars/nmcswDB.sqlite";
//str[1] = "/home/nmcollector/tempjars/";
str[2] = "Inventory.jasper";
str[3] = "1";
str[4] = "1";
} else {
str = args;
}
int returnCode = openReport(str);
System.out.println("call to openReport returnCode = " + returnCode);
}
/**
*
* @param args
* @return result (0 for success, -1 for failure)
*
* Takes arguments for a NM Collector CP defined report and displays it
*
*/
public static int openReport(String[] args) {
int returnCode = -1;
System.out.println("Hello from net.nmcollector.cpReports openReport");
for (int i = 0; i < args.length; i++) {
System.out.println(("openReport value of args( " + i + "): " + args[i]) );
}
String jasperReport = args[1] + args[2];
System.out.println("net.nmcollector.cpReports openReport jasperReport = " + jasperReport);
String datasourceConnectionString = args[0];
System.out.println("net.nmcollector.cpReports openReport datasourceConnectionString = " + datasourceConnectionString);
// Parameters for report
//Map<String, Object> parameters = new HashMap<>();
HashMap parameters = new HashMap();
parameters.put("collectionId",Integer.parseInt(args[3]));
parameters.put("selectedItemId",Integer.parseInt(args[4]));
parameters.put("SUBREPORT_DIR",args[1]);
System.out.println("net.nmcollector.cpReports openReport parameters loaded");
// DataSource
Connection conn = null;
JasperPrint jasperPrint;
try {
String url = "jdbc:sqlite:" + datasourceConnectionString;
System.out.println("net.nmcollector.cpReports openReport url = " + url);
conn = DriverManager.getConnection(url);
System.out.println("net.nmcollector.cpReports openReport conn loaded");
} catch (Exception e) {
System.out.println("SQL connection error:" + e.getMessage());
}
try {
System.out.println("net.nmcollector.cpReports openReport ********* B4J Release Fails Here ********** call JasperPrint");
jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, conn);
//System.out.println("net.nmcollector.cpReports openReport declare and initialize JasperViewer");
//JasperViewer jv = new JasperViewer( jasperPrint, false );
System.out.println("net.nmcollector.cpReports openReport call JasperViewer");
JasperViewer.viewReport( jasperPrint, false );
returnCode=0;
} catch (Exception e) {
System.out.println("Jasper Reports error:" + e.getMessage());
}
return returnCode;
}
}
My B4JPackager11 release_java_modules.txt contents
--add-opens b4j/net.sf.jasperreports.engine.fill=ALL-UNNAMED --add-opens java.desktop/sun.awt=ALL-UNNAMED --add-opens javafx.controls/com.sun.javafx.scene.control.inputmap=ALL-UNNAMED --add-opens javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED --add-opens javafx.controls/com.sun.javafx.scene.control.behavior=ALL-UNNAMED --add-opens javafx.graphics/com.sun.javafx.scene.traversal=ALL-UNNAMED --add-opens javafx.graphics/javafx.scene=ALL-UNNAMED --add-opens javafx.base/com.sun.javafx.collections=ALL-UNNAMED --add-opens javafx.controls/com.sun.javafx.scene.control=ALL-UNNAMED --add-opens javafx.base/com.sun.javafx.event=ALL-UNNAMED --add-opens javafx.graphics/com.sun.javafx.css=ALL-UNNAMED --add-opens javafx.base/com.sun.javafx.runtime=ALL-UNNAMED --add-opens javafx.controls/com.sun.javafx.scene.control.skin=ALL-UNNAMED --add-opens javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED --add-opens javafx.graphics/javafx.scene.canvas=ALL-UNNAMED --add-opens javafx.graphics/com.sun.javafx.geom.transform=ALL-UNNAMED
Only issues I encounter are on Linux ... as follows:
When running on Linux Using B4J Bridge
- with #PackagerProperty: VMArgs = --add-opens b4j/net.sf.jasperreports.engine.fill=ALL-UNNAMED in B4J Main
- Reports work running in Debug, Release, and Release (obfuscated) Modes with following warning
- (java:2474): Gdk-WARNING **: 16:50:09.054: XSetErrorHandler() called with a GDK error trap pushed. Don't do that.
- which is logged after return from call to ReportWrapperLibrary
- similar issue found here: https://stackoverflow.com/questions/55446534/how-to-fix-java22494-gdk-warning
When running release on Linux
- Built from standalone package built in B4J
- Using B4JPackager11 project from within B4J pointing to jar on Linux
B4X:
Hello from net.nmcollector.cpReports openReport
openReport value of args( 0): /home/nmcollector/tempjars/temp/build/bin/nmcswDB.sqlite
openReport value of args( 1): /home/nmcollector/tempjars/temp/build/bin/
openReport value of args( 2): Collections.jasper
openReport value of args( 3): 1
openReport value of args( 4): 0
net.nmcollector.cpReports openReport jasperReport = /home/nmcollector/tempjars/temp/build/bin/Collections.jasper
net.nmcollector.cpReports openReport datasourceConnectionString = /home/nmcollector/tempjars/temp/build/bin/nmcswDB.sqlite
net.nmcollector.cpReports openReport parameters loaded
net.nmcollector.cpReports openReport url = jdbc:sqlite:/home/nmcollector/tempjars/temp/build/bin/nmcswDB.sqlite
net.nmcollector.cpReports openReport conn loaded
net.nmcollector.cpReports openReport ********* B4J Release Fails Here ********** call JasperPrint
reportspage$ResumableSub_Button_Open_Report_Click.resume (java line: -1)
java.lang.IllegalAccessError: superclass access check failed: class Collections_1628001404641_431771 (in unnamed module @0x5219dd7f) cannot access class net.sf.jasperreports.engine.fill.JREvaluator (in module b4j) because module b4j does not export net.sf.jasperreports.engine.fill to unnamed module @0x5219dd7f
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(Unknown Source)
at b4j/net.sf.jasperreports.engine.util.JRClassLoader.loadClass(Unknown Source)
at b4j/net.sf.jasperreports.engine.util.JRClassLoader.loadClassFromBytes(Unknown Source)
at b4j/net.sf.jasperreports.engine.design.JRAbstractJavaCompiler.loadClass(Unknown Source)
at b4j/net.sf.jasperreports.engine.design.JRAbstractJavaCompiler.loadEvaluator(Unknown Source)
at b4j/net.sf.jasperreports.engine.design.JRAbstractCompiler.createEvaluator(Unknown Source)
at b4j/net.sf.jasperreports.engine.design.JRAbstractCompiler.loadEvaluator(Unknown Source)
at b4j/net.sf.jasperreports.engine.JasperCompileManager.getEvaluator(Unknown Source)
at b4j/net.sf.jasperreports.engine.fill.JRFillDataset.createCalculator(Unknown Source)
at b4j/net.sf.jasperreports.engine.fill.BaseReportFiller.<init>(Unknown Source)
at b4j/net.sf.jasperreports.engine.fill.JRBaseFiller.<init>(Unknown Source)
at b4j/net.sf.jasperreports.engine.fill.JRVerticalFiller.<init>(Unknown Source)
at b4j/net.sf.jasperreports.engine.fill.JRFiller.createBandReportFiller(Unknown Source)
...
I saw a post where adding --add-opens b4j/net.sf.jasperreports.engine.fill=ALL-UNNAMED to another persons release_java_modules.txt file solved the "module b4j does not export net.sf.jasperreports.engine.fill to unnamed module @0x5219dd7f" error for them but it does not seem to be working for me.
Thanks in advance for any help!