Microservice Overview
Juneau microservices are self-contained, deployable REST servers built on top of the Juneau REST
server framework. A microservice packages your REST resources, configuration, and an embedded HTTP container
into a single executable jar (or WAR) that you can start with a plain java -jar command.
The microservice layer builds on top of the full Juneau stack:
Deployment Targets
Juneau provides three independently-releasable deployment adapters. All three share the same
Microservice + @Configuration + @Bean Servlet programming model and the same lifecycle contracts.
| Module | When to use |
|---|---|
| juneau-microservice-jetty | Default choice for standalone runnable jars. Ships a zero-config JettyMicroservice.run(args, servlet) one-liner and a classpath-driven jetty.xml knob for advanced connector tuning. |
| juneau-microservice-tomcat | Drop-in alternative when your organisation standardises on Tomcat, or when you want to share [Tomcat] config between an embedded dev launcher and a full Tomcat deployment. |
| juneau-rest-server-springboot | Integration point for Spring Boot applications. REST resources extend BasicSpringRestServlet / BasicSpringRestServletGroup so Spring @Autowired injection and @Bean resolution flow through the Spring application context instead of the Juneau bean store. |
All three adapters depend on juneau-microservice for the core lifecycle engine and on juneau-rest-server for the REST framework itself.
Lifecycle
Every Juneau microservice follows a builder → configure → start → join/stop lifecycle.
All methods on Microservice return this, making it easy to chain the whole bootstrap in one
fluent expression.
Microservice API Classes
The core lifecycle engine lives in a small, self-contained set of packages and classes:
By itself the core API provides only the bootstrap machinery — an executable-jar lifecycle, config
resolution, command-line-argument and manifest access, an interactive console, and the inject bean
store. The embedded HTTP server is contributed by a deployment adapter
(Jetty, Tomcat, or
Spring Boot) registered as a @Configuration class.
Hello World (Jetty)
The following is the smallest complete Juneau microservice: a single REST resource mounted on an embedded Jetty server with automatic JSON/XML/HTML content negotiation.
Add the dependency, with juneau-bom imported as on Install Juneau:
<dependency>
<groupId>org.apache.juneau</groupId>
<artifactId>juneau-microservice-jetty-bundle</artifactId>
<type>pom</type>
</dependency>
Define a REST resource:
import org.apache.juneau.http.*;
import org.apache.juneau.rest.server.*;
import org.apache.juneau.rest.server.servlet.*;
@Rest(
path = "/hello",
title = "Hello World"
)
public class HelloResource extends BasicRestServlet {
@RestGet(path = "/*", summary = "Returns a greeting.")
public String sayHello() {
return "Hello, World!";
}
}
Boot it from main:
import org.apache.juneau.microservice.jetty.*;
public class App {
public static void main(String[] args) throws Exception {
JettyMicroservice.run(args, new HelloResource(), false).join();
}
}
JettyMicroservice.run(args, servlet, false) is a convenience facade that wires JettyConfiguration into
the Microservice builder, registers the servlet at the path in its @Rest annotation, and starts on port
10000 (or as configured in juneau.cfg); join() blocks until the server stops. The false turns the
interactive console off, as on Your First REST App; run(args, servlet)
turns it on. Point a browser at http://localhost:10000/hello — the default HTML view renders automatically.
For the Tomcat or Spring Boot equivalents, see the module-specific pages listed in the Deployment Targets section above.
Ports used in these docs
| Port | When |
|---|---|
| 10000 | Jetty microservice (Getting Started, MCP quickstart, starters, Petstore Jetty). Set by jetty.xml $S{availablePort,10000}. The Spring Boot starter also uses 10000 (server.port), as does the juneau-examples-mcp Jetty ExampleServer (DEFAULT_PORT = 10000). |
| 8080 | Spring Boot's default (Spring guides, the MCP recipe snippets, the juneau-examples-mcp Spring example) and Tomcat. |
| 5000 | Petstore Spring Boot (server.port=${PORT:5000}). |
Configuration Files
Every microservice reads its runtime settings from an INI-style juneau.cfg file that is resolved
from the classpath or working directory at startup. Key sections used by the built-in modules:
[Microservice]
# Name and version shown in the console banner.
name = MyApp
version = 1.0
[Jetty]
# Comma-separated list of candidate ports; first available wins. 0 = random.
port = 8080, 0
[Logging]
# Root logging level (java.util.logging).
level = WARNING
# Log file relative to the working directory.
logFile = logs/microservice.%g.log
The configuration is exposed as a
Config
object through Microservice.getConfig() and is also registered in the
bean store so @Bean factory methods can inject it directly.
Hot-reload
Config supports file-watch hot-reload out of the box. When the underlying juneau.cfg file
changes on disk, listeners registered via
Config.addListener(…)
are notified with the full set of changed entries. The microservice uses this to propagate logging
level changes and port-list updates without a restart.
You can register your own listener from a @Configuration class:
import org.apache.juneau.commons.inject.*;
import org.apache.juneau.config.event.*;
import org.apache.juneau.microservice.*;
@Configuration
public class AppConfig {
@Bean
MicroserviceListener configWatcher() {
return new BasicMicroserviceListener() {
@Override
public void onConfigChange(Microservice ms, ConfigEvents events) {
System.out.println("Config changed: " + events);
}
};
}
}
The onConfigChange(Microservice, ConfigEvents) callback fires on the calling thread of the
file-store watcher, not the request thread, so keep it non-blocking. The ConfigEvents argument
carries the full set of changed entries — see Listeners
for reacting to specific sections.
Built-in Management Resources
The Jetty and Tomcat launchers expose several built-in REST endpoints under the root path when
management mixins are enabled. These are opt-in: add the appropriate mixin to your root
@Rest resource.
| Endpoint | Mixin / feature | Description |
|---|---|---|
GET /healthz | Health Probes | Aggregated health/liveness check. Returns 200 OK or 503 Service Unavailable. |
GET /readyz | Health Probes | Readiness probe, used by Kubernetes load-balancer pre-stop hooks. |
GET /livez | Health Probes | Liveness probe for pod restart decisions. |
GET /actuator | Management Surface | Actuator-style endpoint listing all available management sub-paths. |
GET /api | Auto-generated via Swagger / OpenAPI | Swagger 2.x JSON schema; OPTIONS on any resource returns an inline schema. |
GET /stats | Execution Statistics | Per-operation call counts, error rates, and latency percentiles. |
The management surface is implemented via the standard Juneau mixin pack mechanism — there are no special microservice APIs. The same mixins work in a plain servlet container too.
Bean Store and Inject Bootstrap
Microservice owns an internal
WritableBeanStore
populated from every @Configuration class registered on the builder. This makes it easy for
companion modules — such as JettyConfiguration and TomcatConfiguration — to contribute lifecycle
components and for user code to wire in application services without subclassing.
@Configuration
public class AppConfig {
@Bean
Servlet rootResources() { return new RootResources(); } // auto-mounted by JettyConfiguration
@Bean
MyService myService() { return new MyService(); } // available to other @Bean methods
}
public class App {
public static void main(String[] args) throws Exception {
Microservice.create()
.args(args)
.configurations(JettyConfiguration.class, AppConfig.class)
.build()
.start()
.startConsole()
.join();
}
}
JettyConfiguration walks the bean store at startup, finds every @Bean whose declared return type
is Servlet and whose runtime class carries @Rest, and mounts it at the path declared in
@Rest(path = "..."). TomcatConfiguration follows an identical contract.
See Inject-Aware Microservice for a complete reference on
resolution priority, @PostConstruct / @PreDestroy callbacks, and external bean store integration.
Starter Projects
Apache Juneau provides three minimal clone-and-go starter projects — one per deployment target —
that demonstrate a HelloResource, content negotiation, a Swagger/OPTIONS page, @Path/@Query
binding, a YAML config file, and a MockRestClient test. Each is a true-orphan branch of
apache/juneau:
git clone -b microservice-jetty-starter --single-branch https://github.com/apache/juneau.git my-app
git clone -b microservice-springboot-starter --single-branch https://github.com/apache/juneau.git my-app
git clone -b microservice-tomcat-starter --single-branch https://github.com/apache/juneau.git my-app
See Starter Projects for run commands, layout, and Docker notes.
See Also
- juneau-microservice — core microservice module (lifecycle engine, config, console)
- juneau-microservice-jetty — embedded Jetty launcher
- juneau-microservice-tomcat — embedded Tomcat launcher
- juneau-rest-server-springboot — Spring Boot integration
- REST Server — the underlying REST server API
- Config Files — full configuration file reference
- Microservice with Jetty — adds the Jetty launcher on top of the core module