# Comparison guide: OpenAPI/Swagger Java client generation
Source: https://speakeasy.com/docs/sdks/languages/java/oss-comparison-java

import { Table } from "@/mdx/components";



At Speakeasy, the team specializes in producing idiomatic SDKs in various programming languages, including Java. The approach to SDK generation prioritizes a rich developer experience that enables API providers to concentrate on refining APIs and empowers developer-users to efficiently leverage services.

In this article, we'll compare creating a Java SDK using Speakeasy to creating one using the [OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator).

Below is a table that summarizes the key differences between the two SDKs:

<Table 
  data={[
    { name: "Minimum version", support: "Java 11+ (modern features)", docs: "Java 8+ (legacy support)", notes: "" },
    { name: "Dependencies", support: "✅ Minimal dependencies", docs: "⚠️ Many third-party dependencies", notes: "" },
    { name: "HTTP client", support: "Native Java 11 `java.net.http`", docs: "⚠️ Third-party OkHttp dependency", notes: "" },
    { name: "JSON processing", support: "✅ [Jackson](https://github.com/FasterXML/jackson) (enterprise-ready, faster)", docs: "⚠️ [Gson](https://github.com/google/gson) (simpler, limited config)", notes: "" },
    { name: "Builder pattern", support: "✅ Modern builder pattern", docs: "❌ Traditional setters only", notes: "" },
    { name: "Null safety", support: "✅ Proactive with `Optional` support", docs: "❌ Basic retrospective validation", notes: "" },
    { name: "Retry support", support: "✅ Built-in configurable retries", docs: "❌ Not supported", notes: "" },
    { name: "Documentation", support: "✅ Comprehensive, with examples", docs: "⚠️ Basic documentation", notes: "" },
    { name: "Collections", support: "✅ Modern list implementations", docs: "⚠️ Mix of arrays and lists", notes: "" },
    { name: "Field access", support: "✅ Encapsulated (getter methods)", docs: "❌ Direct field access", notes: "" },
    { name: "OAuth support", support: "✅ Built-in OAuth 2.0", docs: "⚠️ Requires additional library", notes: "" },
    { name: "Pagination", support: "✅ Supported", docs: "❌ Not supported", notes: "" }
  ]}
  columns={[
    { key: "name", header: "Feature" },
    { key: "support", header: "Speakeasy" },
    { key: "docs", header: "OpenAPI Generator" },
    { key: "notes", header: "Notes" }
  ]}
/>

Read more about these headline features of Speakeasy-created Java SDKs in the [March 2024 release notes](/post/release-java-ga), or consult the [Speakeasy Java SDK documentation](/docs/languages/java/methodology-java).

For a detailed technical comparison, read on!

## Installing the CLIs

For this comparison, we need both the Speakeasy and OpenAPI Generator CLIs installed to generate the Java SDKs from the specification YAML file. We're using macOS, so we use Homebrew to install the CLIs.

### Installing the Speakeasy CLI

Install the Speakeasy CLI by running the following command in the terminal:

```bash
brew install speakeasy-api/tap/speakeasy
```

You can check the version to ensure installation was successful:

```bash
speakeasy -v
```

If you encounter any errors, take a look at the [Speakeasy SDK creation documentation](/docs/sdks/create-client-sdks).

### Installing the OpenAPI Generator CLI

Install the OpenAPI Generator CLI by running the following command in the terminal:

```bash
brew install openapi-generator
```

You can check the version:

```bash
openapi-generator version
```

