Java/Kotlin SDK migration guide
The 9.0.0 release of Java and Kotlin SDKs unifies codebases in both SDKs. From now on, Java and Kotlin SDKs will be versioned and released together, and clients using both SDKs will get new features and bug fixes at the same time.
Although we tried to keep the API surface compatible with previous releases, you must make a few changes in your application code when migrating to the Java or Kotlin SDK in version 9.0.0.
Create the PubNub object
Instantiating the PubNub
client through the constructor is no longer allowed. Use the PubNub.create()
method instead.
- Legacy Java SDK
- Legacy Kotlin SDK
- New Java SDK
- New Kotlin SDK
PubNub pubnub = new PubNub(new PNConfiguration(...))
var pubnub = PubNub(PNConfiguration(...))
PubNub pubnub = PubNub.create(new PNConfiguration(...))
var pubnub = PubNub.create(PNConfiguration(...))
Async result callback
The signature of asynchronous API callbacks has changed. PNStatus
is no longer provided or used in the async
callback. The new Result
type lets you access the successful result value or the underlying PubNubException
in case of failure without worrying about potential null pointer exceptions or type mismatches.
The following sections show the legacy (< v.9.0.0) and new (= v.9.0.0) signatures and the proposed usage pattern for obtaining results from the API call.
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 has been reduced and standardized across SDKs.
Subscribe requests
For subscribe requests, the PNStatus
object is used. To get its value, you must add a 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 the category PNConnectionError
. For subscribe failures after an initial successful connection (when PNConnected
has already been received), the status is typically PNUnexpectedDisconnectCategory
.
In all error cases:
-
The
error
field is set totrue
in thePNStatus
. -
The
exception
field contains the underlying exception that caused the disconnect. -
There are no dedicated error categories. To get the error details, you must access the
exception
field of the error.
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, there is no more PNStatus
returned. Instead, a Result
class is used, which can either be a success or a failure.
Success and failure handling
On success, the Result
class delivers the returned value (e.g., 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, for some reason, you were depending on internal classes and methods in your application code, adjust your code as follows:
-
We removed the internal classes that should not be accessed from the compile classpath. That's why, avoid accessing or using these internal classes in your code.
-
All public classes are available in the
com.pubnub.api
package, while we moved internal ones to the dedicatedcom.pubnub.internal
package. Don't access any of the internal classes in your code as they will be eventually removed. -
If you used the
Endpoint
class in your Kotlin code, it previously took two type parameters:Endpoint<Input, Output>
. As we have restricted access to the internalInput
classes, the signature of this class changed toEndpoint<Output>
.
If you notice that the changes affect any other Java or Kotlin SDK functionality, contact support to let us know.