---
title: Complete Java Example
slug: devicepark/sdk-documentation/examples/java-quickstart
description: Run a complete Java allocation and session lifecycle.
docTags: 
createdAt: 2026-08-10T08:03:45.536Z
---

This example lists a device, creates an allocation, starts and stops one session, then releases the allocation. It uses try-with-resources and attempts cleanup even when the test flow fails.

Add the SDK dependency described in [Installation](docId\:CGcNHeobHYgMIAJSgu6Ch), then set credentials:

```bash
export DEVICEPARK_CLIENT_ID=your-client-id
export DEVICEPARK_CLIENT_SECRET=your-client-secret
```

Create `DeviceParkQuickstart.java`:

```java
import io.testinium.devicepark.DeviceParkApiClient;
import io.testinium.devicepark.authentication.credentials.Credentials;
import io.testinium.devicepark.model.allocation.Allocation;
import io.testinium.devicepark.model.allocation.DeviceAllocationRequest;
import io.testinium.devicepark.model.common.PageDto;
import io.testinium.devicepark.model.devices.Device;
import io.testinium.devicepark.model.devices.ListDevicesRequest;
import io.testinium.devicepark.model.sessions.DeviceStartSessionRequest;
import io.testinium.devicepark.model.sessions.Session;

public final class DeviceParkQuickstart {

    private DeviceParkQuickstart() {
    }

    public static void main(String[] args) throws Exception {
        String allocationId = null;
        String sessionId = null;

        try (DeviceParkApiClient client = DeviceParkApiClient.builder()
                .url("https://devicepark.testinium.io")
                .credentials(Credentials.of(
                        System.getenv("DEVICEPARK_CLIENT_ID"),
                        System.getenv("DEVICEPARK_CLIENT_SECRET")))
                .timeout(60)
                .build()) {
            try {
                PageDto<Device> devices = client.devices().list(
                        ListDevicesRequest.builder().page(0).size(20).build());

                Device device = devices.data().stream()
                        .filter(candidate -> candidate.serial() != null)
                        .findFirst()
                        .orElseThrow(() -> new IllegalStateException(
                                "No visible device has a serial number"));

                Allocation allocation = client.allocations().create(
                        DeviceAllocationRequest.builder()
                                .serial(device.serial())
                                .priority(3)
                                .build());

                allocationId = requireValue(
                        allocation.allocationId(),
                        "Allocation response does not contain allocationId");

                if (allocation.deviceSerial() == null) {
                    throw new IllegalStateException(
                            "Allocation " + allocationId
                                    + " is queued at position " + allocation.position());
                }

                Session session = client.sessions().start(
                        DeviceStartSessionRequest.builder()
                                .allocationId(allocationId)
                                .userId(42L)
                                .userEmail("qa@example.com")
                                .companyId(7L)
                                .companyName("Example Company")
                                .videoRecording(true)
                                .build());

                sessionId = requireValue(
                        session.sessionId(),
                        "Session response does not contain sessionId");

                System.out.printf(
                        "allocationId=%s sessionId=%s deviceSerial=%s%n",
                        allocationId,
                        sessionId,
                        session.deviceSerial());

                // Run Appium automation here while the session is active.
            } finally {
                if (sessionId != null) {
                    try {
                        client.sessions().stop(sessionId);
                    } catch (RuntimeException cleanupError) {
                        System.err.println("Could not stop session " + sessionId);
                    }
                }

                if (allocationId != null) {
                    try {
                        client.allocations().delete(allocationId);
                    } catch (RuntimeException cleanupError) {
                        System.err.println("Could not release allocation " + allocationId);
                    }
                }
            }
        }
    }

    private static String requireValue(String value, String message) {
        if (value == null || value.trim().isEmpty()) {
            throw new IllegalStateException(message);
        }
        return value;
    }
}
```

If the allocation enters the queue, this minimal example reports its position and releases it during cleanup. A production runner should keep the same `allocationId`, inspect [List Allocations](docId\:GGobQpsUr2aKNz0jfCNYD) until `deviceSerial` is assigned, and enforce its own maximum wait time.

## Continue

- [Understand allocation targeting and queue behavior](docId\:sPz_N5rutGOmDKrBjbb0L)
- [Review Java failure behavior](docId\:nZrw0_UkMOapMnZtgQtMI)
- [Review exact method signatures](docId\:OoaKfd3Ua6tGD-fnw_WuH)
