nextgenhealthcare / connect

The swiss army knife of healthcare integration.
Other
917 stars 275 forks source link

Class Loading Conflict After v3.12 Upgrade #4947

Open TMarzullo opened 2 years ago

TMarzullo commented 2 years ago

Repost from Mirth Connect Forum

We recently did an upgrade from v3.10 to v3.12 and Mirth went completely wonky due to what appears to be a class conflict. We ultimately resolved the issue (details below) but I wanted to post to the forum and on github about what happened in case it is helpful to someone else. I certainly wasn't able to find any posts about this scenario and it has the potential to be a huge headache and cause downtime.

We utilize a nifty library called Docx4j to create, edit and manipulate MS Word and Excel files. Due to the nature of open source projects, you can imagine that there are many packages/jars in common between Mirth and Docx4j. We had not encountered any conflicts until this upgrade, so whatever changed in Mirth occurred sometime after v3.10. In version 3.12, two jars in the Docx4j dependencies caused problems:

The behavior we saw was weird to say the least. Basically, any process which utilized Mirth's native XML parsing and XSLT features was non functional. No errors were thrown in the server log, the mirth.log or anywhere. The message browser looked like channels simply had received or built empty payloads.

The solution for us was to isolate the code which utilized the Docx4j resources away from everything else. In our case we had a specific channel which created an Excel workbook so we moved the code which required Docx4j objects into a single destination connector. We then configured the channel's dependencies to only include the Docx4j resource in the context for that single destination. This allowed the other parts of the channel which needed to work with XML objects (but not Docx4j XML objects) to continue using Mirth's classes and thus continue to function.

The first warning we wanted to draw attention to in this post pertains to the context scope of custom resources. I believe it has already been a recommended best practice to isolate custom resources rather than just loading everything from custom-lib into the Default Resource, so that is nothing new. For us, we typically assign custom resources at the channel level, but in this case we we had to get more granular and narrow the context to a specific destination.

The second word of warning pertains to potential consequence of the Default Resource's default settings. Depending on how you choose to implement your process for upgrading Mirth to a new version or how you restore a Mirth server, there are possible pitfalls. The Default Resource, by default, has the setting Include All Subdirectories checked although I don't believe the jars are loaded until you manually select Reload Resources in the UI (somebody feel free to correct me if this is inaccurate). The obvious defense against this risk when doing an upgrade or restoring from a backup is to just add a verification step; make sure your custom resources are still isolated, the Default Resource isn't including the subdirectories and reload resources as needed. The bigger risk IMO is when adding a custom resource: the act of dropping in your custom resource files under the custom-lib directory and reloading the Default Resource could potentially bring down any existing development which utilizes Mirth XML XSLT features.

Ultimately, I don't know what changed in Mirth specifically but I suspect it had something to do with the class loading process. I don't know if it is a bug or not and I am not attempting to point fingers or lay blame. Rather, I was just very stumped for an embarrassingly long time and I am hoping this shortens somebody else's head-scratching period :)

jonbartels commented 2 years ago

Discussion in Slack - https://mirthconnect.slack.com/archives/C02SW0K4D/p1641910639140400 (Note this link will go stale as Slack history rolls off)

ChristopherSchultz commented 2 years ago

What are the versions of Mirth's libraries relative to the ones in your dependencies?

TMarzullo commented 2 years ago

I found 8 jars in the Docx4J directory which are also found in Mirth's (v3.12) server-lib directory. • checker-qual-2.8.1.jar • commons-codec-1.12.jar • commons-compress-1.21.jar • commons-io-2.7.jar • commons-lang3-3.9.jar • commons-logging-1.2.jar • error_prone_annotations-2.3.3.jar • slf4j-api-1.7.26.jar

Here is the side by side comparison of their versions. Extra rows when more than one was found in Mirth, bold for the newer version:

  Mirth v3.12 Docx4J Dependencies
  checker-qual-2.10.0.jar checker-qual-2.8.1.jar
database commons-codec-1.11.jar commons-codec-1.12.jar
commons commons-codec-1.13.jar    
  commons-compress-1.17.jar commons-compress-1.21.jar
  commons-io-2.6.jar commons-io-2.7.jar
database commons-lang3-3.5.jar commons-lang3-3.9.jar
commons commons-lang3-3.9.jar    
  commons-logging-1.2.jar commons-logging-1.2.jar
  error_prone_annotations-2.3.4.jar error_prone_annotations-2.3.3.jar
  slf4j-api-1.7.21.jar slf4j-api-1.7.26.jar

I also compared the versions of each of those jars in the current (3.12) version of Mirth to the previous version (3.10) and all except one of them was the same version. In other words, the upgrade from Mirth 3.10 to Mirth 3.12 did not change any of those shared jars except this one: • slf4j-api-1.7.26.jar

Simple Logging Facade for Java doesn't seem related. Also, I should note, I didn't find any xalan libraries.

jonbartels commented 2 years ago

What MC libraries could conflict with Xalan? I'm thinking like Saxon or other Java XML/XSLT implementations.

jonbartels commented 2 years ago

I might be barking up the wrong tree but could you try launching MC with the jaxp.debug JVM argument? https://www.ivankrizsan.se/2013/07/16/jaxp-debug-log/

The reported symptom is that XML and XSLT related operations are not working properly. Showing what classes

Also @TMarzullo - Can you describe how to reproduce this bug? There are several distributions of DocX4J and its official repo which one did you use?

Does this problem only happen when using DocX4J in custom-lib? Does it happen when using DocX4J in a Resource Directory plus the default resource?

What other resources, if any, do you have configured as Resource Directories or in custom-lib?

rogin commented 2 years ago

Thank you @TMarzullo for opening an issue as I bumped into this yesterday. I have a test case regarding a xalan jar within custom-lib affecting normal channel actions. Tested on a Windows 10 machine a moment ago. The xalan jar was pulled from search.maven.org.

  1. Extract Mirth 3.12 from zip
  2. Start mcserver
  3. Start admin launcher, login to local instance as default admin
  4. Import and deploy Relay1.xml
  5. Import and deploy Relay2.xml
  6. Send a text message to Relay1
  7. Verify Message output in Relay2 is "<testXML/>"
  8. Copy xalan-2.4.1.jar under /custom-lib
  9. Under Settings>Resources, click button to reload default resource
  10. Rerun steps 6-7, see that message output in Relay2 is missing and no errors shown MirthBugFiles.zip