# DripSharp: Building a Java-to-C# source converter with AI

> Source: <https://www.isaksky.com/posts/dripsharp-java-to-csharp-source-converter/>
> Published: 2026-08-20 15:55:55+00:00

A few months ago, Jarred Sumner [ported](https://bun.com/blog/bun-in-rust) Bun from Zig to Rust with AI, largely processing one file a time. While it was a cool thing to try, and I’m sure there are many reasons why this made sense for him to do it this way, it didn’t strike me as a great general way to tackle this kind of problem.

I am definitely for using AI where possible, but my instinct was that a better way to do this is to just create a program that walks the syntax tree of the source and applies a bunch of rules to transform it node by node.

A few reasons why this is better:

I decided to let AI (ChatGPT 5.5 and later 5.6) have a go at this. For my day job, a lot of my work is in the .NET ecosystem, and we saw that some problems are better solved in the JVM open source ecosystem. I went for a Java to C# code converter, using Clojure as the implementation language, since that is the JVM language I use the most.

To get started, I set up the main dependencies needed (e.g., Spoon for Java parsing), and wrote documentation for the project goals and architecture with AI assistance. For issue tracking I used [beads_rust](https://github.com/Dicklesworthstone/beads_rust).

At first, I tried a more elaborate workflow. It went like this:

`switch`

, `myMap.put(...)`

, etc.) list of the project, and put it in a database (Datomic).This ended up not working, and I had to throw away more than 1,000 commits. The agent went with a regex/string conversion engine, and iteratively narrowed the project goals down to almost nothing and declared victory.

A large part of why that failed may be that I tried Codex’s /goal mode for this, which at least in my case seemed to keep doubling down on poor decisions, and never “taking a deep breath” and reconsidering whether the direction it was taking was working out.

After throwing that out, I did a few sessions interactively on extra-high reasoning to get it started further in the right direction. ChatGPT 5.6 also dropped around this time, which appeared to help power through the initial logic-heavy work of handling each Java statement/expression type. The workflow that ended up working was a loop orchestrated by a small [Babashka](https://babashka.org/) script:

Towards the end, I switched to doing the planning interactively to make sure it wasn’t wasting time on things that did not matter.

After about two months of cranking on this with Codex, mostly unattended, it can now convert multiple non-trivial projects (PDFBox, Pkl, JSqlParser) and run tests successfully.

I think PDFBox is especially valuable. At work, we cobbled together 3 open-source .NET libraries to approximate the feature set we needed, and we were still missing some parts available in PDFBox, like working with PDF forms. In the ported version, PdfCarton, all 232 upstream test files for the modules I targeted have been ported, and my latest run had all 2,243 runnable tests passing. The remaining 8 were skipped for the same reasons as upstream.

Not all of the projects worked out that cleanly yet. For example, while the core of Pkl is written in Java, it had tests written in Kotlin, which this project cannot (yet?) handle. For now, the mechanically ported coverage is incomplete, but there are extensive LLM-authored tests, leveraging the existing .pkl test files as much as possible.

All in all, it came out to about 110 KLOC of Clojure, and used up most of my budget for a personal OpenAI 20x Pro plan ($200/mo) for two months, so $400. Even if you multiply it by 10 for API pricing, that is still quite a bit cheaper than the $165,000 needed for the Bun port. To be fair to the Bun port, I was not also fixing bugs, and this strategy can’t be parallelized as much. If I had given this my full attention it probably could have been done much faster and with even fewer tokens. For people in smaller software ecosystems without unlimited token budgets, I think this is a promising direction.

The converter lives on GitHub here:

[https://github.com/dripsharp/dripsharp](https://github.com/dripsharp/dripsharp)

The converted projects live in separate repos under the DripSharp organization:

Here is an example of one method converted from Java to C#:

As you can see, it is a pretty conservative translation, with Java compatibility function calls in some places. There are more compatibility wrappers than I expected, but the cases I’ve examined actually have good reasons, like different behavior when it comes to null, or slightly different behavior. For example, Java’s Map.put returns the old value, but the closest C# method does not return anything.

In some cases, it is a little too conservative, like adding `global::`

everywhere, but I’d rather solve that later with a Roslyn-based (the C# compiler/parser library) beautification layer. I’ll also fess up and note that I cheated a little and formatted the C# code above, which is not yet actually done for the outputs, but easily done with `CSharpier`

or similar tools.

If you plan on trying them out, keep in mind it is still early days, and there may be more work needed to get them production-ready.

**Q**: Will they be released on NuGet?
**A**: Yes, PdfCarton is already [on NuGet](https://www.nuget.org/packages/DripSharp.PdfCarton/3.0.8-alpha.1) as an alpha package. The rest are coming soon.

**Q**: Why not just use [IKVM](https://github.com/ikvmnet/ikvm)?
**A**: IKVM seems like a great project, but is limited to Java 8, which was released more than 12 years ago. Some interesting projects, like Pkl, have moved to higher Java versions. IKVM also works on bytecode, which isn’t good for taking advantage of .NET’s strengths like real generics, or creating idiomatic APIs. IKVM also discourages publishing ported packages on NuGet, which isn’t great for adoption.

**Q**: What’s with the name?
**A**: First of all, naming is hard, and a lot of the great names are already taken. That said, there is some logic in the name:

**Q**: Will you manually maintain each project?
**A**: No, I don’t have the bandwidth. But I will maintain DripSharp, and try to ensure it is able to port at least stable versions of the source projects - bug for bug.

**Q**: What about JVM library X?
**A**: Create an issue on the DripSharp repo and make a case for it, or just try converting it yourself. For my part, I want to limit this to high-value projects that do not already have a best-in-class offering on the .NET side.

**Q**: Will this work on any Java library without LLM help?
**A**: No. The JVM and .NET standard libraries have differences, so if a project uses a part of the Java standard library that is not available in .NET, alternatives have to be found or created. That said, as more projects are added and mapped, the chances of that being possible for pure Java projects increase.
