JVM crashes when trying to claim a claimed printer JavaPOS EPSON Thermal Printer

I am using Epson_JavaPOS_ADK_11414_for_Linux_x64 for installing the JavaPOS with pcs ( sh installJavaPOSFull-64.sh )

I ran this program one after the other in different shells and the second process crashes for some reason:

import jpos.JposException;
import jpos.POSPrinter;
import jpos.util.JposPropertiesConst;

import java.time.Duration;
import java.time.Instant;

public class POSPrinterClaimTest {
  static POSPrinter posPrinter;

  private static Boolean isOpen = false;
  private static Boolean isClaimed = false;
  private static Boolean isEnabled = false;



  static {
    System.setProperty(
        JposPropertiesConst.JPOS_POPULATOR_FILE_PROP_NAME, "jpos.xml");
  }

  public static void main(String[] args) {
    try {
      posPrinter = new POSPrinter();
      Instant start = Instant.now();
      Instant finish = null;
      Long timeElapsed = null;
      openConnection("POSPrinter1");
      finish = Instant.now();
      timeElapsed = Duration.between(start, finish).toMillis();
      System.out.println("Time taken to connect : " + timeElapsed.toString());
      Thread.sleep(100000L);
      terminate();
      System.out.println("terminated from try block");
    } catch (JposException | InterruptedException e) {
      e.printStackTrace();
      try {
        terminate();
        System.out.println("terminated from catch block");
        Thread.sleep(5000);
      } catch (JposException | InterruptedException jposException) {
        jposException.printStackTrace();
      }
    } catch(Throwable t){
      t.printStackTrace();
    } finally {
      posPrinter = null;
    }
  }

  private static void openConnection(String printerName) throws JposException {
    try {

      String printerNamesss = printerName;
      /**
       * open the printer object according to the device logical name defined in jpos.xml
       */
      posPrinter.open(printerName);
      isOpen = true;
      System.out.println("opened");
      /**
       * Get the exclusive control right for the opened device.
       * Then the device is disable from other application.
       * */
      posPrinter.claim(3000);
      isClaimed = true;
      System.out.println("claimed");
      /**
       *  enable the device for input and output
       */
      posPrinter.setDeviceEnabled(true);
      isEnabled = true;
      System.out.println("enabled");

    } catch (JposException jposException) {
      System.out.println("jpos exception in open : " + jposException.getMessage());
      throw jposException;
    } catch(Throwable t) {
      System.out.println("unknown throwable open: " + t.getMessage());
    }
  }


  public static void terminate() throws JposException {
    try {
        if(isOpen && isClaimed) {
          posPrinter.clearOutput();
          System.out.println("cleared output");
        }

        if(isEnabled) {
          posPrinter.setDeviceEnabled(false);
          isEnabled = false;
          System.out.println("setDeviceEnabled false");
        }

        if(isClaimed) {
          posPrinter.release();
          isClaimed = false;
          System.out.println("released");
        }

        if(isOpen) {
          posPrinter.close();
          isOpen = false;
          System.out.println("closed");
        }
    } catch (JposException jposException) {
      jposException.printStackTrace();
      throw jposException;
    } catch(Throwable t) {
      System.out.println("unknown throwable terminate: " + t.getMessage());
    }
  }
}


First process output

opened
claimed
enabled
Time taken to connect : 7928 --> now I start the second process.
cleared output
setDeviceEnabled false
released
closed
terminated from try block

Second process output

opened
jpos exception in open : The port is already open.
jpos.JposException: The port is already open.
    at jp.co.epson.upos.core.v1_14_0001.pntr.CommonUPOSExceptionCreator.createJposException(CommonUPOSExceptionCreator.java:138)
    at jp.co.epson.upos.core.v1_14_0001.pntr.CommonUPOSExceptionCreator.createJposException(CommonUPOSExceptionCreator.java:99)
    at jp.co.epson.upos.core.v1_14_0001.pntr.CommonPrinterService.openPort(CommonPrinterService.java:3341)
    at jp.co.epson.upos.core.v1_14_0001.pntr.CommonPrinterService.claim(CommonPrinterService.java:3103)
    at jpos.BaseJposControl.claim(Unknown Source)
    at POSPrinterClaimTestThreads.openConnection(POSPrinterClaimTestThreads.java:73)
    at POSPrinterClaimTestThreads.test(POSPrinterClaimTestThreads.java:36)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
closed
terminated from catch block
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f43880ea9df, pid=12119, tid=0x00007f43690b0700
#
# JRE version: OpenJDK Runtime Environment (8.0_252-b09) (build 1.8.0_252-b09)
# Java VM: OpenJDK 64-Bit Server VM (25.252-b09 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C  [libethernetio31.so+0x1f9df]  CCommonPort::PortEvent(unsigned int, unsigned int, unsigned int*, unsigned int, unsigned char*)+0xf
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /POSPrinterTest/JavaPOS/hs_err_pid12119.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#
Aborted

If you see the second process throws a JposException which then initiates its catch and closes the connection. Then it suddenly crashes instead of sleeping for 5sec.

Any help?

Answer

After discussing this problem with EPSON team, they were able to provide a fix for the same with a new libepsonjpos.so and epsonjpos.jar

It solved two problems for me:

  1. The original claim issue in the post – resolved after using the latest libepsonjpos.so
  2. Multi-threaded printing in a single process in non-install mode (No-SetupPOS-insall)
    • the Epson team said to synchronize the POSPrinter.open() in all the threads and update the epsonjpos.jar with their fix

Some quotes on the issue from Epson Team.

Multi-thread issue – “Change History The fix that has been applied is in the device sharing logic. Only affects lite-mode (No-SetupPOS version) The different objects falsely assumed as equal. As result only the first connected printer has been used. The fix corrects that comparison logic.”

Claim Issue – “We are glad we could help you. As for the background of the issues. The multi-process usage with non-install mode was a corner case for our JavaPOS ADK. With your help we could improve our testing cases.”

Epson team said that they will release the patches in the next version.

Leave a Reply

Your email address will not be published. Required fields are marked *