-
Notifications
You must be signed in to change notification settings - Fork 3k
AWS: Load HttpClientBuilder dynamically to avoid runtime deps of both urlconnection and apache client #6746
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
AWS: Load HttpClientBuilder dynamically to avoid runtime deps of both urlconnection and apache client #6746
Conversation
| DynConstructors.Ctor<HttpClientConfigurations> ctor; | ||
| try { | ||
| ctor = | ||
| DynConstructors.builder(HttpClientConfigurations.class).hiddenImpl(impl).buildChecked(); |
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.
trying to see if we can avoid having to create a new public interface like HttpClientConfigurations. We can have some static methods in non-public class, and dynamically load them using something like
DynMethods.builder("initialize")
.impl(impl, Map.class)
.buildStaticChecked()
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 see Jack's point on not exposing a new public interface. I am wondering if we can define HttpClientConfigurations as a package private abstract class.
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.
Thank you for your suggestions. Currently I switch the implementation to define HttpClientConfigurations.
For the DynMethods way, it seems the final code will be something like:
case HTTP_CLIENT_TYPE_URLCONNECTION:
Object httpClientConfigurations = loadHttpClientConfigurations(
UrlConnectionHttpClientConfigurations.class.getName(),
urlConnectionHttpClientProperties);
((UrlConnectionHttpClientConfigurations)httpClientConfigurations).configureHttpClientBuilder(builder);since we no longer have a interface or superclass. I personally feel it wierd to return and then cast an Object directly here. So I vote +1 for the having a package-private abstract class.
Also, now I am curious about why the previous impl
interface HttpClientConfigurations {
...
does not work. It seems having a package-private interface also will be similar to a package-private abstract class in this case. Is there any design purpose to not use package-private interface or do I misunderstand something here. Thank you in advance for your help.
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.
good question. it is a miss from my end. I just assumed it is a public interface. Yeah, I agree that package-private interface should be same.
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.
The abstract class looks good to me. But why not just having a static method though? In that case we completely save the need for them to inherit the same abstract class.
aws/src/test/java/org/apache/iceberg/aws/TestHttpClientConfigurations.java
Outdated
Show resolved
Hide resolved
aws/src/main/java/org/apache/iceberg/aws/ApacheHttpClientConfigurations.java
Outdated
Show resolved
Hide resolved
| * @param prefix prefix to choose keys from input map | ||
| * @return subset of input map with keys starting with provided prefix | ||
| */ | ||
| public static Map<String, String> propertiesWithPrefixNoTrim( |
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.
"Trim" typically means removing whitespace. Is there a better way to name this method? Maybe the startsWith could be passed as a Predicate<String> and this could be filterProperties? Or maybe filterPropertiesByPrefix?
stevenzwu
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. I assume latest change is tested with the env that can reproduce the issue.
|
|
||
| if (httpClientApacheUseIdleConnectionReaperEnabled != null) { | ||
| builder.useIdleConnectionReaper(httpClientApacheUseIdleConnectionReaperEnabled); | ||
| private Object loadHttpClientConfigurations(String impl) { |
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.
nit: maybe add a brief Javadoc to explain why we are doing the reflection here and link to the github issue for more context.
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.
+1
|
Thanks everyone for reviewing this! I will add a proof of running the latest update on EKS later today or tomorrow |
jackye1995
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.
Looks good to me!
|
I think all the comments are addressed and we have enough vote, I will go ahead and merge this. Thanks for fixing this with such detailed verification! And thanks for the review @stevenzwu @rdblue |
… urlconnection and apache client (apache#6746)


Problem Addressed
This PR fix the problem described in issue #6715 by using reflection to instantiate the httpclient configuration impl class to avoid runtime deps of both
url-connection-clientandapache-httpclientTest Environment
Spark3.3, Scala 2.12.
scripts to spawn spark shell:
Test commands:
Before the fix:
will raise
java.lang.NoClassDefFoundErrorAfter the fix
Successfully create the table, indicating that


url-connection-clientis not required