Poja: Deploy Spring Boot applications to the cloud in minutes
You already trust conventions to wire your Spring Boot application. What happens when the same idea reaches the infrastructure?
In Spring Boot, where you place your main class determines what the application discovers, because @SpringBootApplication scans that package and everything below it.
The same principle runs deeper. Auto-configuration derives parts of the application from what’s on the classpath, while configuration itself follows conventions such as application.yaml.
Rails made the idea famous as convention over configuration. Put simply: if something can be derived, why declare it?
The convention is doing part of the wiring for you.
But that idea usually stops at the application boundary. Your application knows its own beans. AWS, on the other hand, still needs the queue, retries, routing, permissions, mappings, and the rest of the infrastructure around them.
Take an ordinary requirement: “I want to process this asynchronously.” It sounds like one sentence. It isn’t.
What the requirement asks for | What the infrastructure has to provide |
|---|---|
| An event that arrives reliably | A queue, plus a dead-letter queue for failures, with maxReceiveCount deciding when a failed message is moved |
| Retries that don’t fire too early or too often | A visibility timeout of at least six times the function timeout, and a maxReceiveCount of at least 5, per AWS’s own guidance |
| An event that reaches the right handler | An event bus and rules, where the pattern either matches or it doesn’t: one mismatch in the source field and the event goes nowhere |
| Permission to actually run | Roles, policies, event source mappings, and the configuration connecting everything together |
None of that changes what your application is trying to do. It’s just the infrastructure required to make that intent run. And that creates an awkward split: the developer describes the event in Java, while the infrastructure describes how that event moves through AWS.
So the real question isn’t “can this be built.” It’s: how much of that wiring should the developer have to declare manually?
With Poja, you don’t configure the async stack yourself. You follow a few conventions in your code, and Poja takes care of the infrastructure.
For asynchronous processing, you only need to:
PojaEvent and declare how long your handler may take
For example :
and :
That’s it. The convention is documented, and the dispatcher builds the service class name by concatenation. The link between your event and the code that consumes it is a string addition: Poja takes the event’s fully-qualified name, keeps the last segment, and appends Service to resolve the consumer. Poja then uses those two durations to calculate the SQS visibility timeout for your message.
The rest of the stack works by injection rather than by naming:
Mailer.BucketComponent, once file storage is enabled in your configuration.EventProducer.No AWS SDK to wire. No infrastructure configuration to maintain for the stack Poja provides.
Conventions make the infrastructure wiring simpler, and they have to be followed exactly. The event and its consumer are matched by name, so a naming mistake doesn’t show up at compile time, it shows up when the event is consumed.
The asynchronous path is derived from those conventions. Other parts of the stack are reached by injection, as shown above, while resources outside the infrastructure Poja provisions still require their own configuration.
Within that scope, the name you write is what Poja reads to derive the queue, routing, and visibility settings around your handler.
You write the convention. Poja wires the infrastructure.
Two classes and a git push are the whole experiment. Deploy one event, then look at what came out of it: the queue, the routing rule, and the visibility timeout Poja calculated from your two durations.
Subscribe now to keep reading and get access to the full archive.
Fill out the form below or contact us directly to start a conversation about your team’s deployment needs, infrastructure goals, and the solutions that best fit your business.