Skip to content

Commit

Permalink
Deprecate and don't advertise the buggy StompClient() without WS argu…
Browse files Browse the repository at this point in the history
…ment

Resolves:
#251
  • Loading branch information
joffrey-bion committed Jul 3, 2022
1 parent 87a3521 commit 0d156ea
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 79 deletions.
1 change: 0 additions & 1 deletion docs/artifacts.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ You should pick only one of the `krossbow-stomp-*` artifacts, depending on wheth
| Artifact | Description |
|------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| <pre>krossbow-stomp-core</pre> | The basic multiplatform STOMP client. It implements the STOMP 1.2 protocol on top of the web socket abstraction defined by the `krossbow-websocket-core` module. |
| <pre>krossbow-stomp-default</pre> | A superset of `krossbow-stomp-core` adding a `StompClient` constructor without web socket client argument, defaulting to the builtin implementations provided by `krossbow-websocket-builtin` (brought transitively) |
| <pre>krossbow-stomp-jackson</pre> | A superset of `krossbow-stomp-core` adding JSON conversion features using Jackson (JVM only) |
| <pre>krossbow-stomp-kxserialization</pre> | A superset of `krossbow-stomp-core` adding conversion features using Kotlinx Serialization library (multiplatform). You can leverage the multi-format capabilities of Kotlinx Serialization (JSON, protobuf, CBOR, ...). |
| <pre>krossbow-stomp-kxserialization-json</pre> | A superset of `krossbow-stomp-kxserialization` adding JSON helpers and the JSON format dependency. |
Expand Down
14 changes: 9 additions & 5 deletions docs/migration-guides.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,19 @@ built-in web socket implementation for the current platform.

This approach limited the targets supported by those 2 core modules, even though all of their functionality was
target-agnostic.
In order to support all Kotlin platforms in pure Kotlin modules, the built-in websocket implementations and no-arg
`StompClient` constructor had to be moved to separate modules.
In order to support all Kotlin platforms in pure Kotlin modules, the built-in websocket implementations had to be moved
to a separate module, and the constructor without web socket client was moved to a separate module (and later removed
completely for simplicity).

Breaking dependency changes, in short:

* if you used the `StompClient()` constructor without WS client argument (using the default value), simply declare a
dependency on `krossbow-stomp-default` instead of `krossbow-stomp-core`, or in addition to another STOMP artifact.
* if you used `WebSocketClient.default()` from `krossbow-websocket-core`, or any of the built-in clients directly,
simply change your dependency to `krossbow-websocket-builtin` instead
simply change your dependency to `krossbow-websocket-builtin` instead.
* if you used the `StompClient()` constructor without WS client argument (using the default value), add an explicit
dependency on `krossbow-websocket-builtin` and pass the built-in client explicitly to the constructor:
`StompClient(WebSocketClient.default())`.

Note: the `WebSocketClient.default()` function was since renamed `WebSocketClient.builtIn()` in newer versions.

If you used other web socket implementations than the built-in ones, you don't have to change anything to your
dependencies.
Expand Down
4 changes: 2 additions & 2 deletions docs/stomp/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
The `StompClient` can be configured at construction time using a convenient lambda block:

```kotlin
val stompClient = StompClient {
val stompClient = StompClient(WebSocketClient.builtIn()) {
connectionTimeout = 3.seconds
gracefulDisconnect = false
}
Expand All @@ -17,7 +17,7 @@ val stompConfig = StompConfig().apply {
gracefulDisconnect = false
}

val stompClient = StompClient(config = stompConfig)
val stompClient = StompClient(WebSocketClient.builtIn(), stompConfig)
```

## Configuration options
Expand Down
2 changes: 1 addition & 1 deletion docs/stomp/conversions/custom.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ val myConverter = object : TextMessageConverter {
}
}