Browse the [OpenAPI Generator documentation](https://github.com/OpenAPITools/openapi-generator/blob/master/README.md) if any errors occur.

## Downloading the Swagger Petstore specification

We need an OpenAPI specification YAML file to generate SDKs for. We'll use the Swagger Petstore specification, which you can find at [https://petstore3.swagger.io/api/v3/openapi.yaml](https://petstore3.swagger.io/api/v3/openapi.yaml).

Download the file in and save it as `petstore.yaml` with the following command in the terminal:

```bash
curl https://petstore3.swagger.io/api/v3/openapi.yaml --output petstore.yaml
```

## Validating the specification file

Let's validate the spec using both the Speakeasy CLI and OpenAPI Generator.

### Validation using Speakeasy

Run the following command in the terminal where the specification file is located:

```bash
speakeasy validate openapi -s petstore.yaml
```

The Speakeasy validator returns the following:

```bash
╭────────────╮╭───────────────╮╭────────────╮
│ Errors (0) ││ Warnings (10) ││ Hints (72) │
├────────────┴┘               └┴────────────┴────────────────────────────────────────────────────────────╮
│                                                                                                        │
│ │ Line 250: operation-success-response - operation `updatePetWithForm` must define at least a single   │
│ │ `2xx` or `3xx` response                                                                              │
│                                                                                                        │
│   Line 277: operation-success-response - operation `deletePet` must define at least a single `2xx` or  │
│   `3xx` response                                                                                       │
│                                                                                                        │
│   Line 413: operation-success-response - operation `deleteOrder` must define at least a single `2xx` o │
│   r                                                                                                    │
│   `3xx` response                                                                                       │
│                                                                                                        │
│   Line 437: operation-success-response - operation `createUser` must define at least a single `2xx` or │
│   `3xx` response                                                                                       │
│                                                                                                        │
│   Line 524: operation-success-response - operation `logoutUser` must define at least a single `2xx` or │
│   `3xx` response                                                                                       │
│                                                                                                        │
│   ••                                                                                                   │
└────────────────────────────────────────────────────────────────────────────────────────────────────────┘
 ←/→ switch tabs  ↑/↓ navigate  ↵ inspect  esc quit
```

The Speakeasy CLI validation result gives us a handy tool for switching between the errors, warnings, and hints tabs with the option to navigate through the results on each tab.

In this instance, Speakeasy generated ten warnings. Let's correct them before continuing.

Notice that some of the warnings contain a `default` response. For completeness, we'd like to explicitly return a `200` HTTP response. We'll make the following modifications in the `petstore.yaml` file.

When the `updatePetWithForm` operation executes successfully, we expect an HTTP `200` response with the updated `Pet` object to be returned.

Insert the following after `responses` on line 250:

```
"200":
  description: successful operation
  content:
    application/xml:
      schema:
        $ref: '#/components/schemas/Pet'
    application/json:
      schema:
        $ref: '#/components/schemas/Pet'
```

Similarly, following successful `createUser` and `updateUser` operations, we'd like to return an HTTP `200` response with a `User` object.

Add the following text to both operations below `responses`:

```
"200":
  description: successful operation
  content:
    application/xml:
      schema:
        $ref: '#/components/schemas/User'
    application/json:
      schema:
        $ref: '#/components/schemas/User'
```

Now we'll add the same response to four operations. Copy the following text:

```
"200":
  description: successful operation
```

Paste this response after `responses` for the following operations:

- `deletePet`
- `deleteOrder`
- `logoutUser`
- `deleteUser`

We are left with three warnings indicating potentially unused or orphaned objects and operations.

For unused objects, locate the following lines of code and delete them:

```
Customer:
  type: object
  properties:
    id:
      type: integer
      format: int64
      example: 100000
    username:
      type: string
      example: fehguy
    address:
      type: array
      xml:
        name: addresses
        wrapped: true
      items:
        $ref: '#/components/schemas/Address'
  xml:
    name: customer
Address:
  type: object
  properties:
    street:
      type: string
      example: 437 Lytton
    city:
      type: string
      example: Palo Alto
    state:
      type: string
      example: CA
    zip:
      type: string
      example: "94301"
  xml:
    name: address
```

To remove the unused request bodies, locate the following lines and delete them:

```
requestBodies:
    Pet:
      description: Pet object that needs to be added to the store
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Pet'
        application/xml:
          schema:
            $ref: '#/components/schemas/Pet'
    UserArray:
      description: List of user object
      content:
        application/json:
          schema:
            type: array
            items:
              $ref: '#/components/schemas/User'
```

Now if you validate the file with the Speakeasy CLI, you'll notice there are no warnings:

```
╭────────────╮╭──────────────╮╭────────────╮
│ Errors (0) ││ Warnings (0) ││ Hints (75) │
├────────────┴┴──────────────┴┘            └─────────────────────────────────────────────────────────────╮
│                                                                                                        │
│ │ Line 51: missing-examples - Missing example for requestBody. Consider adding an example              │
│                                                                                                        │
│   Line 54: missing-examples - Missing example for requestBody. Consider adding an example              │
│                                                                                                        │
│   Line 57: missing-examples - Missing example for requestBody. Consider adding an example              │
│                                                                                                        │
│   Line 65: missing-examples - Missing example for responses. Consider adding an example                │
│                                                                                                        │
│   Line 68: missing-examples - Missing example for responses. Consider adding an example                │
│                                                                                                        │
│   •••••••••••••••                                                                                      │
└────────────────────────────────────────────────────────────────────────────────────────────────────────┘

 ←/→ switch tabs  ↑/↓ navigate  ↵ inspect  esc quit
```

### Validation using OpenAPI Generator

To validate the `petstore.yaml` specification file with OpenAPI Generator, run the following command in the terminal:

```bash
openapi-generator validate -i petstore.yaml
```

The OpenAPI Generator returns the following response, indicating no issues detected.

```bash
Validating spec (petstore.yaml)
No validation issues detected.
```

Now that we have made the `petstore.yaml` file more complete by fixing the warnings, let's use it to create SDKs.

## Creating SDKs

We'll create Java SDKs using Speakeasy and OpenAPI Generator and then compare them.

### Creating an SDK with Speakeasy

Create a Java SDK from the `petstore.yaml` specification file using Speakeasy by running the following command in the terminal:

```bash