> ## Documentation Index
> Fetch the complete documentation index at: https://docs.go.gbgplc.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Java notes

> Installing and working with the Java Core SDK

This page covers what's specific to the Java client. Authentication, regions, operations and error handling work the same way in both languages; for those, see the [Core SDK](https://docs.go.gbgplc.com/docs/go-v2/developer-integration/sdks/core-sdk.md) page.

## Requirements

JDK 11 or later.

## Installation

The SDK is published to Maven Central under the `com.gbg` group.

```groovy Gradle theme={null}
implementation 'com.gbg:go-core-sdk:0.2.1'
```

```xml Maven theme={null}
<dependency>
    <groupId>com.gbg</groupId>
    <artifactId>go-core-sdk</artifactId>
    <version>0.2.1</version>
</dependency>
```

### Building from source

To build the artifact and install it into your local Maven repository:

```bash macOS and Linux theme={null}
./gradlew publishToMavenLocal -Pskip.signing
```

```bash Windows theme={null}
gradlew.bat publishToMavenLocal -Pskip.signing
```

## Call shape

Every operation follows the same three-part pattern: select the resource, name the operation, then call it. The terminal `.call()` is what sends the request.

```java theme={null}
StartJourneyResponse res = go.journeys().start()
        .request(req)
        .call();
```

Between `start()` and `call()` you can attach a `.request()` body or an extra `.header()`. Operations that use their own credential, such as `devices().connect()`, also take a `.security()`.

## Reading responses

Response bodies come back wrapped in `Optional`. The accessor is named after the body type: for example, the response from `journeys().start()` exposes it as `journeyStartResponse()`.

```java theme={null}
StartJourneyResponse res = go.journeys().start()
        .request(req)
        .call();

res.journeyStartResponse()
        .ifPresent(body -> System.out.println(body.instanceId()));
```

Each response also carries `statusCode()`, `contentType()`, and `rawResponse()` if you need to handle the HTTP response yourself.

## Asynchronous calls

Call `.toAsync()` on a built client to get an async client. Standard operations then return a `CompletableFuture<T>` instead of blocking.

```java theme={null}
import com.gbg.gocore.AsyncGo;
import com.gbg.gocore.Go;
import com.gbg.gocore.models.operations.async.StartJourneyResponse;
import java.util.concurrent.CompletableFuture;

AsyncGo go = Go.builder()
        .customerAccess(System.getenv("GO_CUSTOMER_ACCESS"))
        .build()
        .toAsync();

CompletableFuture<StartJourneyResponse> future = go.journeys().start()
        .request(req)
        .call();

future.thenAccept(res ->
        res.journeyStartResponse()
                .ifPresent(body -> System.out.println(body.instanceId())));
```

Note the different package: async response types live under `com.gbg.gocore.models.operations.async`.

### Reactive libraries

Operations that involve multiple I/O interactions return a Reactive Streams `Publisher<T>` rather than a `CompletableFuture<T>`. Reactive Streams was chosen over the JDK Flow API because most reactive toolkits support it natively:

| Library | Conversion |
| - | - |
| Project Reactor | `Flux.from(publisher)` |
| RxJava | `Flowable.fromPublisher(publisher)` |
| Akka Streams | `Source.fromPublisher(publisher)` |
| Vert.x | `ReadStream.fromPublisher(vertx, publisher)` |
| Mutiny (Quarkus) | `Multi.createFrom().publisher(publisher)` |

If you need the JDK Flow API, adapt with `FlowAdapters.toFlowPublisher(publisher)`.

## Jackson configuration

The SDK ships a pre-configured Jackson `ObjectMapper` with the type modules, strict deserializers, and feature flags it needs, including ISO-8601 `OffsetDateTime` serialization.

```java theme={null}
import com.gbg.gocore.utils.JSON;

String json = JSON.getMapper().writeValueAsString(response);
```

If your application already has its own `ObjectMapper`, register the SDK's module on it rather than replacing your mapper:

```java theme={null}
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gbg.gocore.utils.GoCoreSDKJacksonModule;

ObjectMapper mapper = new ObjectMapper()
        .registerModule(new GoCoreSDKJacksonModule());

String json = mapper.writeValueAsString(response);
```

## Logging

The SDK logs through [SLF4J](https://www.slf4j.org/). Add an implementation to your project and configure the levels you want:

* **DEBUG**: HTTP requests and responses, retry attempts, hook execution
* **TRACE**: request and response bodies, backoff calculations

```groovy theme={null}
dependencies {
    implementation 'ch.qos.logback:logback-classic:1.4.14'
}
```

```xml theme={null}
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- SDK-wide logging -->
    <logger name="com.gbg.gocore" level="DEBUG"/>

    <!-- Component-specific logging -->
    <logger name="com.gbg.gocore.utils.SpeakeasyHTTPClient" level="DEBUG"/>
    <logger name="com.gbg.gocore.utils.Retries" level="DEBUG"/>

    <root level="INFO">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>
```

> [!WARNING]
>
> TRACE level logs full request and response bodies, which include access tokens and end-user personal data. Don't enable it in production.

## Further reading

* [Java SDK reference](https://github.com/gbgplc/gbg-go-core-sdk/blob/main/java/README.md)
* [Generated model documentation](https://github.com/gbgplc/gbg-go-core-sdk/tree/main/java/docs)
