java

How to Integrate Spring Boot with Eclipse MicroProfile for Enterprise Microservices

Learn how to integrate Spring Boot with Eclipse MicroProfile using health checks, metrics, JWT, and fault tolerance for smoother microservices.

How to Integrate Spring Boot with Eclipse MicroProfile for Enterprise Microservices

I’ve been building enterprise Java applications for over a decade, and one question keeps coming up from teams I work with: “We love Spring Boot, but our new microservices need to talk to services running on Eclipse MicroProfile. Can we make them play nicely?” That question is the reason I started tinkering with the combination of Spring Boot and Eclipse MicroProfile. The two ecosystems often feel like rival camps, but in practice, they can complement each other beautifully—especially when you need standardised behaviour across a polyglot cloud-native environment.

Spring Boot is my daily driver. It gives me auto‑configuration, embedded servers, and a huge library of starters. Eclipse MicroProfile, on the other hand, is a specification built specifically for microservices. It standardises things like fault tolerance, health checks, metrics, and JWT propagation. A MicroProfile runtime (such as Open Liberty or Payara) will honour those specifications out of the box. But what if your team is tied to Spring Boot? Do you have to abandon all that MicroProfile consistency? Not at all.

The trick is to think of MicroProfile as a set of contracts, not a runtime. You can implement those contracts inside a Spring Boot application using compatible libraries. This gives you the best of both worlds: Spring Boot’s developer convenience and MicroProfile’s vendor‑neutral specifications. I’ve seen this approach allow large organisations to gradually migrate services from one ecosystem to another without breaking inter‑service communication.

Let’s start with one of the most practical specifications: MicroProfile Fault Tolerance. It defines annotations like @Retry, @CircuitBreaker, @Bulkhead, and @Timeout. In a Spring Boot world, you might reach for Resilience4j. Resilience4j is a lightweight library that provides almost identical annotations. Here’s a short example of how I use Resilience4j in a Spring Boot service to simulate MicroProfile’s @Retry:

import io.github.resilience4j.retry.annotation.Retry;

@Service
public class PaymentService {

    @Retry(name = "paymentRetry", fallbackMethod = "fallbackRetry")
    public String processPayment(String orderId) {
        // logic that may fail transiently
        return restTemplate.postForObject("https://payment-gateway/charge", orderId, String.class);
    }

    private String fallbackRetry(String orderId, Exception ex) {
        return "Payment deferred for " + orderId;
    }
}

Notice the @Retry annotation. The configuration for paymentRetry lives in application.yml:

resilience4j.retry:
  instances:
    paymentRetry:
      maxRetryAttempts: 3
      waitDuration: 500ms

This looks very close to MicroProfile’s @Retry(maxRetries = 3, delay = 500). The difference is that MicroProfile assumes you are using a MicroProfile runtime, while Resilience4j works inside Spring Boot. By adopting Resilience4j, you effectively bring the MicroProfile fault tolerance contract into your Spring Boot codebase.

How about health checks? MicroProfile Health defines a HealthCheck interface and a @Health qualifier. Spring Boot has its own HealthIndicator. Both produce a JSON response that includes the overall status. In a mixed environment, you might want both types of services to expose health endpoints in a uniform way so that your Kubernetes probes behave consistently. I usually create a small adapter that wraps a MicroProfile HealthCheck inside a Spring Boot HealthIndicator. Here’s a simplified version:

@Component
public class MicroProfileHealthAdapter implements HealthIndicator {

    private final HealthCheck mpHealth;

    public MicroProfileHealthAdapter() {
        // Instantiate a MicroProfile HealthCheck implementation
        mpHealth = new DatabaseHealthCheck();
    }

    @Override
    public Health health() {
        HealthCheckResponse response = mpHealth.call();
        if (response.getStatus() == HealthCheckResponse.Status.UP) {
            return Health.up().withDetail("check", response.getName()).build();
        }
        return Health.down().withDetail("check", response.getName()).build();
    }
}

Now Spring Boot’s /actuator/health will include the same logic that a MicroProfile runtime’s /health would expose. No duplication of monitoring configuration.

Metrics are another area where the two worlds collide. MicroProfile Metrics defines @Counted, @Timed, @Metered, etc. Spring Boot uses Micrometer, which is actually the back‑end for MicroProfile Metrics in many runtimes. You can simply use Micrometer annotations in your Spring Boot service and rest assured that any MicroProfile runtime consuming your metrics via the /metrics endpoint will understand the format. For example:

import io.micrometer.core.annotation.Timed;

@RestController
public class OrderController {

    @Timed(value = "orders.create", description = "Time taken to create an order")
    @PostMapping("/orders")
    public Order createOrder(@RequestBody Order order) {
        // ...
    }
}

Does this look familiar to MicroProfile’s @Timed(unit = MetricUnits.MILLISECONDS)? Yes, the concepts are almost identical. The difference is the import package. By sticking to Micrometer, you keep your code portable when the same service later moves to a MicroProfile runtime.

JWT propagation is often the trickiest part. MicroProfile JWT defines a standard way to pass roles and claims using the @RolesAllowed annotation and the JsonWebToken interface. Spring Boot can handle JWTs with spring-security-oauth2-resource-server and spring-security-oauth2-jose. However, the claim names and token validation rules are often different. To align them, I wrote a small class that reads the MicroProfile JWT claims and feeds them into Spring Security’s Authentication object:

@Component
public class MicroProfileJwtAuthenticationConverter implements Converter<Jwt, AbstractAuthenticationToken> {

