<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Development on Maarten on IT</title><link>https://maarten.mulders.it/categories/development/</link><description>Recent content in Development on Maarten on IT</description><generator>Hugo</generator><language>en-us</language><copyright>&amp;copy; 2013 - 2026 Maarten Mulders</copyright><lastBuildDate>Mon, 28 Jul 2025 08:14:19 +0200</lastBuildDate><atom:link href="https://maarten.mulders.it/categories/development/index.xml" rel="self" type="application/rss+xml"/><item><title>Building a CLI with Quarkus, Kotlin and GraalVM</title><link>https://maarten.mulders.it/2025/07/building-a-cli-with-quarkus-kotlin-and-graalvm/</link><pubDate>Mon, 28 Jul 2025 08:17:00 +0200</pubDate><guid>https://maarten.mulders.it/2025/07/building-a-cli-with-quarkus-kotlin-and-graalvm/</guid><description>&lt;p&gt;Command-line tools are great for automation, but choosing the right technology stack to build them can be tricky.
I recently set out to build a new command-line application to streamline some tasks, drawing from previous experiences where the tooling left me wanting more.&lt;/p&gt;
&lt;p&gt;This time, I chose a different combination of technologies that better suits my needs: Kotlin, Quarkus, and GraalVM. In this blog, I’ll walk you through the setup and decisions behind this stack—so you can get up and running even faster when building your own CLI tools.&lt;/p&gt;</description></item><item><title>Measure Your Maven Build</title><link>https://maarten.mulders.it/2024/03/measure-your-maven-build/</link><pubDate>Fri, 15 Mar 2024 09:46:00 +0200</pubDate><guid>https://maarten.mulders.it/2024/03/measure-your-maven-build/</guid><description>&lt;p&gt;Slow builds are annoying!&lt;/p&gt;
&lt;p&gt;There, I&amp;rsquo;ve said it.
And you know it&amp;rsquo;s true, don&amp;rsquo;t you?
They take valuable time, they are a source of frustration, they extend the feedback cycle, and often they provide the perfect excuse for &lt;a href="https://xkcd.com/303/"&gt;slacking off&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But it doesn&amp;rsquo;t have to be this way!
Rather than getting another cup of coffee or playing that medieval game of gladiator, what if we would investigate &lt;em&gt;why&lt;/em&gt; the build is so slow?
If we know the bottlenecks, we can address them.
That would shorten the feedback loop, increasing our productivity and our job happiness in one go.&lt;/p&gt;</description></item><item><title>Use git bisect to pinpoint a bug</title><link>https://maarten.mulders.it/2021/01/use-git-bisect-to-pinpoint-a-bug/</link><pubDate>Thu, 28 Jan 2021 14:15:09 +0100</pubDate><guid>https://maarten.mulders.it/2021/01/use-git-bisect-to-pinpoint-a-bug/</guid><description>&lt;p&gt;During my work on Maven today, I found a very specific bug.
The error message wasn&amp;rsquo;t that clear, and I couldn&amp;rsquo;t make a guess what might&amp;rsquo;ve caused it.
I read about &lt;code&gt;git bisect&lt;/code&gt; a few times and figured that today, I would use that tool to find the bug.&lt;/p&gt;</description></item><item><title>What's New in Maven 4</title><link>https://maarten.mulders.it/2020/11/whats-new-in-maven-4/</link><pubDate>Mon, 30 Nov 2020 08:02:09 +0100</pubDate><guid>https://maarten.mulders.it/2020/11/whats-new-in-maven-4/</guid><description>&lt;p&gt;Recently, the Maven community decided to push forward and &lt;a href="https://github.com/apache/maven/commit/3736be9c15122d65e6ef675557eb0f882f82b012"&gt;start working&lt;/a&gt; &lt;a href="https://twitter.com/ASFMavenProject/status/1332288204351934466"&gt;towards a 4.0.0 release&lt;/a&gt;.
The first question after this announcement is of course: what can we expect Maven 4 to bring us?
A lot - and in this post, we want to highlight some of the features that we are particularly excited about.&lt;/p&gt;</description></item><item><title>Multiple Git identities</title><link>https://maarten.mulders.it/2020/07/multiple-git-identities/</link><pubDate>Mon, 13 Jul 2020 08:10:05 +0200</pubDate><guid>https://maarten.mulders.it/2020/07/multiple-git-identities/</guid><description>&lt;p&gt;Everything is code, and code is everywhere.
For me, this means I put more and more stuff into version control.
Whether it is infrastructure descriptions, documentation, software or this blog, I always store it in a Git repository.
But sometimes this gets dirty, because you accidentally forget to change your Git user details.&lt;/p&gt;</description></item><item><title>DevNexus Day 2: Metrics, Monolith Decomposition</title><link>https://maarten.mulders.it/2020/02/devnexus-day-2-metrics-monolith-decomposition/</link><pubDate>Fri, 21 Feb 2020 21:55:00 +0200</pubDate><guid>https://maarten.mulders.it/2020/02/devnexus-day-2-metrics-monolith-decomposition/</guid><description>&lt;p&gt;Together with four &amp;ldquo;AwesomeSauce&amp;rdquo; colleagues from &lt;a href="https://www.infosupport.com/"&gt;Info Support&lt;/a&gt;, I&amp;rsquo;m attending &lt;a href="https://devnexus.com/"&gt;DevNexus&lt;/a&gt; this year.
For me, it&amp;rsquo;s the second time I&amp;rsquo;m here, as I spoke here in 2018, too.
Next to delivering my own &amp;ldquo;React in 50 minutes&amp;rdquo; session I&amp;rsquo;m attending some sessions to update with new technology advancements.
After &lt;a href="https://maarten.mulders.it/2020/02/devnexus-day-1-webassembly-productivity/"&gt;a great first day&lt;/a&gt;, let&amp;rsquo;s move on to the second (and last) day.&lt;/p&gt;</description></item><item><title>DevNexus Day 1: WebAssembly, Productivity</title><link>https://maarten.mulders.it/2020/02/devnexus-day-1-webassembly-productivity/</link><pubDate>Fri, 21 Feb 2020 15:20:13 +0200</pubDate><guid>https://maarten.mulders.it/2020/02/devnexus-day-1-webassembly-productivity/</guid><description>&lt;p&gt;Together with four &amp;ldquo;AwesomeSauce&amp;rdquo; colleagues from &lt;a href="https://www.infosupport.com/"&gt;Info Support&lt;/a&gt;, I&amp;rsquo;m attending &lt;a href="https://devnexus.com/"&gt;DevNexus&lt;/a&gt; this year.
For me, it&amp;rsquo;s the second time I&amp;rsquo;m here, as I spoke here in 2018, too.
Next to delivering my own &amp;ldquo;React in 50 minutes&amp;rdquo; session I&amp;rsquo;m attending some sessions to update with new technology advancements.&lt;/p&gt;</description></item><item><title>Customise the Maven Release process</title><link>https://maarten.mulders.it/2020/01/customise-the-maven-release-process/</link><pubDate>Fri, 10 Jan 2020 09:30:13 +0200</pubDate><guid>https://maarten.mulders.it/2020/01/customise-the-maven-release-process/</guid><description>&lt;p&gt;Shipping a new release of software usually involves quite a few steps.
Depending on the type of software, this may be something you rarely do.
Thus, it often involves manual steps.
This is not necessary!
Maven has had its &amp;ldquo;Release Plugin&amp;rdquo; since approximately April 2007; yes, that&amp;rsquo;s over 12 years!
It has served both the Maven project and many other software projects.&lt;/p&gt;</description></item><item><title>Devoxx - Day One</title><link>https://maarten.mulders.it/2019/11/devoxx-day-one/</link><pubDate>Wed, 06 Nov 2019 17:22:13 +0200</pubDate><guid>https://maarten.mulders.it/2019/11/devoxx-day-one/</guid><description>&lt;p&gt;This year I&amp;rsquo;m returning to Devoxx.
I&amp;rsquo;m planning to write some notes on interesting sessions or other content.
Also, I&amp;rsquo;ll be delivering my talk on &lt;a href="https://maarten.mulders.it/talks/#ssl-tls-for-mortals"&gt;Transport Layer Security&lt;/a&gt; tomorrow.
But today was a day of catching up with old friends and attending a talk or two.&lt;/p&gt;
&lt;p&gt;One talk really caught my attention: &amp;ldquo;Implementing a simple JVM in Rust&amp;rdquo;.&lt;/p&gt;</description></item><item><title>Building a programming language on GraalVM (Part 1)</title><link>https://maarten.mulders.it/2019/10/building-a-programming-language-on-graalvm-part-1/</link><pubDate>Sun, 13 Oct 2019 16:27:13 +0200</pubDate><guid>https://maarten.mulders.it/2019/10/building-a-programming-language-on-graalvm-part-1/</guid><description>&lt;p&gt;If you&amp;rsquo;ve followed recent developments in the Java ecosystem, you must know &lt;a href="https://www.graalvm.org/"&gt;GraalVM&lt;/a&gt;.
Many blog posts cover how you can &lt;a href="https://royvanrijn.com/blog/2018/09/part-2-native-microservice-in-graalvm/"&gt;build native executables&lt;/a&gt; from Java source code.
This is indeed exciting: your program starts faster, and consumes less memory.
Other popular topics include building Java applications that run code in other languages.
You can run JavaScript, Python, Ruby or R code in the JVM.
But there&amp;rsquo;s more: in fact you can run &lt;em&gt;any&lt;/em&gt; language inside the JVM!
Are you curious how? Continue reading&amp;hellip;&lt;/p&gt;</description></item><item><title>Code One - Day Three</title><link>https://maarten.mulders.it/2019/09/code-one-day-three/</link><pubDate>Wed, 18 Sep 2019 20:08:00 -0700</pubDate><guid>https://maarten.mulders.it/2019/09/code-one-day-three/</guid><description>&lt;p&gt;Third day on Code One already!
Highlights for today: the Community Keynote, a trip to GitHub and a session called &amp;ldquo;Sarcasm as a Service&amp;rdquo;.&lt;/p&gt;</description></item><item><title>Code One - Day Two</title><link>https://maarten.mulders.it/2019/09/code-one-day-two/</link><pubDate>Tue, 17 Sep 2019 16:11:00 -0700</pubDate><guid>https://maarten.mulders.it/2019/09/code-one-day-two/</guid><description>&lt;p&gt;On this second day at Code One I have again visited interesting sessions.
One on security by &lt;a href="https://twitter.com/manicode"&gt;Jim Manicode&lt;/a&gt; and one on cash (or the lack thereof) in Sweden.&lt;/p&gt;</description></item><item><title>Code One - Day One</title><link>https://maarten.mulders.it/2019/09/code-one-day-one/</link><pubDate>Mon, 16 Sep 2019 18:42:32 -0700</pubDate><guid>https://maarten.mulders.it/2019/09/code-one-day-one/</guid><description>&lt;p&gt;This year I&amp;rsquo;m returning to Oracle Code One (formerly JavaOne) for the third time.
I&amp;rsquo;m planning to write some notes on interesting sessions or other content.&lt;/p&gt;</description></item><item><title>How did I get that library?!</title><link>https://maarten.mulders.it/2019/09/how-did-i-get-that-library/</link><pubDate>Wed, 11 Sep 2019 18:42:32 +0200</pubDate><guid>https://maarten.mulders.it/2019/09/how-did-i-get-that-library/</guid><description>&lt;p&gt;When you&amp;rsquo;re writing Java applications, chances are you&amp;rsquo;re using Maven for dependency management.
It lets you declare the &lt;em&gt;artifacts&lt;/em&gt; you need to build your application.
Those artifacts also depend on other artifacts.
This means you have &lt;em&gt;transitive dependencies&lt;/em&gt; - dependencies you didn&amp;rsquo;t declare yourself but you need them anyway.&lt;/p&gt;</description></item><item><title>Troubleshooting SOAP and MTOM using the command line</title><link>https://maarten.mulders.it/2018/12/troubleshooting-soap-and-mtom-using-the-command-line/</link><pubDate>Mon, 17 Dec 2018 09:24:13 +0200</pubDate><guid>https://maarten.mulders.it/2018/12/troubleshooting-soap-and-mtom-using-the-command-line/</guid><description>&lt;p&gt;When you want to transmit binary files over SOAP-based webservices, you have two choices: &lt;a href="https://en.wikipedia.org/wiki/Base64"&gt;Base64&lt;/a&gt; or &lt;a href="https://en.wikipedia.org/wiki/Message_Transmission_Optimization_Mechanism"&gt;Message Transmission Optimization Mechanism (MTOM)&lt;/a&gt;.
The latter is much more efficient, but also harder to troubleshoot if it doesn&amp;rsquo;t work at once.&lt;/p&gt;
&lt;p&gt;Both options have their own typical scenario&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Serialise the file content using Base64 and include the result right into the XML structure.
This is relatevely easy to implement and troubleshoot.
It usually works well for small binary files, but as files grow larger, you may run into performance issues.
The Base64-encoded binary file may be so big that the XML parser will blow up.&lt;/li&gt;
&lt;li&gt;Use MTOM to transfer the request and attachments.
In this approach, the SOAP request (XML) and any attachments are sent as a multipart request.
This is a bit harder to implement, and if it doesn&amp;rsquo;t work at once, it is even harder to troubleshoot.
But on the other hand, it allows for much more efficient transportation of the attached files.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="soap-over-http"&gt;SOAP over HTTP&lt;/h2&gt;
&lt;p&gt;As a primer, let&amp;rsquo;s have a quick look at how &amp;ldquo;regular&amp;rdquo; SOAP requests look when transmitted over HTTP.
Imagine we have a file upload webservice which accepts files in any format, along with a file name.
If we were to upload a file, the request might look like this.&lt;/p&gt;</description></item><item><title>A first look at MVC 1.0</title><link>https://maarten.mulders.it/2018/09/a-first-look-at-mvc-1.0/</link><pubDate>Fri, 14 Sep 2018 21:20:19 +0200</pubDate><guid>https://maarten.mulders.it/2018/09/a-first-look-at-mvc-1.0/</guid><description>&lt;p&gt;Recently, Twitter brought the &lt;a href="https://www.agilejava.eu/2018/08/31/ozark-becomes-eclipse-krazo/"&gt;renaming of Ozark to Krazo&lt;/a&gt; to my attention.
It pulled my attention: I had never heard of either projects, and I wondered what they would be about.
Ozark (or Krazo) will be the Reference Implementation of the new Model-View-Controller Specification.
This &lt;a href="https://www.mvc-spec.org/"&gt;MVC specification&lt;/a&gt;, also known as &lt;a href="https://jcp.org/en/jsr/detail?id=371"&gt;JSR 371&lt;/a&gt;, was planned for inclusion in Java EE 8, but eventually dropped.
Apparently, this didn&amp;rsquo;t kill the effort.
I was curious to see where the specification (and it&amp;rsquo;s implementation) would be now.&lt;/p&gt;</description></item><item><title>Custom SOAP Faults using Spring WS</title><link>https://maarten.mulders.it/2018/07/custom-soap-faults-using-spring-ws/</link><pubDate>Tue, 24 Jul 2018 16:05:35 +0200</pubDate><guid>https://maarten.mulders.it/2018/07/custom-soap-faults-using-spring-ws/</guid><description>&lt;p&gt;There are many situations when you need to write a SOAP-based webservice.
Maybe you are writing a test dummy, or maybe you got the interface from some kind of architect.
&lt;a href="https://docs.spring.io/spring-ws/sites/1.5/reference/html/why-contract-first.html"&gt;(Yes, there are other reasons, too.)&lt;/a&gt;
And chances are you&amp;rsquo;ll be using &lt;a href="https://docs.spring.io/spring-ws/docs/3.0.1.RELEASE/reference/#tutorial"&gt;Spring-WS&lt;/a&gt; to do this.&lt;/p&gt;
&lt;p&gt;Recently I was doing that, and I found the following inside the interface definition (WSDL):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;element&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;faultMessage&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;common:FaultMessage&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;message&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;faultMessage&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;part&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;faultMessage&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;element=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;tns:faultMessage&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/message&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;portType&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;someName&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;operation&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;searchOrder&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;input&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;message=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;tns:searchOrderRequest&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;output&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;message=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;tns:searchOrderResponse&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;fault&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;faultMessage&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;message=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;tns:faultMessage&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/operation&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/portType&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That was a rather challenging thing!
In case the operation would fail, it should give a SOAP Fault with a custom element in it:&lt;/p&gt;</description></item><item><title>Building ASP.NET Core apps on CircleCI</title><link>https://maarten.mulders.it/2018/04/building-asp.net-core-apps-on-circleci/</link><pubDate>Mon, 02 Apr 2018 11:42:35 +0200</pubDate><guid>https://maarten.mulders.it/2018/04/building-asp.net-core-apps-on-circleci/</guid><description>&lt;p&gt;Recently, my co-worker &lt;a href="https://twitter.com/willem_meints"&gt;Willem&lt;/a&gt; pulled my attention to the &lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/index"&gt;.NET Microservices. Architecture for Containerized .NET Applications&lt;/a&gt; e-book.
Although I have a strong background in Java and the Java platform, I started reading it, and soon I felt like trying it out.
But building software without having automated builds and tests is not the real thing, so that was the first thing I wanted to do.
I usually use &lt;a href="https://circleci.com/"&gt;CircleCI&lt;/a&gt; for that, but unfortunately they don&amp;rsquo;t seem to have an official guide for that.&lt;/p&gt;</description></item><item><title>Quickly count your code base</title><link>https://maarten.mulders.it/2016/02/quickly-count-your-code-base/</link><pubDate>Wed, 03 Feb 2016 08:10:40 +0200</pubDate><guid>https://maarten.mulders.it/2016/02/quickly-count-your-code-base/</guid><description>&lt;p&gt;Often, the size of a code base is measured in terms of &amp;ldquo;source lines of code&amp;rdquo; (SLoC).
If you&amp;rsquo;re interested in the size of your code base - or your client is - this metric provides a way to express that size.
Of course, comments and the like are not considered to be code, so how to determine this metric?
Using &lt;code&gt;grep&lt;/code&gt; is tempting, but it quickly results in a very complex and hard-to-understand approach.&lt;/p&gt;</description></item></channel></rss>