ClassNotFoundException during package mapping in application server
Describe the bug
Deploying an ear application that uses Morphia 2.5.1 and MongoDB Driver 5.6.1 (as provided in the lib/ext of the domain) into an application server like Payara (5.2022.5).
When the application starts and should map the package de.asheep.classloaderexample then no entities are mapped because line 621 of Mapper.java classes.add(Class.forName(classInfo.getName())); does not find the corresponding classes and throws an ClassNotFoundException which is ignored.
To Reproduce Steps to reproduce the behavior:
- Build the example with
mvn clean package - Provide the mongodb 5.6.1 jars in the lib/ext directory of the domain of the application sever
- Deploy the ear file into a domain of the application sever
- Start the application
Expected behavior
The entities of the package de.asheep.classloaderexample should be found and mapped.
- Server Version: Payara 5.2022.5
- Driver Version: 5.6.1
- Morphia Version: 2.5.1
Additional context
It seems that the used ClassLoader is not the correct one. Changing the line to classes.add(Class.forName(classInfo.getName(), true, Thread.currentThread().getContextClassLoader())); will result in finding the correct classes.
@aSheep0815 sorry for the delay but claude and I took a stab at this on the plane home the other day. can you try the latest snapshot and see if it fixes your issue?
@evanchooly the latest snapshot works for the reproducer example. But I think it already worked before the latest changes as the note in the commit hints:
Note: Mapper.java already correctly uses the context ClassLoader captured at construction time, so no changes were needed there.
The reproducer uses Mapper.java. It worked in 2.4.6 and it works in 3.0.0-SNAPSHOT.
Only in the 2.5.x branch the Mapper looks like this
@MorphiaInternal
public Mapper(MorphiaConfig config) {
this.config = config;
discriminatorLookup = new DiscriminatorLookup();
}
The Context ClassLoader is not used at construction time. The latest changes look good to me nonetheless and are certainly needed to ensure that the Context ClassLoader is used in all places.
I'll take another look then.
I've updated a few other Class.forName() that might help out. I'll give it a go with your example zip and see how we do. Though I don't have any payara (or other container) set ups to test so it might take a minute. maybe there's a docker image I can use to speedrun. but if you want to give it another try with 2.5.2-SNAPSHOT from tonight, that'd be great, too.
I ran this
docker run -p 8080:8080 -v <path to folder with example ear>:/opt/payara/deployments payara/server-full:7.2025.1
and apart from complaining about the ear not having any ejb's, it deployed "successfully." But I don't know how much I can trust that. Can you give the new jar a shot. And if it doesn't work, can you update your example zip to have an EJB so it'll deploy correctly? Thanks. It feels like we're almost there but I tend to the overly optimistic. ;)
Seems your Payara version is a little bit more restrict than mine. If you like I can provide an updated version.
I tried your new 2.5.x branch in the provided reproducer and in my production code. In both cases it works like a charm and the classes can be mapped.
This issue is crucial to me as I have to switch from MongoDB 4.4 to MongoDB 7+ because earlier versions have already reached end of life or soon will. I would prefer not to use a SNAPSHOT version in my production code if it can be avoided. Is there a timeline for a possible 2.5.2 release?
Thank you very much for addressing the issue!
This is basically the last issue holding it up. I'll close this out and push a release.
/duplicate 3.0
Issue Duplication Results
Processed by @evanchooly
✅ #4066 created for milestone "3.0.0"
Triggered by comment: /duplicate 3.0