KAFKA-17150: Use Utils.loadClass instead of Class.forName to resolve aliases correctly - #16608
Conversation
…aliases correctly Signed-off-by: Greg Harris <greg.harris@aiven.io>
|
Also @yashmayya @mimaison and anyone else interested in reviewing! |
|
Alternatives to this PR are:
|
C0urante
left a comment
There was a problem hiding this comment.
LGTM pending CI to demonstrate that there are no (further) regressions. Great find, thanks Greg!
chia7712
left a comment
There was a problem hiding this comment.
@gharris1727 this patch is good to me. one small comment is left. PTAL
| public static <T> Class<? extends T> loadClass(String klass, Class<T> base) throws ClassNotFoundException { | ||
| return Class.forName(klass, true, Utils.getContextOrKafkaClassLoader()).asSubclass(base); | ||
| ClassLoader contextOrKafkaClassLoader = Utils.getContextOrKafkaClassLoader(); | ||
| // Use loadClass here instead of Class.forName because the name we use here may be an alias |
There was a problem hiding this comment.
Those comments about "alias" seem to valid for connector only, right? I mean the plugin-able configs in other module (core, storage, and tool) have no mechanism about "alias". If the answer is YES, maybe we can tweak the comments so as to avoid incorrect assumption that "all" plugin-able configs can use "alias".
There was a problem hiding this comment.
Aliasing is a general concept, with one particular implementation in connect. I don't think the word alias is incorrect to use here. The comment also doesn't mention plugins at all.
You're right that the only time we use aliases is in connect, via the DelegatingClassLoader, so most of the time this change has no effect, loadedClass.getName().equals(klass) is true.
There was a problem hiding this comment.
I assumed the "alias" are applied to all plugin configs when reading those comments, so the origin comment is "we have some deprecated implementations having same alias as new one. Bababa..."
There is no strong reason to tweak the comments, because the root cause is probably my poor reading 😢
chia7712
left a comment
There was a problem hiding this comment.
LGTM and thanks for this good fix!
|
I'm retriggering CI as 2 jobs failed in the first run. |
|
@gharris1727 The build wasn't working because of a |
Signed-off-by: Greg Harris <greg.harris@aiven.io>
Signed-off-by: Greg Harris <greg.harris@aiven.io>
|
@gharris1727 FYI, I've opened gharris1727#1 to add an integration test for plugin aliases. You are welcome to include it in this PR, or if you'd prefer I can file a PR against trunk to add the test instead. |
|
@C0urante Thanks for implementing an integration test! I think one may be warranted here because it's regressed twice now, and an integration test would have caught this. I'd prefer to unblock the release quickly, so please retarget that PR at upstream/trunk, thanks! |
|
Test failures look unrelated, and the tests pass for me locally. |
…aliases correctly (#16608) Signed-off-by: Greg Harris <greg.harris@aiven.io> Reviewers: Chris Egerton <chrise@aiven.io>, Chia-Ping Tsai <chia7712@gmail.com>, Josep Prat <josep.prat@aiven.io>
…aliases correctly (apache#16608) Signed-off-by: Greg Harris <greg.harris@aiven.io> Reviewers: Chris Egerton <chrise@aiven.io>, Chia-Ping Tsai <chia7712@gmail.com>, Josep Prat <josep.prat@aiven.io>
There are a handful of places where we call Class.forName in the code base. Previously, the ConfigDef call-site required a patch to resolve aliased classes (a feature in Connect). A second call-site via AbstractHerder -> Utils.newInstance has appeared as a regression in the current release. We can apply the same fix to all other call sites for Class.forName to prevent this from happening accidentally again. If aliases are not in-use, this should be a no-op change.
I added a PluginsTest case that exercises all of the ways we could construct Converter objects and ensures that they don't throw a ClassNotFoundException. This test failed before making the fix.
Committer Checklist (excluded from commit message)