This proposal has been approved and the Jakarta RPC project has been created.
Visit the project page for the latest information and development.

Jakarta RPC

Wednesday, September 22, 2021 - 17:34 by Aleks Seovic
This proposal is in the Project Proposal Phase (as defined in the Eclipse Development Process) and is written to declare its intent and scope. We solicit additional participation and input from the community. Please login and add your feedback in the comments section.
Is this a specification project?
Patent License
Implementation Patent License
Project
Parent Project
Proposal State
Created
Background

Over the last several years, with the rise of microservices architectures, gRPC has become a de facto standard for inter-service communication. It is more efficient than REST, and leverages HTTP2 to provide full-duplex communication between the client and the server.

The official gRPC support for Java platform is provided by grpc-java project, which is a robust, full-featured implementation of gRPC. However, because of the requirement for Android support, it hasn't really moved past Java 7, and it does not always play nicely with the existing Java and Jakarta EE technologies. For example, a number of classes generated by the existing gRPC tooling, such as various client stubs, are declared as final, which makes them unusable with CDI.

Another issue is that while gRPC itself is marshaller-agnostic, the existing tooling only provides support for Protobuf, which may or may not be the right choice for an application, but is pretty much forced upon users, as supporting any other serialization format requires a thorough understanding of gRPC internals and a lot of very low-level work on developers' part, making services significantly more difficult to implement.

Finally, because of Java 7 compatibility baggage, grpc-java still doesn't work well with Java Module System, even though an issue has been open to address that more than 4 years ago.

Scope

Jakarta RPC aims to make gRPC services and clients easier to implement in Java by:

  1. Eliminating the need for IDL/proto files and build-time code generation
  2. Allowing developers to define gRPC services via annotated classes, similar to how JAX-RS allows you to define REST services
  3. Allowing developers to define gRPC service clients via annotated interfaces, similar to how Eclipse MicroProfile REST Client allows you to define REST clients
  4. Allowing developers to configure marshaller for a service via annotations on the service endpoint classes and client interfaces
  5. Allowing anyone to add support for a new marshaller via well-defined SPI
  6. Providing "syntactic sugar" where appropriate to make both the service and the client implementation simpler.

The implementation of the gRPC transport itself is explicitly NOT in scope. It is expected, but not required, that most Jakarta RPC implementations will leverage existing work done by the grpc-java team.

Description

The main goal of Jakarta RPC project is to make gRPC easier to use within Jakarta EE ecosystem, by allowing developers to define gRPC services and clients the same way they are defining REST services and clients today -- via annotated classes (a la JAX-RS) on the server, and annotated interfaces (a la Eclipse MicroProfile REST Client) on the client -- and by making them easier to integrate with existing Jakarta EE technologies, such as CDI and Config.

An additional goal is to eliminate the need for special tooling and build-time code generation that favors one serialization format: Protobuf. gRPC was designed to be agnostic to the serialization format, and allows independent configuration of payload marshaller for request and response at the RPC method level, so we see no reason to prefer one serialization format over another and force Protobuf upon everyone.

Finally, we want to make sure that Jakarta RPC implementations work well with modern Java versions and fully support Java Module System. 

Why Here?

Jakarta RPC aims to do for gRPC service developers what JAX-RS did for REST service developers, so we believe making it an official Jakarta specification makes perfect sense.

The goal is also to ensure that services and clients implemented according to Jakarta RPC work well with other Jakarta EE technologies, such as CDI and Config, which is not currently the case with plain grpc-java.

Future Work

The main goal for the next twelve months is to finalize the specification with a broader community, and get the 1.0 version of the spec included into one of upcoming Jakarta EE releases, and to implement RI and TCK.

As for evangelism, the goal is to both write about and speak on the subject at Java conferences, and any help in that regard is very much appreciated.

Project Scheduling

The plan is to start work on the spec and RI in Q1 2022, and hopefully finish it in time for Jakarta EE 11 release.

Initial Contribution

The bulk of the contribution currently exists within Helidon gRPC project, and Oracle holds the copyright.

When we set out to implement gRPC support in Helidon, we wanted it to be more along the lines of JAX-RS on the server, and MP REST Client on the client.

On the server you simply implement a CDI bean with some annotated methods, and provide additional metadata, such as service name and the marshaller to use, via class-level annotations. Here are a few examples of Helidon gRPC services:

https://github.com/helidon-sockshop/payment/blob/master/payment-core/src/main/java/io/helidon/examples/sockshop/payment/PaymentGrpc.java (pure gRPC service, which uses JSONB as a marshaller)

https://github.com/helidon-sockshop/shipping/blob/master/shipping-core/src/main/java/io/helidon/examples/sockshop/shipping/ShippingResource.java (single class supports both JAX-RS and gRPC endpoint -- not something I'd recommend, but we wanted to show that it can be done for simple use cases)

https://github.com/coherence-community/todo-list-example/blob/master/java/helidon-server/src/main/java/com/oracle/coherence/examples/todo/server/grpc/ToDoListGrpcApi.java (slightly more complex service implementation, which uses POF for marshaling, and defines message types as nested classes) 

On the client, you simply define an annotated interface and let the framework create and inject proxy for you:

https://github.com/helidon-sockshop/orders/blob/master/orders-core/src/main/java/io/helidon/examples/sockshop/orders/PaymentClient.java

https://github.com/helidon-sockshop/orders/blob/master/orders-core/src/main/java/io/helidon/examples/sockshop/orders/ShippingClient.java

which can then be injected into another CDI bean and used like this:

https://github.com/helidon-sockshop/orders/blob/master/orders-core/src/main/java/io/helidon/examples/sockshop/orders/DefaultOrderProcessor.java#L60

The plan is to move relevant interfaces, classes, and annotations from io.helidon namespace into jakarta namespace, and iterate on the specification with a broader community until we reach concensus.

The spec itself shouldn't have any third party dependencies, but the implementations of the spec will likely depend on  grpc-java, which is licensed under Apache 2.0 license.

Source Repository Type