    @Override
    public AbstractAuthenticationToken convert(Jwt jwt) {
        Collection<GrantedAuthority> authorities = new ArrayList<>();
        // MicroProfile uses "groups" claim instead of "scope"
        List<String> groups = jwt.getClaimAsStringList("groups");
        if (groups != null) {
            for (String group : groups) {
                authorities.add(new SimpleGrantedAuthority("ROLE_" + group));
            }
        }
        return new JwtAuthenticationToken(jwt, authorities);
    }
}

Now my Spring Boot service accepts the same JWT that a MicroProfile service would emit. The claim structure is consistent across the entire fleet.

I remember one project where we had a dozen Spring Boot services talking to two legacy MicroProfile services written in Open Liberty. The legacy services used @CircuitBreaker from MicroProfile Fault Tolerance. Our Spring Boot services used Resilience4j. As long as both sides exposed the same REST endpoints and agreed on error response codes, it didn’t matter that the circuit breaker implementation came from different libraries. The microservice mesh only cared about behaviour, not the underlying framework.

What about when you need to deploy both types of services in the same Kubernetes cluster? You can write a single health probe configuration that works for both. The key is to make the health endpoint paths and response formats identical. I configure Spring Boot’s management port and base path to match MicroProfile’s default:

management:
  endpoints:
    web:
      base-path: /health
  server:
    port: 8081

Now my Spring Boot health endpoint lives at /health on port 8081. In MicroProfile, the default health endpoint is also /health on a similar management port. Kubernetes liveness and readiness probes can use the same URL for every service.

Is this integration perfect? No. There are edges where MicroProfile specifications require a container that manages lifecycle and configuration, which Spring Boot does differently. For example, MicroProfile Config uses a Config interface with ordered sources, while Spring Boot uses @ConfigurationProperties and Environment abstraction. But you can write a bridge using the SmallRye Config library (the reference implementation of MicroProfile Config) inside Spring Boot. I have done this by including the SmallRye Config dependency and then injecting org.eclipse.microprofile.config.Config directly into my Spring beans. It works, though it adds complexity.

The real value of integrating these two worlds is not about replacing one with the other. It’s about reducing friction when you have teams that are comfortable with different frameworks. Instead of forcing everyone onto Spring Boot or MicroProfile, you let each team pick their favourite, then agree on the contracts for health, fault tolerance, metrics, and security. That agreement is exactly what MicroProfile provides. And with a few lines of configuration and some adapter classes, Spring Boot can honour those contracts without losing its own strengths.

If you find yourself in a similar mixed ecosystem, start small. Pick one MicroProfile specification—say, health checks—and align your Spring Boot service to expose the same endpoint. Validate it with the same tools your MicroProfile services use. Then move on to metrics or fault tolerance. Each step makes your overall system more coherent and easier to manage.

I’d love to hear your own stories about mixing frameworks. Have you tried to get Spring Boot services to work seamlessly alongside MicroProfile runtimes? What worked, and what broke? Drop a comment below. If this article helped you see the possibility, hit the like button and share it with your team—especially the person who insists you must pick only one ecosystem. Together, we can build cloud-native applications that respect both standards and real‑world constraints.


As a best-selling author, I invite you to explore my books on Amazon. Don’t forget to follow me on Medium and show your support. Thank you! Your support means the world!


101 Books

101 Books is an AI-driven publishing company co-founded by author Aarav Joshi. By leveraging advanced AI technology, we keep our publishing costs incredibly low—some books are priced as low as $4—making quality knowledge accessible to everyone.

Check out our book Golang Clean Code available on Amazon.

Stay tuned for updates and exciting news. When shopping for books, search for Aarav Joshi to find more of our titles. Use the provided link to enjoy special discounts!


📘 Checkout my latest ebook for free on my channel!
Be sure to like, share, comment, and subscribe to the channel!


Our Creations

Be sure to check out our creations:

Investor Central | Investor Central Spanish | Investor Central German | Smart Living | Epochs & Echoes | Puzzling Mysteries | Hindutva | Elite Dev | JS Schools


We are on Medium

Tech Koala Insights | Epochs & Echoes World | Investor Central Medium | Puzzling Mysteries Medium | Science & Epochs Medium | Modern Hindutva

Keywords: Spring Boot, Eclipse MicroProfile, enterprise microservices, Resilience4j, JWT propagation



Similar Posts
Blog Image
Secure Event-Driven Architecture: Integrating Apache Kafka with Spring Security for Enterprise Authentication

Learn to integrate Apache Kafka with Spring Security for secure event-driven systems. Build scalable microservices with proper authentication & authorization.

Blog Image
How to Build Event-Driven Microservices with Spring Cloud Stream and Apache Kafka

Learn to build scalable event-driven microservices with Spring Cloud Stream and Apache Kafka. Step-by-step guide with code examples, testing, and production best practices.

Blog Image
CQRS Event Sourcing Spring Boot Axon Framework: Complete Implementation Guide for Enterprise Applications

Learn how to implement CQRS and Event Sourcing with Spring Boot and Axon Framework. Master commands, events, projections, sagas, and production deployment.

Blog Image
Master Event-Driven Microservices: Apache Kafka, Spring Boot & Testcontainers Complete Guide

Learn to build scalable event-driven microservices using Apache Kafka, Spring Boot & Testcontainers. Complete guide with code examples, testing strategies & production tips.

Blog Image
Apache Kafka + Spring Cloud Stream: Build Scalable Event-Driven Microservices Without Complex Boilerplate Code

Learn how to integrate Apache Kafka with Spring Cloud Stream to build scalable event-driven microservices. Simplify messaging with declarative programming and boost performance.

Blog Image
Complete Guide to Virtual Threads in Spring Boot: Performance Boost with Reactive Patterns

Learn how to implement virtual threads with Spring Boot and reactive patterns. Complete guide covering setup, REST APIs, database integration, and performance optimization for scalable Java applications.