Troubleshoot Complex Barcodes

Troubleshoot Complex Barcodes

Complex barcode processing includes several independent stages. A barcode can be successfully recognized as a QR Code, Data Matrix, PDF417, or another symbology, while its payload still cannot be decoded as the expected complex barcode type.

This article focuses only on issues specific to complex barcode processing: recognized symbology checks, complex codetext decoding, required-field validation, and standard-specific validation rules.

The complete source code for this article is available on GitHub:

View ComplexBarcodeTroubleshooting.java

Diagnose failures by stage

Stage Symptom Typical cause
Barcode type check Recognized DecodeType is not the expected symbology The payload is encoded in a different barcode symbology than expected.
Complex decoding tryDecode...() returns null The recognized text does not match the selected complex barcode format.
Payload validation BarCodeException is thrown during codetext construction Required business fields are missing or invalid.
Standard-specific validation BarCodeException is thrown for a populated object A field value violates a limit defined by the barcode specification.

Verify the recognized barcode type

Complex barcode decoding should begin with checking the recognized barcode symbology. For example, Swiss QR payments are encoded as QR Code symbols, while other complex formats may use another symbology.

The following example generates a plain QR Code and recognizes it successfully. However, successful QR recognition does not mean that the payload is a Swiss QR payment payload:

BarcodeGenerator generator = new BarcodeGenerator(EncodeTypes.QR, "NOT-A-SWISS-QR");
String outputPath = ExampleAssist.pathCombine(FOLDER, "plain_qr_not_swiss.png");
generator.save(outputPath, BarCodeImageFormat.PNG);

BarCodeReader reader = new BarCodeReader(outputPath, DecodeType.ALL_SUPPORTED_TYPES);
BarCodeResult[] results = reader.readBarCodes();

Assert.assertEquals(results.length, 1);
Assert.assertEquals(results[0].getCodeType(), DecodeType.QR);
Assert.assertNull(ComplexCodetextReader.tryDecodeSwissQR(results[0].getCodeText()));

This is a complex decoding failure, not a barcode recognition failure. The barcode was found, but its text does not follow the Swiss QR format.

Decode using the matching complex decoder

A valid complex barcode payload must be decoded with the matching ComplexCodetextReader.tryDecode...() method.

For example, HIBC LIC codetext is valid complex barcode data, but it is not Swiss QR data:

HIBCLICCombinedCodetext hibcCodetext = createHIBCLICCodetext();
String outputPath = ExampleAssist.pathCombine(FOLDER, "hibc_lic_for_decoder_check.png");

ComplexBarcodeGenerator generator = new ComplexBarcodeGenerator(hibcCodetext);
generator.save(outputPath, BarCodeImageFormat.PNG);

BarCodeReader reader = new BarCodeReader(outputPath, DecodeType.HIBCQRLIC);
BarCodeResult[] results = reader.readBarCodes();
String recognizedText = results[0].getCodeText();

Assert.assertNull(ComplexCodetextReader.tryDecodeSwissQR(recognizedText));
Assert.assertNotNull(ComplexCodetextReader.tryDecodeHIBCLIC(recognizedText));

Use a null result from a tryDecode...() method as a signal that the selected decoder does not match the payload or that the payload is not a supported instance of that complex barcode type.

Validation occurs before barcode generation

Complex barcode objects are validated when codetext is constructed. This allows applications to detect invalid business data before rendering an image.

SwissQRCodetext incompleteCodetext = new SwissQRCodetext();

try {
    incompleteCodetext.getConstructedCodetext();
    Assert.fail("Expected BarCodeException for missing required Swiss QR fields.");
} catch (BarCodeException exception) {
    Assert.assertTrue(exception.getMessage().contains("IBAN"));
}

For Swiss QR, a missing or invalid IBAN is one possible validation error.

Standard-specific limits are enforced

Aspose.BarCode validates limits defined by a complex barcode specification instead of silently generating a non-compliant payload.

The following example uses a Mailmark item identifier that exceeds the allowed maximum value:

MailmarkCodetext invalidCodetext = new MailmarkCodetext();
invalidCodetext.setFormat(1);
invalidCodetext.setVersionID(1);
invalidCodetext.setClass("1");
invalidCodetext.setSupplychainID(99);
invalidCodetext.setItemID(100_000_000);
invalidCodetext.setDestinationPostCodePlusDPS("XY11     ");

try {
    invalidCodetext.getConstructedCodetext();
    Assert.fail("Expected BarCodeException for an out-of-range Mailmark item ID.");
} catch (BarCodeException exception) {
    Assert.assertTrue(exception.getMessage().contains("99999999"));
}

Recommendations

  • Verify the recognized DecodeType before selecting a complex decoder.
  • Use the tryDecode...() method that matches the expected complex barcode format.
  • Treat null from tryDecode...() as a complex decoding failure, not as a barcode recognition failure.
  • Validate structured payloads before barcode generation.
  • Catch BarCodeException when constructing complex codetext objects.
  • Add automated tests for required fields and standard-specific limits.