Getting Started Developer Guide Feature Catalog Operator Guide Reference
Docs/Getting Started

My First Aether Slice

Build, test, and deploy your first slice from scratch.

Prerequisites

ToolVersionCheck
Java25+java --version
Maven3.8+mvn --version
JBCT CLI1.0.0-rc1+jbct --version

All JBCT and Aether artifacts are published to Maven Central. The generated POM references them automatically — no additional repository configuration needed.

Step 1: Create Your Slice Project

jbct init my-first-slice --slice
cd my-first-slice

This generates a complete Aether slice project. You can customize coordinates:

jbct init my-first-slice -g org.mycompany -a my-first-slice --slice

Generated directory tree:

my-first-slice/
├── pom.xml                    # Maven build (Java 25, JBCT plugin)
├── jbct.toml                  # JBCT formatter/linter config
├── forge.toml                 # Forge cluster configuration
├── aether.toml                # Runtime resource configuration
├── run-forge.sh               # Start local Forge server
├── start-postgres.sh          # Start PostgreSQL container
├── stop-postgres.sh           # Stop PostgreSQL container
├── deploy-forge.sh            # Deploy to local Forge
├── deploy-test.sh             # Deploy to test environment
├── deploy-prod.sh             # Deploy to production
├── generate-blueprint.sh      # Generate deployment blueprint
├── schema/
│   └── init.sql               # Database initialization
└── src/
    ├── main/
    │   ├── java/.../
    │   │   └── myfirstslice/
    │   │       └── MyFirstSlice.java  # Sample slice
    │   └── resources/
    │       └── slices/
    │           └── MyFirstSlice.toml  # Slice runtime config
    └── test/java/.../
        └── myfirstslice/
            └── MyFirstSliceTest.java

Notice: there's only one Java source file. In Aether, the slice interface, request/response types, error types, factory method, and implementation all live together in one file. This is deliberate — related code stays together.

Step 2: Build and Test

mvn clean verify

This runs the full pipeline:

  1. Compile — with the slice annotation processor
  2. Annotation processing — generates factory class, deployment manifest, HTTP route bindings
  3. Test — runs unit tests
  4. JBCT check — formatting and linting rules
  5. Slice packaging — API and implementation JARs
  6. Blueprint generationtarget/blueprint.toml
  7. Slice verification — manifest well-formedness, dependency scope validation

Step 3: Understand the Generated Code

@Slice
public interface MyFirstSlice {

    record Request(String value) {
        public static Result<Request> request(String value) {
            return Verify.ensure(value, Verify.Is::notBlank, new ValidationError.EmptyValue())
                         .map(Request::new);
        }
    }

    record Response(String result) {}

    sealed interface ValidationError extends Cause {
        record EmptyValue() implements ValidationError {
            @Override
            public String message() {
                return "Value cannot be empty";
            }
        }

        static ValidationError emptyValue() {
            return new EmptyValue();
        }
    }

    Promise<Response> process(Request request);

    static MyFirstSlice myFirstSlice() {
        return request -> Promise.success(new Response("Processed: " + request.value()));
    }
}

Key elements:

Step 4: Run Forge

# Start a local 5-node cluster simulator
./run-forge.sh

Forge starts a 5-node cluster on your laptop — real consensus, real leader election, real routing. Key ports:

ServicePortURL
Dashboard8888http://localhost:8888
App HTTP (via LB)8080http://localhost:8080
Management API5150http://localhost:5150

Open the dashboard to see live metrics, cluster topology, and node status. Stop Forge with Ctrl+C.

Step 5: Deploy

# In another terminal
./deploy-forge.sh

This builds a blueprint artifact, uploads it to the running Forge cluster, and deploys it. You should see the slice activate across nodes in the dashboard.

Test it (the URL path depends on your routes.toml configuration):

curl -s -X POST http://localhost:8080/api/v1/my-first-slice/ \
  -H "Content-Type: application/json" \
  -d '{"value": "hello"}' | jq

Next Steps