aws / aws-sdk-java-v2

The official AWS SDK for Java - Version 2
Apache License 2.0
2.12k stars 803 forks source link

Java 11 HTTP Client #1447

Open gabfssilva opened 4 years ago

gabfssilva commented 4 years ago

There's a branch that contains a Java 11 HTTP client implementation (java-11-http-client). I see it's several commits behind master.

Is there any reason why this wasn't merged before? Can someone tell what's left to do? This is a really nice feature if someone doesn't want to include Netty into their app library. ;)

I ask this because I'm willing to work on it if it's possible.

jamesratzlaff commented 4 years ago

@gabfssilva I'm want this as well and willing to contribute with you on this (if you want).

spfink commented 4 years ago

@dagnir is going to work on getting this into a better branch for further development. I believe it's pretty far along but we definitely are open to contributions.

I think the biggest time blocker is updating our release system to be able to release this on a daily basis since our release tooling is all built to use JDK8 and not JDK11. We'll figure out what state we are in to be able to release this and follow back up.

fvasco commented 4 years ago

@spfink did you know https://github.com/rmcsoft/j11_aws_http_client ?

gabfssilva commented 4 years ago

@fvasco I guess the big issue is not about the implementation itself but with how's the build is going to work with the other modules. It'd be nice to isolate only the new http client module to build with Java 11. Not sure if doing it is straightforward tho.

fvasco commented 4 years ago

@gabfssilva I really hope this is not a big issue. Java 11 compiler supports the --release option.

carlspring commented 3 years ago

Any updates on this?

debora-ito commented 3 years ago

No updates at this time.

GSSwain commented 3 years ago

+1

gabfssilva commented 3 years ago

Since we're waiting a lot for this, today I started to work on this: https://github.com/gabfssilva/aws-spi-java-11 It's pretty early, but I'll try to release an alpha version by the end of the week.

nrbw commented 2 years ago

Hello, I'm struggling using aws sdk java v2 with OpenJ9 JDK 11. What's the status on this issue ? @gabfssilva you mentioned netty for a workaround, do you have any pointer on how to use it ?

gabfssilva commented 2 years ago

You shouldn't have any issue using this SDK with OpenJ9, this issue that I've created is to use the Java 11 HTTP client instead of Netty, the default client for the SDK. I've used this library with OpenJ9 without any issues whatsoever, are you seeing any errors when you run on OpenJ9 that don't happen when you run with Hotspot?

What about creating a specific issue for your problem? Maybe it makes more sense, @nrbw.

fvasco commented 2 years ago

Removing the Netty dependency is a big step to reduce the deployment size of a JVM lambda (really important in a cold start). I hope that Netty become not more than an optional dependency.

nrbw commented 2 years ago

Sorry for the late response. I found out I had trouble with SSL connexion with my S3 provider. The problem was not with the sdk itself. The only problem is that it doesn't report for the real issue ...

sigpwned commented 1 year ago

As of SDK release 2.20.0, there is now also aws-crt-client, which provides AwsCrtAsyncHttpClient. It adds about 10MB of dependencies due to aws-crt, so it's definitely heavier than using the built-in Java 11 HttpClient would be, but doesn't require netty. Depending on your requirements and preferences, YMMV.

zoewangg commented 1 year ago

@sigpwned AWS CRT supports platform-specific JARs and you can select the right favor for your application to reduce the JAR size. https://github.com/awslabs/aws-crt-java#platform-specific-jars-experimental

einarjohnson commented 11 months ago

+1

ingram90 commented 5 months ago

It's 2024 now, any progress on supporting Java 11 HttpClient?

Now that JDK 21 has been released, an HTTP client suitable for running in a virtual thread is more crucial than ever before.

sigpwned commented 5 months ago

Is there a reason that UrlConnectionHttpClient is unsuitable for use in virtual threads? Genuinely curious. My read is that virtual threads reduce the importance of supporting the Java 11 client, not increase it.

ingram90 commented 5 months ago

The UrlConnectionHttpClient is suitable for use in virtual threads; however, it lacks support for connection pools and HTTP PATCH, the latter being essential for various AWS APIs.

