Skip to content

Commit 15d9656

Browse files
committed
adding code snippets
1 parent 53afbd0 commit 15d9656

File tree

2 files changed

+188
-5
lines changed

2 files changed

+188
-5
lines changed

_data/authors.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,4 +618,4 @@ maeste:
618618
emailhash: "c97a0cf6b2f42295f8bfa8670ada8f63"
619619
job_title: "Senior Engineering Manager"
620620
twitter: "maeste"
621-
bio: "Senior Engineering Manager at Red Hat / IBM"
621+
bio: "Senior Engineering Manager at Red Hat / IBM with an old passion for Open Source and more recent one for AI Engineering."

_posts/2025-06-27-a2a-project-lanunches-java-sdk.adoc

Lines changed: 187 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ teams’ contribution.
2020

2121
=== A New Era Under Linux Foundation Stewardship
2222

23-
The [A2A](https://a2aproject.github.io/A2A/latest/specification) protocol’s transition to the Linux Foundation represents more
23+
The https://a2aproject.github.io/A2A/latest/specification[A2A] protocol’s transition to the Linux Foundation represents more
2424
than just a change of governance: it’s a commitment to vendor-neutral,
2525
community-driven innovation. Similar how WildFly and Quarkus both recently joined CommonHaus fouundation. This ensures A2A as a critical interoperability
2626
standard remains open and accessible to all. With more than 100
@@ -49,10 +49,193 @@ infrastructure +
4949
Python, JavaScript, or any A2A-compatible language +
5050
well-tested enterprise capabilities (including observability, security...)
5151

52-
Want to see this interoperability in action? Explore our
52+
And you know what? Writing agents in Java is now as easy as writing
53+
54+
==== 1. A class that creates an A2A Agent Card
55+
56+
[source,java]
57+
----
58+
import io.a2a.spec.AgentCapabilities;
59+
import io.a2a.spec.AgentCard;
60+
import io.a2a.spec.AgentSkill;
61+
import io.a2a.spec.PublicAgentCard;
62+
...
63+
64+
@ApplicationScoped
65+
public class WeatherAgentCardProducer {
66+
67+
@Produces
68+
@PublicAgentCard
69+
public AgentCard agentCard() {
70+
return new AgentCard.Builder()
71+
.name("Weather Agent")
72+
.description("Helps with weather")
73+
.url("http://localhost:10001")
74+
.version("1.0.0")
75+
.capabilities(new AgentCapabilities.Builder()
76+
.streaming(true)
77+
.pushNotifications(false)
78+
.stateTransitionHistory(false)
79+
.build())
80+
.defaultInputModes(Collections.singletonList("text"))
81+
.defaultOutputModes(Collections.singletonList("text"))
82+
.skills(Collections.singletonList(new AgentSkill.Builder()
83+
.id("weather_search")
84+
.name("Search weather")
85+
.description("Helps with weather in city, or states")
86+
.tags(Collections.singletonList("weather"))
87+
.examples(List.of("weather in LA, CA"))
88+
.build()))
89+
.build();
90+
}
91+
}
92+
----
93+
94+
==== 2. A class that creates an A2A Agent Executor
95+
96+
[source,java]
97+
----
98+
import io.a2a.server.agentexecution.AgentExecutor;
99+
import io.a2a.server.agentexecution.RequestContext;
100+
import io.a2a.server.events.EventQueue;
101+
import io.a2a.server.tasks.TaskUpdater;
102+
import io.a2a.spec.JSONRPCError;
103+
import io.a2a.spec.Message;
104+
import io.a2a.spec.Part;
105+
import io.a2a.spec.Task;
106+
import io.a2a.spec.TaskNotCancelableError;
107+
import io.a2a.spec.TaskState;
108+
import io.a2a.spec.TextPart;
109+
...
110+
111+
@ApplicationScoped
112+
public class WeatherAgentExecutorProducer {
113+
114+
@Inject
115+
WeatherAgent weatherAgent;
116+
117+
@Produces
118+
public AgentExecutor agentExecutor() {
119+
return new WeatherAgentExecutor(weatherAgent);
120+
}
121+
122+
private static class WeatherAgentExecutor implements AgentExecutor {
123+
124+
private final WeatherAgent weatherAgent;
125+
126+
public WeatherAgentExecutor(WeatherAgent weatherAgent) {
127+
this.weatherAgent = weatherAgent;
128+
}
129+
130+
@Override
131+
public void execute(RequestContext context, EventQueue eventQueue) throws JSONRPCError {
132+
TaskUpdater updater = new TaskUpdater(context, eventQueue);
133+
134+
// mark the task as submitted and start working on it
135+
if (context.getTask() == null) {
136+
updater.submit();
137+
}
138+
updater.startWork();
139+
140+
// extract the text from the message
141+
String userMessage = extractTextFromMessage(context.getMessage());
142+
143+
// call the weather agent with the user's message
144+
String response = weatherAgent.chat(userMessage);
145+
146+
// create the response part
147+
TextPart responsePart = new TextPart(response, null);
148+
List<Part<?>> parts = List.of(responsePart);
149+
150+
// add the response as an artifact and complete the task
151+
updater.addArtifact(parts, null, null, null);
152+
updater.complete();
153+
}
154+
155+
@Override
156+
public void cancel(RequestContext context, EventQueue eventQueue) throws JSONRPCError {
157+
Task task = context.getTask();
158+
159+
if (task.getStatus().state() == TaskState.CANCELED) {
160+
// task already cancelled
161+
throw new TaskNotCancelableError();
162+
}
163+
164+
if (task.getStatus().state() == TaskState.COMPLETED) {
165+
// task already completed
166+
throw new TaskNotCancelableError();
167+
}
168+
169+
// cancel the task
170+
TaskUpdater updater = new TaskUpdater(context, eventQueue);
171+
updater.cancel();
172+
}
173+
174+
private String extractTextFromMessage(Message message) {
175+
StringBuilder textBuilder = new StringBuilder();
176+
if (message.getParts() != null) {
177+
for (Part part : message.getParts()) {
178+
if (part instanceof TextPart textPart) {
179+
textBuilder.append(textPart.getText());
180+
}
181+
}
182+
}
183+
return textBuilder.toString();
184+
}
185+
}
186+
}
187+
----
188+
189+
Pretty straightforward, right? The SDK provides all the necessary
190+
components to create agent cards, handle agent execution, and manage
191+
communication between agents.
192+
193+
And when it comes to client-side development, it's even easier. The SDK
194+
includes a simple HTTP client that allows you to interact with A2A agents
195+
using the A2A protocol. This client abstracts away the complexities of
196+
the protocol, making it easy to send messages, receive responses, and
197+
manage agent interactions. Creating an A2A client in Java is as simple as:
198+
199+
==== 1. Create an A2A client
200+
201+
[source,java]
202+
----
203+
// Create an A2AClient (the URL specified is the server agent's URL, be sure to replace it with the actual URL of the A2A server you want to connect to)
204+
A2AClient client = new A2AClient("http://localhost:1234");
205+
----
206+
207+
==== 2. Send a message to the A2A server agent
208+
209+
[source,java]
210+
----
211+
// Send a text message to the A2A server agent
212+
Message message = A2A.toUserMessage("tell me a joke"); // the message ID will be automatically generated for you
213+
MessageSendParams params = new MessageSendParams.Builder()
214+
.message(message)
215+
.build();
216+
SendMessageResponse response = client.sendMessage(params);
217+
----
218+
219+
Note that `+A2A#toUserMessage+` will automatically generate a message ID
220+
for you when creating the `+Message+` if you don’t specify it. You can
221+
also explicitly specify a message ID like this:
222+
223+
[source,java]
224+
----
225+
Message message = A2A.toUserMessage("tell me a joke", "message-1234"); // messageId is message-1234
226+
----
227+
228+
And the SDK also provides a convenient way to handle task management,
229+
allowing you to create, get gurrent state, and cancel tasks with ease. This is
230+
especially useful for managing long-running operations or coordinating
231+
complex workflows between multiple agents. You can find more details
232+
about task management and many other features in the *https://github.com/a2aproject/a2a-java[A2A Java SDK]* repository's.
233+
234+
You just want more code? Are you interested to see interoperability in action? Explore our
53235
https://github.com/a2aproject/a2a-samples/tree/main/samples/multi_language/python_and_java_multiagent[multi-language
54236
sample implementation&#44;] which demonstrates how Python and Java
55-
agents collaborate seamlessly.
237+
agents collaborate seamlessly. See this picture for a bird-eye overview,
238+
and checkout the code for more insights
56239

57240
image::A2A_multi_agent.png[scaledwidth=100%]
58241

@@ -61,7 +244,7 @@ image::A2A_multi_agent.png[scaledwidth=100%]
61244
And if you need your agent to be reactive, don't worry about the dependencies you are adding, because
62245
the Java SDK leverages *mutiny-zero* as its reactive foundation, a
63246
decision that reflects our commitment to framework-agnostic excellence.
64-
[Mutiny Zero](https://smallrye.io/smallrye-mutiny-zero/latest/) is a minimal API for creating reactive streams-compliant
247+
https://smallrye.io/smallrye-mutiny-zero/latest/[Mutiny Zero] is a minimal API for creating reactive streams-compliant
65248
publishers that weighs less than 50K and have **zero** external dependencies
66249
beyond the Reactive Streams API. This architecture delivers several
67250
compelling advantages:

0 commit comments

Comments
 (0)