I'm using OpenMRS 2.0.6, and I'm having issues with linkage errors during class loading. The following example shows a different library version, but the same issue occurs even if they are the same version:
- Module A is deployed to OpenMRS with version 2.0.1 of javax.ws.rs-api
- Module B is deployed to OpenMRS with version 2.1.0 of javax.ws.rs-api
Module A and B have no dependencies to each other. Module B only depends on the legacy-ui module.
I receive a Linkage Error sometimes when I try to start OpenMRS or run classes that have a dependency on the javax.ws.rs package.
I would rather not add a dependency from B to module A. Module A depends on multiple other modules, and I don't want a user to have to load the other unneeded modules.
The class having the issues is the service implementation defined in the moduleApplicationContext.xml file. I performed some debugging, and the issues seems to happen when the Spring context is refreshed. I placed a breakpoint in the ModuleClassLoader loadClass method, and the refresh goes through there first. Everything looks correct at this point because the class is loaded from Module B's class loader. Then a call comes from Spring refresh to the OpenmrsClassLoader loadClass method. It then looks up all module class loaders that have a reference to the javax.ws.rs package. It find 2 modules (Module A and B). But the list has Module A first, and tries to load the class and fails.
HTTP Status 500 - Handler processing failed; nested exception is java.lang.LinkageError: ClassCastException: attempting to castfile:/C:/windows/system32/config/systemprofile/Application%20Data/OpenMRS/.openmrs-lib-cache/ModuleA/javax/ws/rs/client/ClientBuilder.class to file:/C:/windows/system32/config/systemprofile/Application%20Data/OpenMRS/.openmrs-lib-cache/ModuleB/javax/ws/rs/client/ClientBuilder.class
I do have a reproducible test case. Performing the following steps below will cause the linkage error to occur. Please advise if I have something in the modules configured incorrectly.
- Deploy OpenMRS Platform 2.0.6 (bundled with legacy-ui module).
- Open the Manage modules page from the OpenMRS admin page.
- Deploy Module A (https://github.com/sjmckee/Module-A.git).
- Deploy Module B ([https://github.com/sjmckee/Module-B.git]).
- Receive the linkage error during deployment of Module B: Constructor threw exception; nested exception is java.lang.LinkageError: ClassCastException: attempting to castfile:/C:/windows/system32/config/systemprofile/Application%20Data/OpenMRS/.openmrs-lib-cache/modulea/javax/ws/rs/client/ClientBuilder.class to file:/C:/windows/system32/config/systemprofile/Application%20Data/OpenMRS/.openmrs-lib-cache/moduleb/javax/ws/rs/client/ClientBuilder.class
Here is another manifestation of this problem: https://talk.openmrs.org/t/fhir2-module-causing-linkage-error-with-name-javax-xml-namespace-qname/28675/17