|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: 'Quarkus and WildFly teams from Red Hat collaborating with Google on launch of Agent2Agent Java SDK' |
| 4 | +date: 2025-06-27 |
| 5 | +tags: release |
| 6 | +synopsis: 'We’re thrilled to announce the launch of the Agent2Agent (A2A) Java SDK, contributed by the WildFly and the Quarkus communities' |
| 7 | +author: maeste |
| 8 | +--- |
| 9 | +:imagesdir: /assets/images/posts/a2a-announce |
| 10 | + |
| 11 | +The agent revolution just took a massive leap forward! Following the |
| 12 | +recent landmark https://developers.googleblog.com/en/google-cloud-donates-a2a-to-linux-foundation/[announcement] that Google has donated the Agent2Agent |
| 13 | +(A2A) protocol to the Linux Foundation, we’re thrilled to announce the |
| 14 | +launch of the https://github.com/a2aproject/a2a-java[A2A Java SDK], created by the WildFly and Quarkus teams in close collaboration, and now contributed to the official A2A project. |
| 15 | + |
| 16 | + |
| 17 | +== A New Era Under Linux Foundation Stewardship |
| 18 | + |
| 19 | +The https://a2aproject.github.io/A2A/latest/specification[A2A] protocol’s transition to the Linux Foundation represents more |
| 20 | +than just a change of governance: it’s a commitment to vendor-neutral, |
| 21 | +community-driven innovation. Similar how WildFly and Quarkus both recently joined the CommonHaus foundation. This ensures that A2A, as a critical interoperability |
| 22 | +standard, remains open and accessible to all. With more than 100 |
| 23 | +companies now supporting the protocol, we’re witnessing the formation of |
| 24 | +what industry leaders are calling "`an open, interoperable Internet of |
| 25 | +Agents.`" |
| 26 | +With the A2A Java SDK now part of this movement, enterprise developers can participate in this open agent ecosystem from day one. |
| 27 | + |
| 28 | +== Why Java SDK Matters |
| 29 | + |
| 30 | +Here’s where things get exciting from a technical perspective: *true |
| 31 | +polyglot agent ecosystems*. |
| 32 | + |
| 33 | +The agent landscape has been fragmented, with Python dominating AI/ML |
| 34 | +workflows, JavaScript powering web-based agents, and Java serving as the |
| 35 | +backbone of enterprise backend systems. Siloed development across language ecosystems has held back the true potential of agentic applications. |
| 36 | + |
| 37 | + |
| 38 | +Our Java SDK shatters these barriers by implementing the A2A protocol |
| 39 | +specification natively in Java, enabling: |
| 40 | + |
| 41 | +* *Enterprise-grade agent integration* with existing Java |
| 42 | +infrastructure + |
| 43 | +* *Seamless interoperability* between Java agents and those written in |
| 44 | +Python, JavaScript, or any A2A-compatible language with |
| 45 | +well-tested enterprise capabilities (including observability, security...) |
| 46 | + |
| 47 | +And you know what? Writing agents in Java is now as easy as writing |
| 48 | + |
| 49 | +=== 1. A class that creates an A2A Agent Card |
| 50 | + |
| 51 | +[source,java] |
| 52 | +---- |
| 53 | +import io.a2a.spec.AgentCapabilities; |
| 54 | +import io.a2a.spec.AgentCard; |
| 55 | +import io.a2a.spec.AgentSkill; |
| 56 | +import io.a2a.spec.PublicAgentCard; |
| 57 | +... |
| 58 | +
|
| 59 | +@ApplicationScoped |
| 60 | +public class WeatherAgentCardProducer { |
| 61 | + |
| 62 | + @Produces |
| 63 | + @PublicAgentCard |
| 64 | + public AgentCard agentCard() { |
| 65 | + return new AgentCard.Builder() |
| 66 | + .name("Weather Agent") |
| 67 | + .description("Helps with weather") |
| 68 | + .url("http://localhost:10001") |
| 69 | + .version("1.0.0") |
| 70 | + .capabilities(new AgentCapabilities.Builder() |
| 71 | + .streaming(true) |
| 72 | + .pushNotifications(false) |
| 73 | + .stateTransitionHistory(false) |
| 74 | + .build()) |
| 75 | + .defaultInputModes(Collections.singletonList("text")) |
| 76 | + .defaultOutputModes(Collections.singletonList("text")) |
| 77 | + .skills(Collections.singletonList(new AgentSkill.Builder() |
| 78 | + .id("weather_search") |
| 79 | + .name("Search weather") |
| 80 | + .description("Helps with weather in city, or states") |
| 81 | + .tags(Collections.singletonList("weather")) |
| 82 | + .examples(List.of("weather in LA, CA")) |
| 83 | + .build())) |
| 84 | + .build(); |
| 85 | + } |
| 86 | +} |
| 87 | +---- |
| 88 | + |
| 89 | +=== 2. A class that creates an A2A Agent Executor |
| 90 | + |
| 91 | +[source,java] |
| 92 | +---- |
| 93 | +import io.a2a.server.agentexecution.AgentExecutor; |
| 94 | +import io.a2a.server.agentexecution.RequestContext; |
| 95 | +import io.a2a.server.events.EventQueue; |
| 96 | +import io.a2a.server.tasks.TaskUpdater; |
| 97 | +import io.a2a.spec.JSONRPCError; |
| 98 | +import io.a2a.spec.Message; |
| 99 | +import io.a2a.spec.Part; |
| 100 | +import io.a2a.spec.Task; |
| 101 | +import io.a2a.spec.TaskNotCancelableError; |
| 102 | +import io.a2a.spec.TaskState; |
| 103 | +import io.a2a.spec.TextPart; |
| 104 | +... |
| 105 | +
|
| 106 | +@ApplicationScoped |
| 107 | +public class WeatherAgentExecutorProducer { |
| 108 | +
|
| 109 | + @Inject |
| 110 | + WeatherAgent weatherAgent; |
| 111 | +
|
| 112 | + @Produces |
| 113 | + public AgentExecutor agentExecutor() { |
| 114 | + return new WeatherAgentExecutor(weatherAgent); |
| 115 | + } |
| 116 | +
|
| 117 | + private static class WeatherAgentExecutor implements AgentExecutor { |
| 118 | +
|
| 119 | + private final WeatherAgent weatherAgent; |
| 120 | +
|
| 121 | + public WeatherAgentExecutor(WeatherAgent weatherAgent) { |
| 122 | + this.weatherAgent = weatherAgent; |
| 123 | + } |
| 124 | +
|
| 125 | + @Override |
| 126 | + public void execute(RequestContext context, EventQueue eventQueue) throws JSONRPCError { |
| 127 | + TaskUpdater updater = new TaskUpdater(context, eventQueue); |
| 128 | +
|
| 129 | + // mark the task as submitted and start working on it |
| 130 | + if (context.getTask() == null) { |
| 131 | + updater.submit(); |
| 132 | + } |
| 133 | + updater.startWork(); |
| 134 | +
|
| 135 | + // extract the text from the message |
| 136 | + String userMessage = extractTextFromMessage(context.getMessage()); |
| 137 | +
|
| 138 | + // call the weather agent with the user's message |
| 139 | + String response = weatherAgent.chat(userMessage); |
| 140 | +
|
| 141 | + // create the response part |
| 142 | + TextPart responsePart = new TextPart(response, null); |
| 143 | + List<Part<?>> parts = List.of(responsePart); |
| 144 | +
|
| 145 | + // add the response as an artifact and complete the task |
| 146 | + updater.addArtifact(parts, null, null, null); |
| 147 | + updater.complete(); |
| 148 | + } |
| 149 | +
|
| 150 | + @Override |
| 151 | + public void cancel(RequestContext context, EventQueue eventQueue) throws JSONRPCError { |
| 152 | + Task task = context.getTask(); |
| 153 | +
|
| 154 | + if (task.getStatus().state() == TaskState.CANCELED) { |
| 155 | + // task already cancelled |
| 156 | + throw new TaskNotCancelableError(); |
| 157 | + } |
| 158 | +
|
| 159 | + if (task.getStatus().state() == TaskState.COMPLETED) { |
| 160 | + // task already completed |
| 161 | + throw new TaskNotCancelableError(); |
| 162 | + } |
| 163 | +
|
| 164 | + // cancel the task |
| 165 | + TaskUpdater updater = new TaskUpdater(context, eventQueue); |
| 166 | + updater.cancel(); |
| 167 | + } |
| 168 | +
|
| 169 | + private String extractTextFromMessage(Message message) { |
| 170 | + StringBuilder textBuilder = new StringBuilder(); |
| 171 | + if (message.getParts() != null) { |
| 172 | + for (Part part : message.getParts()) { |
| 173 | + if (part instanceof TextPart textPart) { |
| 174 | + textBuilder.append(textPart.getText()); |
| 175 | + } |
| 176 | + } |
| 177 | + } |
| 178 | + return textBuilder.toString(); |
| 179 | + } |
| 180 | + } |
| 181 | +} |
| 182 | +---- |
| 183 | + |
| 184 | +Pretty straightforward, right? The SDK provides all the necessary |
| 185 | +components to create agent cards, handle agent execution, and manage |
| 186 | +communication between agents. |
| 187 | + |
| 188 | +Note: In future some of this boiler plate code we expect will be simplified by Quarkus and other frameworks using the A2A Java SDK. |
| 189 | + |
| 190 | +And when it comes to client-side development, it's even easier. The SDK |
| 191 | +includes a simple A2A client that allows you to interact with A2A agents |
| 192 | +using the A2A protocol. This client abstracts away the complexities of |
| 193 | +the protocol, making it easy to send messages, receive responses, and |
| 194 | +manage agent interactions. Creating an A2A client in Java is as simple as: |
| 195 | + |
| 196 | +=== 1. Create an A2A client |
| 197 | + |
| 198 | +[source,java] |
| 199 | +---- |
| 200 | +// 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) |
| 201 | +A2AClient client = new A2AClient("http://localhost:1234"); |
| 202 | +---- |
| 203 | + |
| 204 | +=== 2. Send a message to the A2A server agent |
| 205 | + |
| 206 | +[source,java] |
| 207 | +---- |
| 208 | +// Send a text message to the A2A server agent |
| 209 | +Message message = A2A.toUserMessage("tell me a joke"); // the message ID will be automatically generated for you |
| 210 | +MessageSendParams params = new MessageSendParams.Builder() |
| 211 | + .message(message) |
| 212 | + .build(); |
| 213 | +SendMessageResponse response = client.sendMessage(params); |
| 214 | +---- |
| 215 | + |
| 216 | +Note that `+A2A#toUserMessage+` will automatically generate a message ID |
| 217 | +for you when creating the `+Message+` if you don’t specify it. You can |
| 218 | +also explicitly specify a message ID like this: |
| 219 | + |
| 220 | +[source,java] |
| 221 | +---- |
| 222 | +Message message = A2A.toUserMessage("tell me a joke", "message-1234"); // messageId is message-1234 |
| 223 | +---- |
| 224 | + |
| 225 | +And the SDK also provides a convenient way to handle task management, |
| 226 | +allowing you to create, get the current state, and cancel tasks with ease. This is |
| 227 | +especially useful for managing long-running operations or coordinating |
| 228 | +complex workflows between multiple agents. You can find more details |
| 229 | +about task management and many other features in the *https://github.com/a2aproject/a2a-java[A2A Java SDK]* repository's. |
| 230 | + |
| 231 | +You just want more code? Are you interested to see interoperability in action? Explore our |
| 232 | +https://github.com/a2aproject/a2a-samples/tree/main/samples/multi_language/python_and_java_multiagent[multi-language |
| 233 | +sample implementation,] which demonstrates how Python and Java |
| 234 | +agents collaborate seamlessly. See this picture for a bird-eye overview, |
| 235 | +and checkout the code for more insights |
| 236 | + |
| 237 | +image::a2a-agentic.png[scaledwidth=100%] |
| 238 | + |
| 239 | +== Technical Excellence: The Mutiny-Zero Advantage |
| 240 | + |
| 241 | +And if you need your agent to be reactive, don't worry about the dependencies you are adding, because |
| 242 | +the Java SDK leverages *mutiny-zero* as its reactive foundation, a |
| 243 | +decision that reflects our commitment to framework-agnostic excellence. |
| 244 | +https://smallrye.io/smallrye-mutiny-zero/latest/[Mutiny Zero] is a minimal API for creating reactive streams-compliant |
| 245 | +publishers that weighs less than 50K and have **zero** external dependencies |
| 246 | +beyond the Reactive Streams API. This architecture delivers several |
| 247 | +compelling advantages: |
| 248 | + |
| 249 | +* *No Vendor Lock-in*: No specific technology commitments for your |
| 250 | +agents. + |
| 251 | +* *Lightweight Performance*: Faster startups, reduced resource |
| 252 | +consumption. + |
| 253 | +* *Maximum Compatibility*: Seamless integration with existing Java |
| 254 | +reactive ecosystems. + |
| 255 | +* *Future-Proof Design*: Ready for Java’s modern Flow APIs, backward |
| 256 | +compatible. |
| 257 | + |
| 258 | +This reactive foundation ensures your Java agents can handle |
| 259 | +high-throughput, low-latency agent-to-agent communications while |
| 260 | +remaining lightweight and composable. |
| 261 | + |
| 262 | +== Community-Driven Innovation |
| 263 | + |
| 264 | +What started as an external contribution has now become an official part |
| 265 | +of the A2A project repository, showcasing how the ecosystem can rapidly |
| 266 | +evolve through diverse contributions. This is precisely the kind of |
| 267 | +collaborative development that will accelerate A2A adoption and |
| 268 | +innovation. |
| 269 | + |
| 270 | +Ready to dive in? Here’s your roadmap: |
| 271 | + |
| 272 | +[arabic] |
| 273 | +. *Explore the SDK*: Visit |
| 274 | +https://github.com/a2aproject/a2a-java[github.com/a2aproject/a2a-java] |
| 275 | +to examine the implementation + |
| 276 | +. *Study Real Examples*: Check out the |
| 277 | +https://github.com/a2aproject/a2a-samples/tree/main/samples/multi_language/python_and_java_multiagent[multi-language |
| 278 | +samples] to see interoperability in action + |
| 279 | +. *Join the Community*: Connect with fellow developers in the A2A |
| 280 | +ecosystem + |
| 281 | +. *Start Building*: Begin prototyping your first multi-language agent |
| 282 | +team |
| 283 | + |
| 284 | +== The Bigger Picture: Collaborative Intelligence |
| 285 | + |
| 286 | +The A2A protocol aims to break down the silos that currently limit the |
| 287 | +potential of AI infuse applications by providing a common language for |
| 288 | +AI agents to discover each other’s capabilities, securely exchange |
| 289 | +information, and coordinate complex tasks. |
| 290 | + |
| 291 | +With Java now joining Python and JavaScript in the A2A ecosystem, we’re |
| 292 | +building towards a future where intelligence is truly collaborative, |
| 293 | +where the most sophisticated AI systems are assembled from specialized |
| 294 | +agents, each optimized for specific tasks but unified through |
| 295 | +standardized communication protocols. |
| 296 | + |
| 297 | +This Java SDK launch is just the beginning. The A2A project under Linux |
| 298 | +Foundation stewardship is positioned for rapid expansion, with |
| 299 | +additional language implementations, enhanced security features, and |
| 300 | +enterprise-grade tooling on the horizon. |
| 301 | + |
| 302 | +*Your contributions matter*. Whether you’re fixing bugs, adding |
| 303 | +features, creating examples, or building integrations with other frameworks — every commithelps build this collaborative future. |
| 304 | +The agent revolution is here, and with the A2A Java SDK, the entire Java |
| 305 | +ecosystem can participate. Let’s build something amazing together! 🚀 |
0 commit comments