A2A Hello World Example
April 10, 2026 ยท View on GitHub
This example demonstrates how to use the A2A Java SDK to communicate with an A2A server. The example includes a Java client that sends both regular and streaming messages to a Python A2A server.
Prerequisites
- Java 11 or higher
- JBang (see INSTALL_JBANG.md for quick installation instructions)
- Python 3.8 or higher
- uv (recommended) or pip
- Git
Setup and Run the Python A2A Server
The Python A2A server is part of the a2a-samples project. To set it up and run it:
-
Clone the a2a-samples repository:
git clone https://github.com/google-a2a/a2a-samples.git cd a2a-samples/samples/python/agents/helloworld -
Recommended method: Install dependencies using uv (much faster Python package installer):
# Install uv if you don't have it already # On macOS and Linux curl -LsSf https://astral.sh/uv/install.sh | sh # On Windows powershell -c "irm https://astral.sh/uv/install.ps1 | iex" # Install the package using uv uv venv source .venv/bin/activate # On Windows: .venv\Scripts\activate uv pip install -e . -
Run the server with uv (recommended):
uv run .
The server will start running on http://localhost:9999.
Using the Java Server Instead
Alternatively, you can use the Java server example instead of the Python server. The Java server supports multiple transport protocols (JSONRPC, GRPC, and HTTP+JSON). See the server README for details on starting the Java server with different transport protocols.
Run the Java A2A Client
The Java client can be run using either Maven or JBang.
Build the A2A Java SDK
First, ensure you have built the a2a-java project:
cd /path/to/a2a-java
mvn clean install
Option 1: Using Maven (Recommended)
Run the client using Maven's exec plugin:
cd examples/helloworld/client
mvn exec:java
Transport Protocol Selection
The client supports multiple transport protocols. You can select which protocol to use via the quarkus.agentcard.protocol property:
Using JSONRPC (default):
mvn exec:java
Using GRPC:
mvn exec:java -Dquarkus.agentcard.protocol=GRPC
Using HTTP+JSON:
mvn exec:java -Dquarkus.agentcard.protocol=HTTP+JSON
Available protocols:
JSONRPC- Uses JSON-RPC for communication (default)GRPC- Uses gRPC for communicationHTTP+JSON- Uses HTTP with JSON payloads
Note: The protocol you select on the client must match the protocol configured on the server.
Enabling OpenTelemetry
To enable OpenTelemetry with Maven:
mvn exec:java -Dopentelemetry=true
You can combine protocol selection with OpenTelemetry:
mvn exec:java -Dquarkus.agentcard.protocol=HTTP+JSON -Dopentelemetry=true
Option 2: Using JBang
A JBang script is provided for running the client without Maven:
-
Make sure you have JBang installed. If not, follow the JBang installation guide.
-
Run the client using the JBang script:
jbang examples/helloworld/client/src/main/java/org/a2aproject/sdk/examples/helloworld/HelloWorldRunner.java
Transport Protocol Selection with JBang
Select the transport protocol using the same -Dquarkus.agentcard.protocol property:
Using JSONRPC (default):
jbang examples/helloworld/client/src/main/java/org/a2aproject/sdk/examples/helloworld/HelloWorldRunner.java
Using GRPC:
jbang examples/helloworld/client/src/main/java/org/a2aproject/sdk/examples/helloworld/HelloWorldRunner.java -Dquarkus.agentcard.protocol=GRPC
Using HTTP+JSON:
jbang examples/helloworld/client/src/main/java/org/a2aproject/sdk/examples/helloworld/HelloWorldRunner.java -Dquarkus.agentcard.protocol=HTTP+JSON
Enabling OpenTelemetry with JBang
To enable OpenTelemetry with JBang:
jbang examples/helloworld/client/src/main/java/org/a2aproject/sdk/examples/helloworld/HelloWorldRunner.java -Dopentelemetry=true
You can combine protocol selection with OpenTelemetry:
jbang examples/helloworld/client/src/main/java/org/a2aproject/sdk/examples/helloworld/HelloWorldRunner.java -Dquarkus.agentcard.protocol=GRPC -Dopentelemetry=true
What the Example Does
The Java client (HelloWorldClient.java) performs the following actions:
- Fetches the server's public agent card
- Fetches the server's extended agent card
- Creates a client using the extended agent card that connects to the Python server at
http://localhost:9999. - Sends a regular message asking "how much is 10 USD in INR?".
- Prints the server's response.
- Sends the same message as a streaming request.
- Prints each chunk of the server's streaming response as it arrives.
Enable OpenTelemetry (Optional)
The client includes support for distributed tracing with OpenTelemetry. To enable it:
Prerequisites
IMPORTANT: The client expects an OpenTelemetry collector to be ready and accepting traces. You have two options:
Option 1: Use the Java Server Example (Recommended)
Instead of the Python server, use the Java server example which has built-in OpenTelemetry support:
-
Start the Java server with OpenTelemetry enabled:
mvn quarkus:dev -Popentelemetry -pl examples/helloworld/server/ -Dquarkus.agentcard.protocol=HTTP+JSONThis will:
- Start the server at
http://localhost:9999 - Launch Grafana at
http://localhost:3001 - Start OTLP collectors on ports 5317 (gRPC) and 5318 (HTTP)
- Start the server at
-
Run the client with OpenTelemetry:
Using Maven (from
examples/helloworld/client):mvn exec:java -Dopentelemetry=trueWith specific protocol:
mvn exec:java -Dquarkus.agentcard.protocol=HTTP+JSON -Dopentelemetry=trueOr using JBang:
jbang examples/helloworld/client/src/main/java/org/a2aproject/sdk/examples/helloworld/HelloWorldRunner.java -Dopentelemetry=trueWith specific protocol:
jbang examples/helloworld/client/src/main/java/org/a2aproject/sdk/examples/helloworld/HelloWorldRunner.java -Dquarkus.agentcard.protocol=HTTP+JSON -Dopentelemetry=true -
View traces in Grafana:
- Open
http://localhost:3001(credentials: admin/admin) - Go to "Explore" โ select "Tempo" data source
- View distributed traces showing the full request flow from client to server
- Open
Option 2: Use External OpenTelemetry Collector
If you want to use the Python server with OpenTelemetry:
-
Start an OpenTelemetry collector on port 5317 (e.g., using Docker):
docker run -p 5317:4317 otel/opentelemetry-collector -
Run the Python server
-
Run the client with OpenTelemetry:
mvn exec:java -Dopentelemetry=trueOr with JBang:
jbang examples/helloworld/client/src/main/java/org/a2aproject/sdk/examples/helloworld/HelloWorldRunner.java -Dopentelemetry=trueWith specific protocol:
mvn exec:java -Dquarkus.agentcard.protocol=HTTP+JSON -Dopentelemetry=true
What Gets Traced
When OpenTelemetry is enabled, the client traces:
- Agent card fetching (public and extended)
- Message sending (blocking and streaming)
- Task operations (get, cancel, list)
- Push notification configuration operations
- Connection and transport layer operations
Client traces are automatically linked with server traces (when using the Java server), providing end-to-end visibility of the entire A2A protocol flow.
Configuration
The client is configured to send traces to http://localhost:5317 (OTLP gRPC endpoint). To use a different endpoint, modify the initOpenTelemetry() method in HelloWorldClient.java:
OtlpGrpcSpanExporter.builder()
.setEndpoint("http://your-collector:4317")
.build()
Notes
- Make sure the Python server is running before starting the Java client.
- The client will wait for 10 seconds to collect streaming responses before exiting.
- You can modify the message text or server URL in the
HelloWorldClient.javafile if needed.