Java Question [SOLVED] "--add-opens ... =ALL-UNNAMED" arg not working on Linux Deployment

cjpryor

Active Member
Licensed User
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:

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!
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
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
#PackagerProperty only has effect when you build a standalone package using the internal packager.

You should run the external packager using B4J-Bridge and you should set the VMArgs global variable. It can also be done with the generated json file.
 

cjpryor

Active Member
Licensed User
#PackagerProperty only has effect when you build a standalone package using the internal packager.

You should run the external packager using B4J-Bridge and you should set the VMArgs global variable. It can also be done with the generated json file.

Thank you for your response! It helps a bunch! I did (attempt to) use the external package manager using B4J-bridge as mentioned in my original post (as quoted below), but it looks like I did not configure it correctly.

When running release on Linux
- Built from standalone package built in B4J
- Using B4JPackager11 project from within B4J pointing to jar on Linux

That project is where I found the release_java_modules.txt that I modified. However, I did not make any changes to the parameters in the project file itself. These are my current configuration which I see now are incomplete.

B4X:
Sub Process_Globals
    
    'Linux
    Private InputJar As String = "/home/nmcollector/data/CP_deploy/Linux/NMCollectorCP.jar"
    
    Private NetFrameworkCSC As String = "%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\csc.exe" 'windows only
    Private IconFile As String
    Private ExcludedModules As List
    ExcludedModules = Array("javafx.web") 'comment this line if using WebView
    Private IncludedModules As List' = Array("jdk.crypto.ec")
    Private AdditionalModuleInfoString As String '= "exports net.sf.jasperreports.engine.fill;"
    Private VMArgs As String
    'non configurable variables:
    Private JavafxJmods As String
    Private java As String
    Private PackageName As String
    Private TempFolder As String
    Private Modules As List
    Private TargetModule As String = "b4j"
    Private JavaFXLibs As String
    Private Version As Float = 1.21
    Private Windows As Boolean
    Private Mac As Boolean
    Private Linux As Boolean 'ignore
    Private ExeName As String
    Private Java14 As Boolean
End Sub

Thanks again!
 
Top