On the other hand, the Apache HttpClient (version 4) relies on synchronization internally, which can lead to issues such as thread pinning and deadlocks. (see https://issues.apache.org/jira/projects/HTTPCORE/issues/HTTPCORE-746?filter=allissues for details.)

Considering the requirements of AWS Java SDK under virtual threads, the available options are limited.

zoewangg commented 5 months ago

Hi @ingram90 and anyone who would like to see this feature supported in the SDK, can you let us know what is your use-case for Java 11 HTTP client?

If the use-case is reducing start up latency, we'd recommend AwsCrtHttpClient(sync) and AwsCrtAsyncHttpClient(async), which have lower startup latency compared to other HTTP clients supported in the SDK. You can see our Dev Guide for more information https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration.html.

Note that AWS CRT Java supports platform-specific JARs, so you only need to include the dependency for the platform you need instead of the uber JAR. https://github.com/awslabs/aws-crt-java#platform-specific-jars

SentryMan commented 5 months ago

what is your use-case for Java 11 HTTP client?

A big one is that the built-in client does not require large external dependencies to function.

zoewangg commented 5 months ago

@SentryMan I think it makes sense, but could you go into more details? What does no external dependencies mean to you? Less maintenance efforts, smaller JAR size, or something else?

SentryMan commented 5 months ago

I deploy a bunch of Java applications in lambda so keeping my application size down is a priority for me. The fact that it natively supports virtual threads is a great bonus as well.

ingram90 commented 5 months ago

@zoewangg

The primary focus at the moment revolves around virtual threads. Is the AWS CRT client capable of supporting virtual threads without pinning? I haven't found any official documentation or analyses addressing this concern. Considering that the CRT employs native methods, which inherently involve thread pinning, it is not our preferred option at the moment.

We are currently in the process of assessing the compatibility of CRT with virtual threads. However, using the Java 11 Http Client seems to be a more straightforward path for us.

fvasco commented 5 months ago

@zoewangg

Currently all AWS libraries require Netty: a large library that provides functionality already present in the Java platform. I want to swap the question: why do AWS libraries require Netty? The historical reason is poor motivation, IMHO. Also "Great Performance", everyone can enable Netty dependency at compile time without hassle. Finally: it's easier for a developer to use an incompatible Netty version, without fighting with AWS dependencies.

sigpwned commented 5 months ago

I took a minute yesterday and ripped the Java 11 HTTP Client implementation out of the java-11-http-client branch on this repo, lightly modernized it, and put it in a new repo at sigpwned/aws-java-sdk-v2-java-nio-client.

It builds, passes tests, and generates JavaDoc, but I haven't released it because I haven't had the time to give it a proper once-over yet. I hope to add a synchronous client and do a release ASAP this week.

Of course, all feedback and contributions welcome. If we can get this working, I think it will be of significant interest to the community!

sigpwned commented 5 months ago

OK, I've had a minute to look things over. Here's where things stand on the updated Java client:

I'll take on the basic blocking and tackling of Continuous Integration, Maven setup, and so on over the next few days.

If anyone has an interest in helping out on the above, sigpwned/aws-java-sdk-v2-java-nio-client#2 breaks out all the above in more detail. Please leave comments and/or PRs with any updates. All work is appreciated, and naturally you would be added to contributors!

If anyone who works/has worked on the AWS Java SDK in an official capacity can weigh in on testing best practices, it would be particularly appreciated. @zoewangg, I'm hoping you might be able to give us a little guidance on what kind of testing is expected for "official" libraries (although I fully understand that this is an unofficial library with no support or approval by Amazon implied). Mostly, I'm just trying to figure out how we can make sure this project works for everyone, and I suspect that Amazon has put some thought into that already. 😉

@Quanzzzz and @dagnir, I thought you might enjoy hearing that your project from years ago is getting some attention right now. 😄 Any thoughts or assistance you feel like contributing would be a huge asset!

Also, I hope no one minds, but I've also added everyone who has contributed in the conversation in the last few years to the contributor list. Thanks to all the below for helping form the idea for this project:

I'm looking forward to working with everyone to get this library ready for community consumption!

SentryMan commented 5 months ago

Most excellent, I'm looking forward to it. It's unfortunate though that the official AWS SDK does not have this functionality.

sigpwned commented 5 months ago

I've got a (preliminary, beta) release of the AWS Java SDK v2 Java 11 Async HTTP Client deployed to Maven Central. You can add it to your project with GAV com.sigpwned:awssdkv2-java11-async-client:2.37.7.0-b0:

<dependency>
    <groupId>com.sigpwned</groupId>
    <artifactId>awssdkv2-java11-async-client</artifactId>
    <version>2.37.7.0-b0</version>
</depenency>

Also, the GitHub repo has moved to @sigpwned/aws-java-sdk-v2-java-11-client.

All feedback -- even if it's just "I tried it, and it worked" -- is welcome, appreciated, and useful! Issues and PRs are even better.

Here's what's left in the plan:

marcogrcr commented 3 months ago

@ingram90 , @sigpwned, @zoewangg Thanks for your comments! I'm particularly interested in the virtual threads use case.

Deployment artifacts size aside, until an official or stable third-party Java 11 HTTP client exists, if I want to take advantage of virtual threads in production code, is there any concern with using software.amazon.awssdk:netty-nio-client or software.amazon.awssdk:aws-crt-client as follows:

final var client = DynamoDbAsyncClient
    .builder()
    .httpClientBuilder(
        // See: https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-netty.html
        NettyNioAsyncHttpClient
                .builder()
                .maxConcurrency(/* ... */)
    )
    .asyncConfiguration(b -> b
        .advancedOption(
            // See: https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/asynchronous.html
            SdkAdvancedAsyncClientOption.FUTURE_COMPLETION_EXECUTOR,
            Executors.newVirtualThreadPerTaskExecutor()
        )
    )
    .build();

Thread.startVirtualThread(() -> {
    try {
        /*
        * This will complete asynchronously via Netty/CRT's internal threads (if any).
        * In the case of Netty HTTP client, AWS SDK will use a virtual thread to process the
        * continuation of the future returned by Netty.
        */
        final var future = client.getItem(r -> r.tableName("...").key(Map.of("...", AttributeValue.fromS("..."))));

        /*
         * This will block the current virtual thread, releasing the carrier platform thread to do other work.
         * We use `.get()` instead of `.join()` so the Virtual Thread can react to interrupts.
         */
        final var response = future.get();

        // TODO: do something with response
    } catch (ExecutionException | InterruptedException e) {
        e.printStackTrace(System.out);
    }
});

A more detailed example can be found here and the results are promising.

Are there any gotchas that I'm missing?

SentryMan commented 3 months ago

Seems a bit off topic, but at first glance I'm not seeing anything egregious

marcogrcr commented 3 months ago

On the other hand, the Apache HttpClient (version 4) relies on synchronization internally, which can lead to issues such as thread pinning and deadlocks. (see https://issues.apache.org/jira/projects/HTTPCORE/issues/HTTPCORE-746?filter=allissues for details.)

Apache HTTP Client is planning to support them in 5.3.x. However, as of today, the latest software.amazon.awssdk:apache-client:2.25.14 depends on Apache client 4.x.x.

Despite a Java 11 HTTP Client being the ideal path (smaller deployment artifact sizes), upgrading the underlying Apache client is an alternative.

hrstoyanov commented 3 months ago

It's a pity that developers who pay for AWS services (or work for someone who pays) have to justify the obvious benefits of using a Java 11 http client and spend time to fix Amazon's software. Using the Java 11 http client with virtual threads eliminates the need for async, on top of the other benefits already mentioned (less external dependencies bloat, smaller deployable, less security attack surface, no "jar hell", etc).

AWS SDK CRT http client library has this problems:

What would be awesome is, if the Amazon team comes up with a timeline for Java AWS SDK v3 that:

It is doable! Oracle's team ditched Netty and reimplemented the Helidon 4 server with virtual threads, with spectacular performance results!

kpodkalicki commented 3 weeks ago

Any updates on this issue?

SentryMan commented 2 weeks ago

@sigpwned Perhaps if you make a PR adding your implementation they'll take it then?