StompClient().connect(url).withTextConversions(myConverter).use { session ->
StompClient(WebSocketClient.builtIn()).connect(url).withTextConversions(myConverter).use { session ->
session.convertAndSend("/some/destination", MyPojo("Custom", 42))

val messages = session.subscribe<MyMessage>("/some/topic/destination")
Expand Down
8 changes: 4 additions & 4 deletions docs/stomp/conversions/jackson.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ into a `TypedStompSession`.
This new session type has additional methods that use Jackson to convert your objects into JSON and back:

```kotlin
StompClient().connect(url).withJackson().use { session ->
StompClient(WebSocketClient.builtIn()).connect(url).withJackson().use { session ->
session.convertAndSend("/some/destination", Person("Bob", 42))

val messages: Flow<MyMessage> = session.subscribe<MyMessage>("/some/topic/destination")
Expand All @@ -32,14 +32,14 @@ val customObjectMapper: ObjectMapper = jacksonObjectMapper()
.disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES)
.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS)

val client = StompClient().connect(url)
val client = StompClient(WebSocketClient.builtIn()).connect(url)
val session = client.withJacksonConversions(customObjectMapper)
```

## Dependency

You will need to declare the following Gradle dependency to add these capabilities
(you don't need the core module anymore as it is transitively brought by this one):
To use Jackson conversions, add `krossbow-stomp-jackson` to your Gradle dependencies
(`krossbow-stomp-core` is unnecessary because it's transitively brought by this one):

```kotlin
implementation("org.hildan.krossbow:krossbow-stomp-jackson:{{ git.tag }}")
Expand Down
9 changes: 7 additions & 2 deletions docs/stomp/conversions/kx-serialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ data class Person(val name: String, val age: Int)
@Serializable
data class MyMessage(val timestamp: Long, val author: String, val content: String)

val session = StompClient().connect(url)
val session = StompClient(WebSocketClient.builtIn()).connect(url)
val jsonStompSession = session.withJsonConversions() // adds convenience methods for kotlinx.serialization's conversions

jsonStompSession.use { s ->
Expand All @@ -68,7 +68,7 @@ val json = Json {
ignoreUnknownKeys = true
}

val session = StompClient().connect(url)
val session = StompClient(WebSocketClient.builtIn()).connect(url)
val jsonStompSession = session.withJsonConversions(json)
```

Expand All @@ -95,6 +95,11 @@ implementation("org.hildan.krossbow:krossbow-stomp-kxserialization-json:{{ git.t

This module brings `kotlinx-serialization-json` transitively, so you don't have to add it yourself.

### Additional notes

With this setup, `krossbow-stomp-core` is unnecessary because it's transitively brought by the
`krossbow-stomp-kxserialization` modules.

Note that Kotlinx Serialization also requires a compiler plugin to generate serializers for your `@Serializable` classes.
See the [Kotlinx Serialization doc](https://github.com/Kotlin/kotlinx.serialization#dependency-on-the-json-library)
for more information about this.
6 changes: 3 additions & 3 deletions docs/stomp/conversions/moshi.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ This new session type has additional methods that use Moshi to convert your obje
val moshi = Moshi.Builder()
.addLast(KotlinJsonAdapterFactory())
.build()
StompClient().connect(url).withMoshi(moshi).use { session ->
StompClient(WebSocketClient.builtIn()).connect(url).withMoshi(moshi).use { session ->
session.convertAndSend("/some/destination", Person("Bob", 42))

val messages: Flow<MyMessage> = session.subscribe<MyMessage>("/some/topic/destination")
Expand All @@ -25,8 +25,8 @@ StompClient().connect(url).withMoshi(moshi).use { session ->

## Dependency

You will need to declare the following Gradle dependency to add these capabilities
(you don't need the core module anymore as it is transitively brought by this one):
To use Moshi conversions, add `krossbow-stomp-jackson` to your Gradle dependencies
(`krossbow-stomp-core` is unnecessary because it's transitively brought by this one):

```kotlin
implementation("org.hildan.krossbow:krossbow-stomp-moshi:{{ git.tag }}")
Expand Down
68 changes: 18 additions & 50 deletions docs/stomp/getting-started.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
To quickly get started and use the built-in web socket clients, add the following Gradle dependency to your
`build.gradle(.kts)`:
## Gradle setup

For the basic usage of STOMP without serialization, add the `krossbow-stomp-core` dependency as well as the web socket
module of your choice.

For example to use STOMP with Ktor's web socket client:

```kotlin
implementation("org.hildan.krossbow:krossbow-stomp-default:{{ git.tag }}")
implementation("org.hildan.krossbow:krossbow-stomp-core:{{ git.tag }}")
implementation("org.hildan.krossbow:krossbow-websocket-ktor:{{ git.tag }}")
```

You can find more info about more advanced configuration [below](#gradle-setup).
Check out the [web socket client table](../index.md#web-socket-clients-target-support) to help you choose.
We recommend the built-in client adapters if they cover the Kotlin targets you need to support, it order to limit 3rd
party dependencies.
Otherwise, Ktor is a good choice if you don't have special needs like SockJS.

## Basic usage (without body conversions)

Expand All @@ -14,8 +22,10 @@ This is how to create a STOMP client and interact with it:
```kotlin
import kotlinx.coroutines.flow.*
import org.hildan.krossbow.stomp.*
import org.hildan.krossbow.websocket.*
import org.hildan.krossbow.websocket.builtin.*

val client = StompClient() // custom WebSocketClient and other config can be passed in here
val client = StompClient(WebSocketClient.builtIn()) // other config can be passed in here
val session: StompSession = client.connect(url) // optional login/passcode can be provided here

session.sendText("/some/destination", "Basic text message")
Expand All @@ -41,8 +51,10 @@ a `try`/`finally` block, or use `StompSession.use()`, which is similar to `Close
```kotlin
import kotlinx.coroutines.flow.*
import org.hildan.krossbow.stomp.*
import org.hildan.krossbow.websocket.*
import org.hildan.krossbow.websocket.builtin.*

val client = StompClient() // custom WebSocketClient and other config can be passed in here
val client = StompClient(WebSocketClient.builtIn()) // other config can be passed in here
val session: StompSession = client.connect(url) // optional login/passcode can be provided here

session.use { s ->
Expand All @@ -68,47 +80,3 @@ Check out the following sections to see how to automatically convert your object
* [using Jackson](./conversions/jackson.md) (JVM-only)
* [using Moshi](./conversions/moshi.md) (JVM-only)
* [using custom conversions](./conversions/custom.md)

## Gradle setup

### Using the built-in web socket clients

For the basic usage of STOMP with the built-in web socket clients, you only need the following Gradle dependency:

```kotlin
implementation("org.hildan.krossbow:krossbow-stomp-default:{{ git.tag }}")
```

This provides a [StompClient()](../kdoc/krossbow-stomp-default/org.hildan.krossbow.stomp/-stomp-client.html)
constructor that will automatically use the built-in web socket client for the current platform.

If you want to use STOMP body conversions to serialize/deserialize objects directly into/from STOMP frames, add the
relevant conversion module.
For instance, to use Kotlinx Serialization:

```kotlin
implementation("org.hildan.krossbow:krossbow-stomp-default:{{ git.tag }}")
implementation("org.hildan.krossbow:krossbow-stomp-kxserialization:{{ git.tag }}")
```

### Using third-party web socket clients

If you want to use another web socket client, declare both the core STOMP artifact and the specific web socket artifact.
For example, if you want to use Krossbow with Ktor web socket client:

```kotlin
implementation("org.hildan.krossbow:krossbow-stomp-core:{{ git.tag }}")
implementation("org.hildan.krossbow:krossbow-websocket-ktor:{{ git.tag }}")
```

This way you can call the [StompClient](../kdoc/krossbow-stomp-core/org.hildan.krossbow.stomp/-stomp-client/index.html)
constructor with the web socket client of your choice (e.g. `StompClient(KtorWebSocketClient())`).

If you want to use STOMP body conversions to serialize/deserialize objects directly into/from STOMP frames, replace the
`krossbow-stomp-core` module with the relevant conversion module.
For instance, to use Kotlinx Serialization:

```kotlin
implementation("org.hildan.krossbow:krossbow-stomp-kxserialization:{{ git.tag }}")
implementation("org.hildan.krossbow:krossbow-websocket-ktor:{{ git.tag }}")
```
9 changes: 1 addition & 8 deletions docs/websocket/builtin.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,8 @@ adapts the Foundation framework's

## Dependency information

To use the built-in web socket client for pure web socket interactions, add the following to your `build.gradle`:
To use the built-in web socket clients, add the following to your `build.gradle`:

```kotlin
implementation("org.hildan.krossbow:krossbow-websocket-builtin:{{ git.tag }}")
```

If you're using STOMP with this default built-in client, you actually only need `krossbow-stomp-default`, which
transitively brings `krossbow-websocket-builtin`:

```kotlin
implementation("org.hildan.krossbow:krossbow-stomp-default:{{ git.tag }}")
```
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package org.hildan.krossbow.stomp

import org.hildan.krossbow.stomp.config.StompConfig
import org.hildan.krossbow.websocket.WebSocketClient
import org.hildan.krossbow.websocket.default
import org.hildan.krossbow.websocket.builtin.builtIn

/**
* Creates a new `StompClient` with a default web socket implementation using the built-in client from each platform.
Expand All @@ -12,7 +12,16 @@ import org.hildan.krossbow.websocket.default
*
* You can configure the client by passing an optional [configure] lambda.
*/
@Deprecated(
message = "This helper loads a conflicting StompClientKt class and causes NoSuchMethodError upon connect(). " +
"It will be removed in a future release. Please use an explicit web socket client instead.",
replaceWith = ReplaceWith(
expression = "StompClient(WebSocketClient.builtIn(), configure)",
imports = ["org.hildan.krossbow.websocket.builtin.builtIn"],
),
level = DeprecationLevel.ERROR,
)
fun StompClient(configure: StompConfig.() -> Unit = {}) = StompClient(
webSocketClient = WebSocketClient.default(),
config = StompConfig().apply { configure() },
webSocketClient = WebSocketClient.builtIn(),
configure = configure,
)

0 comments on commit 0d156ea

Please sign in to comment.