-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Java Client: remove usage of reflection while using Pulsar Implementation classes #11636
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
Conversation
- load the DefaultImplementation only once with reflection - use standard Java calls to access the Pulsar Implementation classes - reduce the overall overhead of using Reflection - clarify the relationsship between the classes - add explicit linking between the impl and api classes, this way it is easier to read the code and perform refactorings - allow to handle correctly the Exception thrown by implementation classes
rdhabalia
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.
LGTM
merlimat
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.
I really like this approach. I just have a question on how we can guarantee that we're picking the right classloader.
| } | ||
|
|
||
| public ClientBuilder newClientBuilder() { | ||
| return new org.apache.pulsar.client.impl.ClientBuilderImpl(); |
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.
Wouldn't this be using the class loader from the current context? How can we be sure it's going to be the same as PulsarClientImplementationBindingImpl?
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.
See the JVM specs here
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html
chapter "5.3. Creation and Loading"
look for "If D was defined by a user-defined class loader, then that same user-defined class loader initiates loading of C"
basically if a class "D" (where "D" is not a system class) triggers the loading of a class "C", then the same Classloader that loaded "D" will initiate the loading of "C"
So in this case the same classloader which loaded PulsarClientImplementationBindingImpl will initiate the loading of ClientBuilderImpl if the class has not been loaded yet
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.
Got it. thanks!
| } | ||
|
|
||
| public MessageId newMessageId(long ledgerId, long entryId, int partitionIndex) { | ||
| return new org.apache.pulsar.client.impl.MessageIdImpl(ledgerId, entryId, partitionIndex); |
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.
Couldn't we import the classes here instead of using the full name?
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.
Fixed.
I left the FQCN only because I converted the class semi automatically, before of this change they where simple strings.
|
@eolivelli thanks for providing doc-related info. If your PR does not need to update doc, could you please help label the PR with |
|
|
@merlimat I have removed the usage of Fully qualified class names. After merging this patch I will add new integration tests in Pulsar Functions in order to verify that we are loading correctly all (of most of them) the classes referred by |
…tion classes (apache#11636) * Java Client: remove usage of reflection for loading Pulsar Impl classes - load the DefaultImplementation only once with reflection - use standard Java calls to access the Pulsar Implementation classes - reduce the overall overhead of using Reflection - clarify the relationsship between the classes - add explicit linking between the impl and api classes, this way it is easier to read the code and perform refactorings - allow to handle correctly the Exception thrown by implementation classes * Fix checkstyle and build * fix unit test * Add some javadoc and remove use of fully qualified class names Co-authored-by: Enrico Olivelli <eolivelli@apache.org>
…tion classes (apache#11636) * Java Client: remove usage of reflection for loading Pulsar Impl classes - load the DefaultImplementation only once with reflection - use standard Java calls to access the Pulsar Implementation classes - reduce the overall overhead of using Reflection - clarify the relationsship between the classes - add explicit linking between the impl and api classes, this way it is easier to read the code and perform refactorings - allow to handle correctly the Exception thrown by implementation classes * Fix checkstyle and build * fix unit test * Add some javadoc and remove use of fully qualified class names Co-authored-by: Enrico Olivelli <eolivelli@apache.org> (cherry picked from commit 683c2d6)
…tion classes (apache#11636) * Java Client: remove usage of reflection for loading Pulsar Impl classes - load the DefaultImplementation only once with reflection - use standard Java calls to access the Pulsar Implementation classes - reduce the overall overhead of using Reflection - clarify the relationsship between the classes - add explicit linking between the impl and api classes, this way it is easier to read the code and perform refactorings - allow to handle correctly the Exception thrown by implementation classes * Fix checkstyle and build * fix unit test * Add some javadoc and remove use of fully qualified class names Co-authored-by: Enrico Olivelli <eolivelli@apache.org> (cherry picked from commit 683c2d6)
Motivation
Currently the link between the Pulsar Client API and the Implementation is done at runtime, using Java reflection, in the DefaultImplementation class.
This comes with a few problems:
Modifications
PulsarClientImplementationBindingthat defines the connections from the "public API" and the "implementation", this interface contains all the methods of the old "DefaultImplementation"PulsarClientImplementationBindingImplPulsarClientImplementationBindingImplcan access directly, without reflection all the implementation classes, this is faster and also it allows us to have direct linking (for human reading, for IDE help....)PulsarClientImplementationBindingImplclass only onceDefaultImplementation.staticMethod(xxx)toDefaultImplementation.getDefaultImplementation().method(xxx)Verifying this change
This change is a trivial rework / code cleanup without any test coverage.
Documentation
No need for docs