This article explains how to use the Arconia framework to enhance the developer experience with Spring Boot. This project is a recent initiative under active development. However, it caught my attention because of one feature I love in Quarkus and found missing in Spring Boot. I am referring to a solution called Dev Services, which is likely familiar to those of you who are familiar with Quarkus. Dev Services supports the automatic provisioning of unconfigured services in development and test mode. Similar to Quarkus, Arconia is based on Testcontainers and also uses Spring Boot Testcontainers support.
To learn how Spring Boot supports Testcontainers, read my article on the subject. If you’re interested in Quarkus Dev Services, consider this post, which focuses on automated testing support in Quarkus.
Prerequisites
To perform the exercise described in this article, you must have the following on your laptop:
- Docker / Podman
- Java 21+
- Maven 3.9+
Source Code
Feel free to use my source code if you’d like to try it out yourself. To do that, you must clone my sample GitHub repository. Then you should only follow my instructions.
Create Spring Boot Application
For this exercise, we will build a simple application that connects to a Postgres database and returns employee information through a REST interface. In addition to the core logic, we will also implement integration tests to verify endpoint functionality with a live database. Below is a list of required dependencies.
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-web
org.postgresql
postgresql
runtime
org.springframework.boot
spring-boot-starter-test
test
XML
Here’s the Employee domain object, which is stored in the employee table:
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private int organizationId;
private int departmentId;
private String name;
private int age;
private String position;
// GETTERS and SETTERS
}
Java
Here’s the Spring Data repository interface responsible for interacting with the Postgres database:
public interface EmployeeRepository extends CrudRepository<Employee, Integer> {
List<Employee> findByDepartmentId(int departmentId);
List<Employee> findByOrganizationId(int organizationId);
}
Java
This is the EmployeeController code with several REST endpoints that allow us to add and find employees in the database:
@RestController
@RequestMapping("/employees")
public class EmployeeController {
private static final Logger LOGGER = LoggerFactory
.getLogger(EmployeeController.class);
@Autowired
EmployeeRepository repository;
@PostMapping
public Employee add(@RequestBody Employee employee) {
LOGGER.info("Employee add...: {}", employee);
return repository.save(employee);
}
@GetMapping("/{id}")
public Employee findById(@PathVariable("id") Integer id) {
LOGGER.info("Employee find: id={}", id);
return repository.findById(id).get();
}
@GetMapping
public List<Employee> findAll() {
LOGGER.info("Employee find");
return (List<Employee>) repository.findAll();
}
@GetMapping("/department/{departmentId}")
public List<Employee> findByDepartment(@PathVariable("departmentId") int departmentId) {
LOGGER.info("Employee find: departmentId={}", departmentId);
return repository.findByDepartmentId(departmentId);
}
@GetMapping("/organization/{organizationId}")
public List<Employee> findByOrganization(@PathVariable("organizationId") int organizationId) {
LOGGER.info("Employee find: organizationId={}", organizationId);
return repository.findByOrganizationId(organizationId);
}
@GetMapping("/department-with-delay/{departmentId}")
public List<Employee> findByDepartmentWithDelay(@PathVariable("departmentId") int departmentId) throws InterruptedException {
LOGGER.info("Employee find with delay: departmentId={}", departmentId);
Thread.sleep(2000);
return repository.findByDepartmentId(departmentId);
}
}
Java
With the following configuration in the application.yml, we will initialize the database schema on the application or tests startup:
spring:
application:
name: sample-spring-web-with-db
jpa:
hibernate:
ddl-auto: create
properties:
hibernate:
show_sql: true
format_sql: true
YAML
Finally, here’s the @SpringBootTest that calls and verifies previously implemented REST endpoints:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class EmployeeControllerTests {
@Autowired
TestRestTemplate restTemplate;
@Test
@Order(1)
public void testAdd() {
Employee employee = new Employee();
employee.setName("John Doe");
employee.setAge(30);
employee.setPosition("Manager");
employee.setDepartmentId(1);
employee.setOrganizationId(1);
employee = restTemplate.postForObject("/employees", employee, Employee.class);
Assertions.assertNotNull(employee);
Assertions.assertNotNull(employee.getId());
}
@Test
@Order(2)
public void testFindById() {
Employee employee = restTemplate.getForObject("/employees/1", Employee.class);
Assertions.assertNotNull(employee);
Assertions.assertEquals(1, employee.getId());
}
@Test
@Order(3)
public void testFindAll() {
Employee[] employees = restTemplate.getForObject("/employees", Employee[].class);
Assertions.assertNotNull(employees);
Assertions.assertEquals(1, employees.length);
}
@Test
@Order(4)
public void testFindByDepartment() {
List<Employee> employees = restTemplate.getForObject("/employees/department/1", List.class);
Assertions.assertNotNull(employees);
Assertions.assertEquals(1, employees.size());
}
}
Java
Spring Boot Dev Services with Arconia
The Arconia framework offers multiple modules to support development services for the most popular databases and event brokers. To add support for the Postgres database, include the following dependency in your Maven pom.xml:
io.arconia
arconia-dev-services-postgresql
runtime
true
XML
We will add other Arconia modules later, so let’s include the BOM (Bill of Materials) with the latest version:
io.arconia
arconia-bom
0.18.2
pom
import
XML
And that’s all we needed to do. Now you can run the application in developer mode using the Maven command or through the arconia CLI. CLI is an add-on here, so for now, let’s stick with the standard mvn command.
mvn spring-boot:run
ShellSession
You can also run automated tests with the mvn test command or through the IDE’s graphical interface.
Spring Boot Observability with Arconia
Dev services are just one of the features offered by Arconia. In this article, I will present a simple scenario of integrating with the Grafana observability stack using OpenTelemetry. This time, we will include two dependencies. The first is a special Spring Boot starter provided by Arconia, which automatically configures OpenTelemetry, Micrometer, and Spring Boot Actuator for your app. The second dependency includes the dev services for a Grafana LGTM observability platform, which contains: Loki, Grafana, Prometheus, Tempo, and OpenTelemetry collector.
io.arconia
arconia-opentelemetry-spring-boot-starter
io.arconia
arconia-dev-services-lgtm
runtime
true
XML
In addition to the standard Arconia Observability settings, we will enable all built-in resource contributors. Below is the required configuration to add to the application settings in the application.yml file.
arconia:
otel:
resource:
contributors:
build:
enabled: true
host:
enabled: true
java:
enabled: true
os:
enabled: true
process:
enabled: true
YAML
That’s it. Let’s start our application in development mode once again.
mvn spring-boot:run
ShellSession
This time, Arconia starts one container more than before. I can access the Grafana dashboard at http://localhost:33383.

