Skip to content
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

Java 11 HTTP Client #1447

Open
gabfssilva opened this issue Sep 30, 2019 · 36 comments
Open

Java 11 HTTP Client #1447

gabfssilva opened this issue Sep 30, 2019 · 36 comments
Labels
feature-request A feature should be added or improved. p1 This is a high priority issue

Comments

@gabfssilva
Copy link

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
Copy link

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

@spfink
Copy link
Contributor

spfink commented Oct 2, 2019

@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.

@zoewangg zoewangg added the feature-request A feature should be added or improved. label Oct 3, 2019
@fvasco
Copy link

fvasco commented Jan 21, 2020

@gabfssilva
Copy link
Author

@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
Copy link

fvasco commented Jan 22, 2020

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

@carlspring
Copy link

Any updates on this?

@debora-ito
Copy link
Member

No updates at this time.

@GSSwain
Copy link

GSSwain commented Apr 22, 2021

+1

@gabfssilva
Copy link
Author

gabfssilva commented May 3, 2021

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.

aws-sdk-java-automation added a commit that referenced this issue Jun 4, 2021
…186f497d9

Pull request: release <- staging/505221ed-0a31-4c56-93b5-090186f497d9
@nrbw
Copy link

nrbw commented Jul 15, 2021

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
Copy link
Author

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
Copy link

fvasco commented Jul 16, 2021

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
Copy link

nrbw commented Oct 8, 2021

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 ...

@yasminetalby yasminetalby added the p1 This is a high priority issue label Nov 29, 2022
@sigpwned
Copy link

sigpwned commented Feb 24, 2023

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
Copy link
Contributor

@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
Copy link

+1

@ingram90
Copy link

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
Copy link

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
Copy link

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
Copy link
Contributor

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
Copy link

SentryMan commented Jan 19, 2024

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
Copy link
Contributor

@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
Copy link

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
Copy link

@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
Copy link

fvasco commented Jan 20, 2024

@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
Copy link

sigpwned commented Jan 21, 2024

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
Copy link

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

  • I've lightly audited the other HTTP clients, and there is at least some "standard" test coverage for HTTP clients in the form of test suites. These need to be added to the new client.
  • The Netty client in particular has a huge test library. A more detailed audit of the various and sundry HTTP clients is needed to determine which tests are required for the new client, and why.
  • Once it's clear what tests are needed, these tests need to be added to the new client project.

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-11-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
Copy link

SentryMan commented Jan 22, 2024

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

@sigpwned
Copy link

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
Copy link

marcogrcr commented Mar 21, 2024

@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
Copy link

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

@marcogrcr
Copy link

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
Copy link

hrstoyanov commented Mar 28, 2024

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:

  • is Java 8 based
  • not modularized
  • HTTP 1 only
  • no one has tested it with virtual threads.

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

  • requires Java 21+.
  • uses Java 11 http client.
  • replace Async with virtual threads.

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

@kpodkalicki
Copy link

Any updates on this issue?

@SentryMan
Copy link

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

@lazystone
Copy link

@hrstoyanov

no one has tested it with virtual threads

Well, I did. Nothing unexpected - does not work properly.

Since AWS CRT is a native binaries with java wrappers, results are quite predictable - thread pinning on foreign function invocations and a deadlock.

@debora-ito can somebody from AWS step in and answer on those issues(including this one)? This silence is getting disreputable for such a huge company.

Virtual threads are being getting adopted. This is a reality - no hiding from this.

Also the fact that AWS SDK still supports Java 8 - IS NOT AN EXCUSE, since we have Multi-Release JARs.

Amazon DO CAN provide one jar which can use benefits of different versions of Java. As other libraries do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request A feature should be added or improved. p1 This is a high priority issue
Projects
None yet
Development

No branches or pull requests