Generating Clients#

The Smithy Java build plugin, java-client-codegen, generates Java clients from Smithy models, and can be executed with Gradle (recommended) or the Smithy CLI.

Important

The Smithy CLI is a prerequisite for this guide. See the Smithy CLI installation guide if you do not already have the CLI installed.

Configuring code generation#

In order to execute code generation, the java-client-codegen plugin must be added to your smithy-build config:

smithy-build.json#
{
  "version": "1.0",
  "plugins": {
+    "java-client-codegen": {
+      "service": "com.example#CoffeeShop", // <- Replace with your service's ID
+      // Generated Java code will use this as the root package namespace
+      "namespace": "com.example.cafe"
+    }
  }
}

Add generated code to the Java sourceSet#

Your package is now configured to generate Java client source code. However, the generated code must be added to a sourceSet to be compiled by Gradle. To add the generated code to the main sourceSet, add the following to your Gradle build script:

build.gradle.kts#
 // Add generated Java sources to the main sourceSet so they are compiled alongside
 // any other Java code in your package
 afterEvaluate {
     val clientPath = smithy.getPluginProjectionPath(smithy.sourceProjection.get(), "java-client-codegen")
     sourceSets {
         main {
             java {
                 srcDir(clientPath)
             }
         }
     }
 }

 // Ensure client files are generated before java compilation is executed.
 tasks.named("compileJava") {
     dependsOn("smithyBuild")
 }

Generating code#

To generate and compile your client code, run a build from the root of your Gradle project:

./gradlew clean build

Building the project will generate code in the build/smithy-projections/<project-name>/source/java-client-codegen/ directory.

Complete example#

The following Gradle build script and smithy-build.json files provide a complete example of how to configure a Gradle project to generate a Smithy Java client:

build.gradle.kts#
 plugins {
     `java-library`
     id("software.amazon.smithy.gradle.smithy-base") version "1.2.0"
 }

 dependencies {
     // Add the code generation plugin to the smithy build dependencies
     smithyBuild("software.amazon.smithy.java.codegen:client:0.0.1")

     // Add any smithy model dependencies as `implementation` dependencies here.
     // For example, you might add additional trait packages here.
     implementation("...")

     // Add the client-core dependency needed by the generated code
     implementation("software.amazon.smithy.java:client-core:0.0.1")

     // Also add your protocol implementations or auth schemes as dependencies
     implementation("com.example:my-protocol:1.0.0")
     implementation("com.example:my-auth-scheme:1.0.0")
 }

 // Add generated Java sources to the main sourceSet so they are compiled alongside
 // any other java code in your package
 afterEvaluate {
     val clientPath = smithy.getPluginProjectionPath(smithy.sourceProjection.get(), "java-client-codegen")
     sourceSets {
         main {
             java {
                 srcDir(clientPath)
             }
         }
     }
 }

 // Ensure client files are generated before java compilation is executed.
 tasks.named("compileJava") {
     dependsOn("smithyBuild")
 }

 repositories {
     mavenLocal()
     mavenCentral()
 }
smithy-build.json#
 {
   "version": "1.0",
   "plugins": {
     "java-client-codegen": {
       "service": "com.example#CoffeeShop",
       "namespace": "com.example.cafe",
       // Default protocol for the client. Must have a corresponding trait in the
       // model and implementation discoverable via SPI (see section on protocols below)
       "protocol": "aws.protocols#restJson1",
       // Adds a common header to all generated files
       "headerFile": "license.txt"
     }
   }
 }