-
Notifications
You must be signed in to change notification settings - Fork 2.9k
NIFI-15388: Leak in ReflectionUtils annotation cache. #10691
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
d4912f7 to
e924169
Compare
exceptionfactory
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for proposing this change @bobpaulin. The adjustment appears to be logical, but some sporadic test failures raise questions about unintended consequences. This might be an opportunity to consider switching some references to Apache Commons Lang3 MethodUtils, depending on whether certain uses should participate in the caching of Class and Method references. The framework uses this class in a number of places, so if there are only a few places where Method references should not be cached, it may be cleaner to switch to MethodUtils, instead of making this more fundamental change.
21f5c2f to
6536b7c
Compare
|
Hi @exceptionfactory you are correct that I could replace ReflectionUtils with MethodUtils to invoke annotated methods without caching in strategic places that do not benefit from caching. I also agree that making that change in a few strategic locations could reduce the risk given how widely used this class is. I'm open to going in that direction in the short term. That said I'd like to lean in a bit to on these failures. There is a fundamental issue with using a WeakHashMap when the values (specifically the methods) contain references to the keys (the class). It effectively makes the WeakHashMap contain strong references which prevents it from serving it's intended purpose here. I've just rebased the code on the latest main and will also see if I can reproduce these failures locally to determine if there is in fact a logical problem or if perhaps there's something else going on.
|
Thanks @bobpaulin, that's a very good point. It does seem worth tracing this down a bit more in light of the failures surfaced. |
|
Looks like the reason these test may be failing is due to the Method objects created from the Class are copies instead of directly referenced objects from Class object. Because of this the weak References to the methods will be eligible for garbage collection. This may be the reason the system test were failing. I experimented with a few different approaches including switching to MethodHandles which also leaves you with a reference to the class object which will prevent the WeakHashMap from doing what it is suppose to. So I've got a different approach that removes the keys when the instance classloader is closed. This also provides the desired effect of allowing the classes to be garbage collected. Will update this PR for this approach and will change the title of this PR to better represent this change. |
* WeakHashMap does not work properly to remove keys and values due to strong reference to the Key found in the Cache Value * Keys should be programatically invalidated when the ClassLoader is closed to allow classes to be Garbage Collected. * Moved ReflectionUtils to nifi-nar-utils so it can be shared by nifi-framework-nar-utils and nifi-framework-components
strong reference to the Key found in the Cache Value
closed to allow classes to be Garbage Collected.
nifi-framework-nar-utils and nifi-framework-components
Summary
NIFI-15388
Tracking
Please complete the following tracking steps prior to pull request creation.
Issue Tracking
Pull Request Tracking
NIFI-00000NIFI-00000Pull Request Formatting
mainbranchVerification
Please indicate the verification steps performed prior to pull request creation.
Add DBCPConnectionPool Controller Service
Enable with PostgresJDBC driver properties
Disable Controller Service
Remove Controller Service
Expected result
Classes should be GC'ed when InstanceClassLoader is GCed.
Actual
Classes still have strong references with the methods stored in the ReflectionUtils annotationCache.
With code change Classes can be unloaded because values are stored as WeakReferences and can be GC.
Build
./mvnw clean install -P contrib-checkLicensing
LICENSEandNOTICEfilesDocumentation