Let’s display all the containers running locally:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a6a097fb9ebe docker.io/testcontainers/ryuk:0.12.0 /bin/ryuk 2 minutes ago Up 2 minutes 0.0.0.0:42583->8080/tcp testcontainers-ryuk-dfdea2da-0bbd-43fa-9f50-3e9d966d877f
917d74a5a0ad docker.io/library/postgres:18.0-alpine postgres -c fsync... 2 minutes ago Up 2 minutes 0.0.0.0:38409->5432/tcp pensive_mcnulty
090a9434d1fd docker.io/grafana/otel-lgtm:0.11.16 /otel-lgtm/run-al... 2 minutes ago Up 2 minutes 0.0.0.0:33383->3000/tcp, 0.0.0.0:39501->3100/tcp, 0.0.0.0:32867->3200/tcp, 0.0.0.0:40389->4317/tcp, 0.0.0.0:46739->4318/tcp, 0.0.0.0:36915->9090/tcp vigorous_euler
ShellSession
And now for the best part. Right after launch, our application is fully integrated with the Grafana stack. For example, logs are sent to the Loki instance, from which we can view them in the Grafana UI.

We can also display a dashboard with Spring Boot metrics.

Right after launch, I sent several test POST and GET requests to the application endpoints. Information about this is available in Grafana Tempo.

We can also verify JVM statistics in a dedicated dashboard.

What more could you want? 🙂
Conclusion
Arconia is an exciting and promising project, which I will be watching closely in the future. It is a relatively new initiative that is still undergoing intensive development. Arconia already offers several practical solutions that significantly simplify working with the Spring Boot application. I have shown you how this framework works in a simple scenario: running and integrating our application with the Postgres database and the Grafana observability stack using the Micrometer framework.

