Skip to content

Commit 8db9134

Browse files
committed
docs: add a migration guide for mutiny bindings generator 3.x to 4.x
1 parent 859b2a6 commit 8db9134

File tree

2 files changed

+273
-3
lines changed

2 files changed

+273
-3
lines changed

docs/migration-guide-3x-4x.md

Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
# Vert.x Mutiny bindings generator migration guide
2+
3+
## Overview
4+
5+
As stated in the [vertx mutiny bindings generator guide](https://smallrye.io/smallrye-mutiny-vertx-bindings/latest/):
6+
> [Eclipse Vert.x](https://vertx.io/) is the leading toolkit for writing reactive applications on the JVM.
7+
>
8+
> While the Vert.x core APIs expose asynchronous programming through _promise / future_, code generators offer bindings to other asynchronous programming models, including: [Kotlin coroutines](https://github.com/vert-x3/vertx-lang-kotlin/tree/master/vertx-lang-kotlin-coroutines), and [RxJava 1, 2 and 3](https://github.com/vert-x3/vertx-rx).
9+
>
10+
> This project offers [Vert.x](https://vertx.io/) binding for [Mutiny, an intuitive event-driven reactive programming library for Java](https://smallrye.io/smallrye-mutiny/).
11+
12+
With the release of Vert.x 5, important API changes were made, sometimes breaking the compability with Vert.x 4.x projects. It was an opportunity to release a new version of the generator. This guide will walk through the changes between Vert.x-mutiny bindings 3.x and 4.x.
13+
14+
## API changes
15+
Numerous API changes are due to the transition to Vert.x 5.
16+
The Vert.x 4 to 5 migration guide is available at https://vertx.io/docs/guides/vertx-5-migration-guide/.
17+
18+
We provide here a brief summary of the breaking changes.
19+
20+
### No more Callbacks
21+
22+
Complete removal of callback methods such as:
23+
```java
24+
void request(RequestOptions request, Handler<AsyncResult<HttpClientRequest>> callback);
25+
```
26+
27+
They have all been replaced with a Future such as:
28+
```java
29+
Future<HttpClientRequest> request(RequestOptions request);
30+
```
31+
32+
Consequently, the bindings generator only supports the `Future` style and will generate the following:
33+
```java
34+
Uni<HttpClientRequest> request(RequestOptions request);
35+
```
36+
37+
### Deprecated classes are no more
38+
| Sunsetting in 4.x | Replacement in 5.x |
39+
| --------------------- | --------------------------------------------------------------------------------- |
40+
| Vert.x Sync | Vert.x virtual threads |
41+
| Service Factories | None |
42+
| Maven Service Factory | None |
43+
| HTTP Service Factory | None |
44+
| Vert.x Web OpenAPI | [Vert.x Web OpenAPI Router](https://vertx.io/docs/vertx-web-openapi-router/java/) |
45+
| *talk about CLI ?* | |
46+
### Changes with regards to @VertxGen
47+
Numerous classes are now annotated `@DataObject` instead of `@VertxGen`. `@DataObject` annotation existed in Vert.x 4.x and was used mainly for `*Options.java` classes. No wrappers are thus required, the core Vert.x interface is used directly. They will break existing projects are imports are now invalid.
48+
49+
Below are some classes that are not "mutinified" anymore:
50+
- `io.vertx.core.buffer.Buffer`
51+
- `io.vertx.core.net.Address`
52+
- `io.vertx.core.net.SocketAddress`
53+
- `io.vertx.core.parsetools.JsonEvent`
54+
- `io.vertx.core.MultiMap`
55+
- `io.vertx.core.datagram.DatagramPacket`
56+
57+
### SQL clients have been pruned
58+
In Vert.x 4, `Pool` subtypes were used for every kind of databases: `PgPool, MySQLPool, MSSQLPool`, etc. They have all been removed and replaced with client builder subtypes:
59+
60+
```java
61+
// 4.x
62+
PgPool client = PgPool.pool(vertx, connectOptions, poolOptions);
63+
64+
//5.0
65+
Pool client = PgBuilder.pool()
66+
.with(poolOptions)
67+
.connectingTo(connectOptions)
68+
.using(vertx)
69+
.build();
70+
```
71+
72+
## Dropped or replaced modules
73+
74+
| Module | Replacement |
75+
| ------------------- | ----------------------------- |
76+
| service-discovery-* | *dropped* |
77+
| web-openapi | (openapi, web-openapi-router) |
78+
| web-auth-shiro | *dropped* |
79+
| web-auth-webauthn | web-auth-webauthn4j |
80+
| auth-jdbc | *dropped* |
81+
| jdbc-client | *dropped* |
82+
| web-api-contract | *dropped* |
83+
| web-templ-jade | *dropped* |
84+
| stomp | *dropped* |
85+
| shell | *dropped* |
86+
## Using the generator for other APIs
87+
The generator is still open source, and can still be leveraged to produce mutiny bindings for any asynchronous APIs. The generator can be used in any module. This section briefly details how to specify which classes will be subject to generation, before showing how to setup a module to enable mutiny bindings generation.
88+
### Specifying which class to bind for
89+
Let's work with a custom Java module providing a basic greeting service.
90+
```java
91+
package org.acme;
92+
93+
import io.vertx.core.Future;
94+
import io.vertx.codegen.annotations.VertxGen;
95+
96+
@VertxGen
97+
public interface Hello {
98+
default Future<String> hello() {
99+
return Future.succeededFuture("Hello !");
100+
}
101+
}
102+
```
103+
104+
This interface returning a `Future<String>`, it is possible to generate the mutiny equivalent by annotating with `@VertxGen`. The resulting interface is below, in a new package `org.acme.mutiny`.
105+
```java
106+
package org.acme.mutiny;
107+
108+
import io.smallrye.common.annotation.CheckReturnValue;
109+
import io.smallrye.mutiny.Uni;
110+
import io.smallrye.mutiny.vertx.MutinyDelegate;
111+
import io.smallrye.mutiny.vertx.MutinyGen;
112+
import io.smallrye.mutiny.vertx.TypeArg;
113+
import io.vertx.core.Future;
114+
import java.util.function.Supplier;
115+
116+
/**
117+
* <strong>NOTE:</strong> This class has been automatically generated from the {@link org.acme.Hello original} non Mutiny-ified interface.
118+
*
119+
*
120+
* @see org.acme.Hello
121+
*/
122+
@MutinyGen(org.acme.Hello.class)
123+
public class Hello implements MutinyDelegate {
124+
125+
private final org.acme.Hello delegate;
126+
127+
/**
128+
* Create a new instance of {@link Hello} delegating to the given (non-null) instance of {@link org.acme.Hello}.
129+
*/
130+
public Hello(org.acme.Hello delegate) {
131+
// Generated by io.smallrye.mutiny.vertx.apigenerator.shims.DelegateConstructorShim
132+
this.delegate = delegate;
133+
}
134+
135+
/**
136+
* Empty constructor used by CDI, do not use this constructor directly.
137+
*/
138+
Hello() {
139+
// Generated by io.smallrye.mutiny.vertx.apigenerator.shims.NoArgConstructorShimModule
140+
this.delegate = null;
141+
}
142+
143+
public Hello(Object delegate) {
144+
// Generated by io.smallrye.mutiny.vertx.apigenerator.shims.DelegateAsObjectAndTypeArgsConstructorShimModule
145+
this.delegate = (org.acme.Hello) delegate;
146+
}
147+
148+
/**
149+
* Get the <em>delegate</em> instance.
150+
* <p>
151+
* This method returns the instance on which this shim is delegating the calls.
152+
* And so, give you access to the <em>bare</em> API.
153+
* </p>
154+
*
155+
* @return the delegate instance
156+
*/
157+
public org.acme.Hello getDelegate() {
158+
return delegate;
159+
}
160+
161+
/**
162+
* <p>
163+
* Unlike the <em>bare</em> Vert.x variant, this method returns a {@link io.smallrye.mutiny.Uni Uni}.
164+
* The uni emits the result of the operation as item.
165+
* If the operation fails, the uni emits the failure.
166+
* </p>
167+
* <p>
168+
* Don't forget to <em>subscribe</em> on it to trigger the operation.
169+
* </p>
170+
*
171+
*
172+
*
173+
* @return A {@link io.smallrye.mutiny.Uni Uni} representing the asynchronous result of this operation.
174+
* @see org.acme.Hello#hello()
175+
*/
176+
@CheckReturnValue
177+
public Uni<String> hello() {
178+
// Code generated by io.smallrye.mutiny.vertx.apigenerator.shims.UniMethodShimModule;
179+
Supplier<Future<String>> _res = () -> getDelegate().hello();
180+
return Uni.createFrom().completionStage(() -> _res.get().toCompletionStage());
181+
}
182+
183+
/**
184+
* <p>
185+
* Unlike the <em>bare</em> Vert.x variant, this method returns a {@link java.lang.String}.
186+
* This method awaits <strong>indefinitely</strong> for the completion of the underlying asynchronous operation.
187+
* If the operation completes successfully, the result is returned, otherwise the failure is thrown (potentially wrapped in a {@code RuntimeException}).
188+
* </p>
189+
*
190+
*
191+
*
192+
* @return The operation result
193+
* @see org.acme.Hello#hello()
194+
*/
195+
public String helloAndAwait() {
196+
// Code generated by io.smallrye.mutiny.vertx.apigenerator.shims.UniMethodShimModule;
197+
Uni<String> _res = hello();
198+
return _res.await().indefinitely();
199+
}
200+
201+
/**
202+
* <p>
203+
* Unlike the <em>bare</em> Vert.x variant, this method ignores the {@link java.lang.String} result or any failure.
204+
* </p>
205+
*
206+
*
207+
*
208+
* @return The current instance to chain operations if needed.
209+
* @see org.acme.Hello#hello()
210+
*/
211+
public Hello helloAndForget() {
212+
// Code generated by io.smallrye.mutiny.vertx.apigenerator.shims.UniMethodShimModule;
213+
hello().subscribe().with(_ignored -> {});
214+
return this;
215+
}
216+
217+
/**
218+
* Creates a new instance of the {@code Hello}.
219+
*/
220+
public static Hello newInstance(org.acme.Hello delegate) {
221+
// Generated by io.smallrye.mutiny.vertx.apigenerator.shims.NewInstanceMethodShimModule
222+
return delegate != null ? new Hello(delegate) : null;
223+
}
224+
225+
@Override
226+
public int hashCode() {
227+
// // Code generated by io.smallrye.mutiny.vertx.apigenerator.shims.EqualsHashCodeAndToStringShimModule
228+
return delegate.hashCode();
229+
}
230+
231+
@Override
232+
public boolean equals(Object o) {
233+
// // Code generated by io.smallrye.mutiny.vertx.apigenerator.shims.EqualsHashCodeAndToStringShimModule
234+
if (this == o) return true;
235+
if (o == null || getClass() != o.getClass()) return false;
236+
Hello that = (Hello) o;
237+
return delegate.equals(that.getDelegate());
238+
}
239+
240+
@Override
241+
public String toString() {
242+
// // Code generated by io.smallrye.mutiny.vertx.apigenerator.shims.EqualsHashCodeAndToStringShimModule
243+
return delegate.toString();
244+
}
245+
}
246+
```
247+
248+
The original interface is transformed, but the original is kept as a delegate. Other methods such as `boolean equals(Object o)`, `int hashCode()`, `String toString()`, `Hello newInstance(org.acme.Hello delegate)` are generated along with the *"mutinified"* `Uni<String> hello()` and its variants `String helloAndAwait()`, `Hello hellAndForget()`.
249+
250+
The delegate instance is important as every call to `hello`, `helloAndAwait`, `helloAndForget` depends on the transformation of the `Future<String>` in an `Uni<String>`.
251+
252+
> [!warning]
253+
> Every class of your module that uses an `Hello` instance or depends on the `Hello` interface should be annotated `@VertxGen` in order to use the generated `org.acme.mutiny` package instead of the original one in `org.acme`.
254+
255+
### Configuring a module to generate mutiny bindings
256+
It is possible to generate bindings for a module manually, by creating instances of `MutinyGenerator`, or to automate the process by adding build plugins.
257+
#### Using Maven
258+
The generator now works in three distinct phases:
259+
260+
1. Collection
261+
2. Analyzis
262+
3. Generation
263+
264+
Four maven build plugins are used to collect sources, analyze them, and generate new sources.
265+
- ``maven-dependency-plugin`` to gather the sources as well as potential additional sources on which we depend ; and put them is a specific directory `outputDirectory`.
266+
- ``maven-jar-plugin`` to setup the module name in the target jar.
267+
- `exec-maven-plugin` to launch the generator with the settings defined previously. This plugin depends directly on ``io.smallrye.reactive.vertx-mutiny-code-generator`` and requires the following arguments:
268+
- module name `--module-name`
269+
- source folder `--source`
270+
- additional sources folder `--additional-source`
271+
- output folder `--output`
272+
- `build-helper-maven-plugin` to tell maven that the folder in which the bindings were outputed (give as argument `--output` must be compiled and treated as sources.

vertx-mutiny-code-generator/src/test/java/io/smallrye/mutiny/vertx/apigenerator/generation/AndAwaitWithVoidTest.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,4 @@ public interface MyInterface {
3333
env.compile();
3434

3535
assertThat(env.getOutputFor("org.acme.MyInterface").javaFile().toString()).contains("void methodAndAwait()");
36-
37-
}
38-
}
36+

0 commit comments

Comments
 (0)