About Me
Modernizing the systems businesses already depend on
I've been working with Java almost since it existed. I first saw it as a book on an engineer's desk while I was an electronics test technician at Spectra Logic in Boulder, Colorado, teaching myself C on the side. Sun Microsystems had a campus eight miles from my home, and I decided I was going to work there. A few years of self-study and one lucky introduction later, I did: my first professional software job was building Java-based enterprise web applications at Sun.
Since then I've worked on enterprise Java systems from several sides: as a developer, as a test automation architect, and as part of a DevOps architecture team helping an organization move from waterfall delivery to continuous delivery. I've built and tested microservices, containerized test environments with Docker and Kubernetes, and set up the CI/CD pipelines that let teams change large systems without fear.
That mix shapes how I approach modernization. Most legacy applications aren't failing because of Java. They're hard to change because boundaries have eroded, tests are thin, deployments are risky, and knowledge is spread across a handful of people. Rewriting from scratch rarely fixes any of that. It usually just moves the risk somewhere you can't see it.
I treat modernization as a risk-management problem first and an architecture problem second. Microservices can be the right answer, but only when the domain, the team structure, and the operational maturity support them. Often the better first move is a well-structured modular monolith on a current Java and framework version, with tests and observability in place. From there, services can be extracted one at a time, behind a facade, with a rollback path at every step.
My background in quality engineering is a big part of what I bring. Characterization tests, contract tests, parallel runs, and good telemetry are what turn a high-stakes migration into a series of small, boring, reversible changes. Boring is the goal.
How I Modernize Without Betting the Business
Six steps that keep the system running, and shippable, the whole way through
Understand before changing
Map the domain, dependencies, and runtime behavior. Tie the effort to business outcomes such as release speed, scaling, or cost, and decide honestly whether microservices are needed at all.
Build a safety net
Pin down current behavior with characterization and API tests, add a CI/CD pipeline, and capture baseline metrics. You can't safely change what you can't verify.
Modularize in place
Upgrade the Java and framework baseline, then carve the monolith into modules with enforced boundaries. A clean modular monolith is often a good stopping point.
Strangle incrementally
Put a routing facade in front of the application and extract one capability at a time, starting where value is high and coupling is low. The legacy path stays live until the new one has proven itself.
Release reversibly
Use feature flags, shadow traffic, parallel runs, and canary releases. Every cutover has a measured success signal and a rollback that takes minutes, not a war room.
Untangle the data last
Split the shared database only after the code boundaries hold. Use views, change data capture, and the outbox pattern to move ownership without dual-write bugs.
What I Write About
Practical guidance drawn from real projects
Monolith Decomposition
Finding service boundaries, modular monoliths, the Strangler Fig pattern, and knowing when to stop
Java Platform Upgrades
Moving from legacy Java EE and old JDKs to modern Java, Jakarta EE, and Spring Boot
Testing as a Safety Net
Characterization, contract, and end-to-end tests that make large changes safe to ship
Cloud-Native Delivery
Containers, Kubernetes, CI/CD pipelines, and the observability that makes cutovers measurable
Latest Articles
Modernization, architecture, and the engineering practices that support them
Modernizing a Java Monolith Without Betting the Business
A step-by-step playbook for moving an enterprise Java application toward modular and microservice architectures while keeping risk low.
Quality Dashboards with Elasticsearch and Kibana
Aggregating results across frameworks to expose failure trends and release quality.
The Power of Playwright: Supercharging Test Automation with AI
What makes Playwright so capable, and how AI-assisted workflows make it even more powerful.
Contact
Planning a modernization effort, or stuck in the middle of one? I'm happy to talk.