How to use Java libraries in a Mirth Connect channel

:white_check_mark: Java Library Use in Mirth Connect 4.5.2

:gear: 1. Mirth 4.x uses GraalVM JavaScript (ES6)

Starting with Mirth Connect 4.0, the JavaScript engine is GraalVM, not Nashorn or Rhino anymore. This changes how you access Java classes slightly.

:rocket: 2. Updated Syntax with GraalVM

In GraalVM, Java.type() still works for now, but may have some restrictions depending on the Java version and security context. You may need to use Packages. in some cases or adjust security settings.


:package: Step-by-Step for Mirth 4.5.2

1. Place Your JAR File in the Right Location

  • Recommended: MIRTH_HOME/custom-lib/ (e.g., /opt/mirth-connect/custom-lib/ or C:\Program Files\Mirth Connect\custom-lib\)
  • Restart the Mirth Connect service (not just the Administrator UI).

For the below code to work you need to place dcm4che-core-5.34.0.jar from the Releases Β· dcm4che/dcm4che Β· GitHub release into the custom-lib folder

2. Access the Java Class in a JavaScript Transformer/Step

var UIDUtils = Packages.org.dcm4che3.util.UIDUtils;
var uid = UIDUtils.createUID();
logger.info("Generated UID: " + uid);

Here is a quick example Mirth channel

It doesn’t do smart stuff end to end yet, but rather is just triggered by an .txt file and then converts a pdf to DICOM.

The interesting part is the DICOM wrapper.
You can find the full javascript code in the channel but here is a copy paste of it

// Java imports
var File = Packages.java.io.File;
var FileInputStream = Packages.java.io.FileInputStream;
var FileOutputStream = Packages.java.io.FileOutputStream;
var ByteArrayOutputStream = Packages.java.io.ByteArrayOutputStream;
var Date = Packages.java.util.Date;
var Integer = Packages.java.lang.Integer;
var Array = Packages.java.lang.reflect.Array;

// DICOM imports
var Attributes = Packages.org.dcm4che3.data.Attributes;
var DicomOutputStream = Packages.org.dcm4che3.io.DicomOutputStream;
var Tag = Packages.org.dcm4che3.data.Tag;
var VR = Packages.org.dcm4che3.data.VR;
var UID = Packages.org.dcm4che3.data.UID;
var UIDUtils = Packages.org.dcm4che3.util.UIDUtils;

// === Paths ===
var inputPdfPath = "C:\\downloads\\dicom-test\\pdf\\pdf-sample-report.pdf";
var outputDcmPath = "C:\\downloads\\dicom-test\\pdf\\output.dcm";

// === Read PDF into byte array ===
var pdfFile = new File(inputPdfPath);
var fis = new FileInputStream(pdfFile);
var baos = new ByteArrayOutputStream();

var buffer = Array.newInstance(java.lang.Byte.TYPE, 8192);
var len = 0;

while ((len = fis.read(buffer)) != -1) {
    baos.write(buffer, 0, len);
}
fis.close();

var pdfBytes = baos.toByteArray();

// === Create date array for setDate method ===
//var dateArray = Array.newInstance(Date.class, 1);
//dateArray[0] = new Date();

// === Create DICOM attributes ===
var attrs = new Attributes();
attrs.setString(Tag.SOPClassUID, VR.UI, UID.EncapsulatedPDFStorage);
attrs.setString(Tag.SOPInstanceUID, VR.UI, UIDUtils.createUID());
attrs.setString(Tag.Modality, VR.CS, "DOC");
attrs.setString(Tag.MIMETypeOfEncapsulatedDocument, VR.LO, "application/pdf");
attrs.setString(Tag.PatientName, VR.PN, "Doe^John");
attrs.setString(Tag.PatientID, VR.LO, "123456");
attrs.setString(Tag.StudyInstanceUID, VR.UI, UIDUtils.createUID());
attrs.setString(Tag.SeriesInstanceUID, VR.UI, UIDUtils.createUID());

// Cast tags to int for setDate()
//attrs.setDate(Integer.valueOf(Tag.StudyDate).intValue(), VR.DA, dateArray);
//attrs.setDate(Integer.valueOf(Tag.StudyTime).intValue(), VR.TM, dateArray);

attrs.setInt(Tag.InstanceNumber, VR.IS, 1);
attrs.setBytes(Tag.EncapsulatedDocument, VR.OB, pdfBytes);

// === Write DICOM file ===
var dos = new DicomOutputStream(new File(outputDcmPath));
dos.writeDataset(null, attrs);
dos.close();

logger.info("βœ… Encapsulated PDF DICOM created: " + outputDcmPath);