Java/Kotlin SDK migration guide
The 9.0.0 release of Java and Kotlin SDKs unifies both codebases. From now on, the SDKs are versioned and released together, so clients using both receive features and fixes at the same time.
We kept the API surface close to earlier releases. To upgrade to the Java or Kotlin SDK v9.0.0, you make a few focused updates in your application code for PubNub usage.
Create the PubNub object
Use PNConfiguration.builder()
to configure, then PubNub.create()
to instantiate the client. This approach replaces direct constructor use.
- Legacy Java SDK
- Legacy Kotlin SDK
- New Java SDK
- New Kotlin SDK
PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId("yourUserId"), "yourSubscribeKey");
configBuilder.publishKey("myPublishKey");
PubNub pubnub = PubNub.create(configBuilder.build());
val builder = PNConfiguration.builder(UserId("myUniquesUserID"), "subscribeKey") {
publishKey = "publishKey"
}
val pubnub = PubNub.create(builder.build())
PubNub pubnub = PubNub.create(new PNConfiguration(...))
var pubnub = PubNub.create(PNConfiguration(...))
Async result callback
The asynchronous API callback signature has changed. PNStatus
is no longer provided in the async
callback. The new Result
type gives you either the successful value or a PubNubException
, with no null checks or type mismatches.
The sections below show legacy (< v9.0.0) and v9.0.0 signatures and a recommended usage pattern for getting results from API calls.
Function signature
- Legacy Java SDK
- Legacy Kotlin SDK
- New Java SDK
- New Kotlin SDK
public void async(@NotNull final PNCallback<Output> callback)
public interface PNCallback<@Nullable X> {
void onResponse(@Nullable X result, @NotNull PNStatus status);
}
fun async(callback: (result: Output?, status: PNStatus) -> Unit)
public void async(@NotNull final Consumer<Result<Output>> callback)
public interface Consumer<Result<Output>> {
void accept(Result<Output> result);
}
fun async(callback: (Result<Output>) -> Unit)
Usage pattern
- Legacy Java SDK
- Legacy Kotlin SDK
- New Java SDK
- New Kotlin SDK
pubnub.publish(...).async((result, status) -> {
if (status.isError()) {
// handle error either by looking at the exception, error or category:
status.getErrorData()
status.getCategory()
} else {
// handle success
System.out.println(
"Sent message with timetoken: " + result.getTimetoken()
);
}
});
pubnub.publish(...).async { result, status ->
if (status.isError()) {
// handle error either by looking at the exception, error or category:
status.exception
status.category
} else {
// handle success
println(
"Sent message with timetoken: " + result!!.timetoken
)
}
}
pubnub.publish(...).async(result -> {
result.onFailure((PubNubException exception) -> {
// handle error
System.err.println("Got exception: " + exception);
}).onSuccess(pnPublishResult -> {
// handle success
System.out.println(
"Sent message with timetoken: " + pnPublishResult.getTimetoken()
);
});
});
// alternative version
pubnub.publish(...).async(result -> {
show all 25 linespubnub.publish(...).async { result ->
result.onFailure { exception ->
// handle error
println("Got exception: " + exception);
}.onSuccess { pnPublishResult ->
// handle success
println(
"Sent message with timetoken: " + pnPublishResult.timetoken
)
}
}
// alternative version
pubnub.publish(...).async { result ->
show all 25 linesStatuses
PNStatus
is still used for subscribe calls, while a Result
class is used for other requests. The set of possible statuses is reduced and standardized across SDKs.
Subscribe requests
For subscribe requests, use the PNStatus
object. To get its value, see StatusListener.
// Adding the status listener to the PubNub client
pubnub.addListener(object : StatusListener() {
override fun status(pubnub: PubNub, status: PNStatus) {
// This block is executed asynchronously for each status update
println("Connection Status: ${status.category}")
}
})
Error statuses
For initial subscribe failures, you receive a status with category PNConnectionError
. For failures after an initial successful connection (after PNConnected
), the status is typically PNUnexpectedDisconnectCategory
.
Current statuses
For more on current statuses, see Status Events in the Java SDK and Status Events in the Kotlin SDK.
In all error cases:
- The
error
field istrue
inPNStatus
. - The
exception
field contains the exception that caused the disconnect. - There are no dedicated error categories. To get details, use the
exception
field.
Access Manager
Access Manager errors now appear as follows:
PubNubException(errorMessage={"message": "Forbidden", "payload": {"channels": ["abc"]}, "error": true, "service": "Access Manager", "status": 403},
pubnubError=PubNubError(name=HTTP_ERROR, code=103, message='HTTP Error. Please check network connectivity.'),
jso={"message":"Forbidden","payload":{"channels":["abc"]},"error":true,"service":"Access Manager","status":403},
statusCode=403,
affectedChannels=[abc])
Non-subscribe requests
For non-subscribe requests like publish, you now receive a Result
(success or failure) instead of PNStatus
.
Success and failure handling
On success, Result
delivers the returned value (for example, PNPublishResult
). On failure, it delivers a PubNubException
.
Publish success and failure handling example
pubNub.publish("abc", "test").async {
it.onSuccess { result: PNPublishResult ->
println(result)
}.onFailure { exception: PubNubException ->
println(exception)
}
}
Minor API differences
If you depended on internal classes or methods, adjust your code as follows:
- Internal classes are no longer on the compile classpath. Avoid accessing or using them in your code.
- All public classes are in the
com.pubnub.api
package. Internal ones are incom.pubnub.internal
. Avoid using internal classes because they can change or be removed. - If you used the
Endpoint
class in Kotlin, it previously took two type parameters:Endpoint<Input, Output>
. Because access to internalInput
classes is restricted, the signature is nowEndpoint<Output>
.
If you see other impacts to Java or Kotlin SDK functionality, contact support and we’ll help you move forward quickly.