Fix agent class package definition#2566
Conversation
elastic-apm-agent/src/main/java/co/elastic/apm/agent/premain/ShadedClassLoader.java
Show resolved
Hide resolved
| } | ||
|
|
||
| @SuppressWarnings("deprecation") | ||
| private boolean isPackageNotDefined(String packageName) { |
There was a problem hiding this comment.
Probably a matter of taste but I'd always use affirmative rather than negative method names.
See also https://softwareengineering.stackexchange.com/a/196837
| Package pkg; | ||
| if (getDefinedPackage != null) { | ||
| try { | ||
| pkg = (Package) getDefinedPackage.invokeExact(this, packageName); |
There was a problem hiding this comment.
Do we even need to call getDefinedPackage or is getPackage good enough? Maybe its preferable to have the same semantics regardless of the Java version?
On Slack you said
If migrating the call to the deprecated
getPackage(...)and usinggetDefinedPackage(...)the difference is that now it does not tries to delegate to parent nor Bootstrap CL when checking if the package is defined.
Given the classes that are loaded by the shaded CL can only be loaded by this CL, I don't think there is any need to ask the parent CL in this case.
So it seems there's not really a benefit of calling getDefinedPackage?
There was a problem hiding this comment.
Ah, I misunderstood. The getPackage delegates to the parent which may be an issue in certain cases if the package has been defined in a parent CL but not the current CL. Probably not an issue either way in our case, as the parent (platform CL or bootstrap CL) will never have defined an agent package.
I'm fine either way, I guess. Calling getDefinedPackage is technically more correct and avoids calling a deprecated API but adds a bit of boiler plate.
There was a problem hiding this comment.
That's a very good question !
In theory there is no case where the ShadedClassLoader will load classes that are defined in packages that have been defined by a parent classloader, so using getDefinedPackage should be enough and we can skip the extra lookups that are done by getPackage. Performance wise, it should be a trivial difference as the packages are stored in a concurrent map.
In practice, we still have cases where the call the definePackage throws an IllegalArgumentException, which means a parent CL is expected to sometimes create those packages. So if packages can be defined by another CL, hence delegation to parent CL does make sense.
On top of that, we only check for the package presence with a null check and don't use the returned Package instance, so there is no difference on the origin of the Package instance.
As a conclusion I now think it's not worth the extra complexity to use a method handle here, and we can always revisit this later. I'll add a comment to clarify the usage of getPackage vs getDefinedPackage.
|
/test |
What does this PR do?
Fixes agent class package definition in shaded classloader
Checklist