Skip to main content

Using AI to modernize a Java project

·874 words·5 mins
Alejandro Duarte
Author
Alejandro Duarte
Alejandro Duarte is a Software Engineer, published author, and Developer Relations. He has been programming computers since the mid-90s. Starting with BASIC, Alejandro transitioned to C, C++, and Java during his academic years at the National University of Colombia. He relocated first to the UK and then to Finland to foster his involvement in the open-source industry. Alejandro is a recognized figure in Java and MariaDB circles.

If you have been following the latest buzzwords in the software industry, you have probably encountered the term spec-driven development (SDD). There are now many tools and processes using the term, often with different meanings at the implementation level. Some advocate for methodologies where developers only deal with specs and never touch the code. Others propose a more lax process where specs are close to throwaway prompts. I have been experimenting with some of these frameworks/tools/methodologies to find the best fit for my projects and (as always) the answer on what to pick is “it depends”. I have tried some of these tools and decided to use an ad-hoc AGENTS.md-based approach for one of my one-man-show projects (CrudUI Add-On).

SDD tools (that I have tried)
#

These are some of the SDD tools I have tried with small projects for experimentation:

  • Kiro (by AWS) seems to be relatively straightforward to adopt, and it includes tools and a simple process for defining requirements (a set of user stories), software design, and tasks (implementation steps). Once you create the specs, you kind of forget about them.

  • Spec-kit (by GitHub) follows a multi-phase process: constitution (project principles, non-negotiable rules), specify (user stories), plan (tech stack, architecture), tasks (implementation steps). Although it wasn’t 100% clear to me, it seems to propose using specs as the source of truth for your project—you evolve the spec documents as the project progresses. However, it also uses independent branches for every spec created, which makes it hard (impossible?) to use them as an evolving, always-up-to-date spec.

  • Tessl (by a startup with the same name) seems to aim at making specs the main (only?) touch point for developers and enabling “just let the AI write the code”. The workflow includes several steps: interview (an agent interviews you, a bit friendlier than this), spec (the agent writes documents that become the ultimate source of truth), review (you check the spec and validate), implementation (the agent writes code). When you need changes, you don’t edit the code; you edit the spec, which makes the agent update the code accordingly.

  • AI Unified Process (by my friend Simon Martinelli) frames AI-assisted development as a disciplined, iterative process. I like that it treats AI as a collaborator inside a structured workflow, not as a magic box that replaces engineering judgment.

My process with CrudUI Add-On
#

I recommend trying and following one of the previous tools in projects with multiple developers involved. For teams of one developer, like my personal project CrudUI Add-On, a lightweight process works pretty well. My plan was to create a new version of the library’s API that moves it from a classic imperative/setter-based style to a fluent one. This requires a rewrite, and I had been working on the main parts of the new API by designing it by hand with no AI-assisted coding. Once I was convinced that the new API would look and work well while keeping the philosophy of the project, I started implementing the missing parts with coding agents.

Here’s what I did:

  1. Implemented the main Java interfaces that are core to the library. This step was of high value, as it prevented LLMs from drifting too much from the software design I had in mind. Whether I could have simply written a spec for it instead of doing the software design myself is open to debate. Happy to hear your thoughts!

  2. I created an AGENTS.md file (that most if not all coding agents automatically read) and defined the project at a high level, the tech stack, source code organization, the role of the coding agent, build instructions, and what not to do.

  3. Inspired by the AI Unified Process, I created a vision.md file and added a link to it in the AGENTS.md file. The vision states the problem that the library solves, the solution at a high level, the target users, the goals and non-goals, and the core API that I manually designed (these are mostly Java interfaces).

  4. I used a coding agent to write specs using a given template. Since this was a modernization project and I had already coded some of the new API manually, I instructed the agent to write specs for missing functionality that the old API has but the new one does not. The agent generated around a dozen spec files.

  5. I took one spec at a time, reviewed it, edited it, and passed it to a coding agent for implementation. Steering was needed in most of the specs. This was sometimes due to ambiguity in the spec, sometimes due to realizations that you get when you actually see the feature implemented and change your mind, and sometimes just the AI drifting a bit. For some specs I went back and edited them for clarity or changes, and for others I left them untouched even if I had to steer the agent.

Conclusion
#

I was able to complete the new API implementation in a few days. There are still some rough edges that need polish, as well as testing and validation in real-world applications. However, the jump in productivity was clear and hard to argue against.

If you are curious and want to see the details, the code is available on GitHub.

Enjoyed this post? I can help your team implement similar solutions—contact me to learn more.

Related