<?xml version="1.0" encoding="UTF-8"?>


<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>A Java geek</title>
    <description>Nicolas Fränkel&apos;s blog</description>
    <link>https://blog.frankel.ch/</link>
    <language>en</language>
    <copyright>Copyright 2008-2026 Nicolas Fränkel</copyright>
    <atom:link href="https://blog.frankel.ch/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Wed, 01 Apr 2026 16:29:58 +0000</pubDate>
    <lastBuildDate>Wed, 01 Apr 2026 16:29:58 +0000</lastBuildDate>
    <generator>Jekyll</generator>
    <image>
      <url>https://blog.frankel.ch/assets/pages/me/me.jpg</url>
      <title>A Java geek</title>
      <link>https://blog.frankel.ch/</link>
    </image>
    
    
      <item>
        <title>One tip for successful OpenTelemetry projects</title>
        <description>Leading your organization to use OpenTelemetry is a challenge. In addition to all the usual project hurdles, you&amp;#8217;ll face one of these two situations: convince your teams to use OpenTelemetry, or convince them to move from the telemetry tool they are already using to OpenTelemetry. Most people don&amp;#8217;t want to change. You&amp;#8217;ll need lots of effort and baby steps. My tip is the following: the fewer the changes, the higher your chances of success.</description>
        <pubDate>Sun, 29 Mar 2026 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/tip-opentelemetry-projects/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/tip-opentelemetry-projects/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/tip-opentelemetry-projects/cover.jpg" width="1536" height="1024" />
        
        
        <category>opentelemetry</category>
        
        <category>jvm</category>
        
        <category>jmx</category>
        
        <category>pragmatism</category>
        
        
        <category>Technical</category>
        
      </item>
    
      <item>
        <title>The Software Architect Elevator</title>
        <description>I don&amp;#8217;t think it&amp;#8217;s necessary to introduce Gregor Hohpe. I’m a big fan, having read Enterprise Integration Patterns, and I&amp;#8217;ve recommended the book ever since. When I spoke at the Software Architecture Gathering in 2024, I was fortunate enough to meet him and purchase this book. I&amp;#8217;m the happy owner of a signed copy.     Modern architects don’t try to be the smartest people in the room–they make everyone else smarter.</description>
        <pubDate>Sun, 22 Mar 2026 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/software-architect-elevator/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/software-architect-elevator/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/software-architect-elevator/cover.jpg" width="1062" height="1332" />
        
        
        <category>api</category>
        
        <category>design pattern</category>
        
        
        <category>Book</category>
        
        <category>review</category>
        
      </item>
    
      <item>
        <title>Writing an agent skill</title>
        <description>Most developers now use coding assistants. I do too—Copilot at work, Claude Code at home. As a developer, I prefer not to repeat myself. This post explains why and how to avoid repetition as a skill.   Don&amp;#8217;t Repeat Yourself   The DRY principle has been present in the software development field for ages. The idea is that if you copy and paste code in multiple places and a bug appears, you&amp;#8217;ll need to fix the bug in all these places.</description>
        <pubDate>Sun, 15 Mar 2026 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/writing-agent-skill/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/writing-agent-skill/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/writing-agent-skill/cover.jpg" width="1536" height="1024" />
        
        
        <category>ai</category>
        
        <category>agent</category>
        
        <category>skill</category>
        
        
        <category>Technical</category>
        
      </item>
    
      <item>
        <title>Pi-hole behind Tailscale</title>
        <description>As I age, I become increasingly cautious about my privacy. The slope the world is sliding on is also a big, unfortunate incentive. I have been eying Pi-hole for some time: in this post, I want to explain what it does, how to install it on a Raspberry Pi, and how to integrate it with Tailscale.   My take on privacy   Privacy, or more specifically digital privacy, is the ability to protect oneself from the constant data collection by legitimate companies and malicious actors alike when online.</description>
        <pubDate>Sun, 08 Mar 2026 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/pi-hole-tailscale/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/pi-hole-tailscale/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/pi-hole-tailscale/cover.jpg" width="1536" height="1024" />
        
        
        <category>privacy</category>
        
        <category>raspberry pi</category>
        
        <category>tailscale</category>
        
        
        <category>Technical</category>
        
      </item>
    
      <item>
        <title>Ready-to-use virtual clusters</title>
        <description>vCluster is a solution for creating virtual clusters within a host Kubernetes cluster.     Virtual clusters are a Kubernetes concept that enables isolated clusters to be run within a single physical Kubernetes cluster. Each cluster has its own API server, which makes them better isolated than namespaces and more affordable than separate Kubernetes clusters.    &amp;#8212; What are virtual clusters?</description>
        <pubDate>Sun, 01 Mar 2026 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/ready-to-use-virtual-clusters/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/ready-to-use-virtual-clusters/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/ready-to-use-virtual-clusters/cover.jpg" width="1536" height="1024" />
        
        
        <category>vcluster</category>
        
        <category>devops</category>
        
        <category>logging</category>
        
        <category>loki</category>
        
        
        <category>Technical</category>
        
      </item>
    
      <item>
        <title>JVM timing options</title>
        <description>For as long as I have been coding in Java, we have had requirements to measure the execution time of blocks of code. While the current good practice is to use OpenTelemetry&amp;#8217;s traces, not every company has reached this stage yet. Plus, some of the alternatives are OpenTelemetry-compatible. Let&amp;#8217;s see them in order.   The basic option   The basic option is what we have been doing for ages, and what the other options rely on anyway. It&amp;#8217;s based on the following API: System.</description>
        <pubDate>Sun, 22 Feb 2026 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/jvm-timing-options/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/jvm-timing-options/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/jvm-timing-options/cover.jpg" width="1536" height="1024" />
        
        
        <category>timer</category>
        
        <category>stopwatch</category>
        
        
        <category>Java</category>
        
      </item>
    
      <item>
        <title>Migrating from Jekyll to Hugo... or not</title>
        <description>Most of my blog posts are lessons learned. I&amp;#8217;m trying to achieve something, and I document the process I used to do it. This one is one of the few where, in the end, I didn&amp;#8217;t achieve what I wanted. In this post, I aim to explain what I learned from trying to migrate from Jekyll to Hugo, and why, in the end, I didn&amp;#8217;t take the final step.   Context   I started this blog on WordPress. After several years, I decided to migrate to Jekyll. I have been happy with Jekyll so far.</description>
        <pubDate>Sun, 15 Feb 2026 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/migrating-jekyll-hugo/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/migrating-jekyll-hugo/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/migrating-jekyll-hugo/cover.jpg" width="1536" height="1024" />
        
        
        <category>blog</category>
        
        <category>jekyll</category>
        
        <category>hugo</category>
        
        <category>static site generator</category>
        
        <category>performance</category>
        
        
        <category>Technical</category>
        
      </item>
    
      <item>
        <title>Rediscovering Java ServiceLoader: Beyond Plugins and Into Capabilities</title>
        <description>When you think of Java modularity, chances are your first thoughts land on JPMS, or perhaps on Spring’s flexible configuration model. For those who &apos;experienced&apos; like me, thought can reach OSGI specification or other stacks like Vert-X. Yet long before either, Java offered a minimal yet powerful mechanism for loose coupling: ServiceLoader.</description>
        <pubDate>Sun, 08 Feb 2026 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/rediscovering-java-serviceloader/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/rediscovering-java-serviceloader/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/rediscovering-java-serviceloader/cover.jpg" width="1536" height="1024" />
        
        
        
        <category>Java</category>
        
      </item>
    
      <item>
        <title>Feedback on checked exceptions and lambdas</title>
        <description>I got a lot of interesting feedback on Checked exceptions and lambdas. Let&amp;#8217;s start with my own: after writing the post, I realized I had written a similar post some time ago.   Mistakes I made   I made a mistake in the code regarding Apache Commons Lang 3, where I mistakenly used the recover() function, which is actually from Vavr.   Apache Commons Lang provides a regular utility function, which mimics the custom code we wrote last week.</description>
        <pubDate>Sun, 01 Feb 2026 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/feedback-checked-exceptions-lambdas/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/feedback-checked-exceptions-lambdas/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/feedback-checked-exceptions-lambdas/cover.jpg" width="1536" height="1024" />
        
        
        <category>exceptions</category>
        
        <category>error handling</category>
        
        <category>lambdas</category>
        
        
        <category>Java</category>
        
      </item>
    
      <item>
        <title>From a JAR to a full-fledged MacOS app</title>
        <description>A couple of years ago, I developed a small Kotlin GUI to help me rename my files in batch. I actually created it with different JVM frameworks to compare their relative merits. In any case, I didn&amp;#8217;t use it up until last week. And then, I was surprised to see that it didn&amp;#8217;t work to rename a network volume, although it had in the past. In this brief post, I aim to describe the issue and its solution.   The problem   When launching the UberJAR, I couldn&amp;#8217;t see the network volumes.</description>
        <pubDate>Sun, 25 Jan 2026 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/jar-to-macos-app/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/jar-to-macos-app/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/jar-to-macos-app/cover.jpg" width="1536" height="1024" />
        
        
        <category>jar</category>
        
        <category>macos</category>
        
        <category>app</category>
        
        
        <category>Java</category>
        
      </item>
    
      <item>
        <title>Checked exceptions and lambdas</title>
        <description>Java&amp;#8217;s checked exceptions were a massive improvement over C&amp;#8217;s error-handling mechanism. As time passed and experience accumulated, we collectively concluded that we weren&amp;#8217;t there yet. However, Java&amp;#8217;s focus on stability has kept checked exceptions in its existing API.   Java 8 brought lambdas after the &apos;checked exceptions are great&apos; trend. None of the functional interface methods accepts a checked exception.</description>
        <pubDate>Sun, 18 Jan 2026 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/checked-exceptions-lambdas/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/checked-exceptions-lambdas/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/checked-exceptions-lambdas/cover.jpg" width="1536" height="1024" />
        
        
        <category>exceptions</category>
        
        <category>error handling</category>
        
        <category>lambdas</category>
        
        
        <category>Java</category>
        
      </item>
    
      <item>
        <title>From Cloudflare Zero-trust to Tailscale</title>
        <description>I have spent some time last year implementing Cloudflare Tunnels on my Home Assistant and my Synology NAS. On Mastodon, I had not one but two commenters advertising for Tailscale:     Post by @frankel@mastodon.top View on Mastodon     I decided to give it a try and migrate my servers and devices to Tailscale. In this post, I want to describe how I did. Thanks to Heiko Does and higgins for prompting me to look further!   What is Tailscale, how and why?</description>
        <pubDate>Sun, 11 Jan 2026 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/cloudflare-zero-trust-tailscale/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/cloudflare-zero-trust-tailscale/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/cloudflare-zero-trust-tailscale/cover.jpg" width="1536" height="1024" />
        
        
        <category>cloudflare</category>
        
        <category>tailscale</category>
        
        <category>networking</category>
        
        
        <category>Technical</category>
        
      </item>
    
      <item>
        <title>2025 in retrospective</title>
        <description>From the beginning, the focus of this blog has been technical, very rarely organizational. I broke this unwritten rule once in 2015. I began writing retrospectives in 2023 on the year that had passed. Let&amp;#8217;s continue the tradition, but with a wider scope than before. The situation warrants it.   More chaos   It&amp;#8217;s a hard realization to admit, but the world is spiraling deeper and deeper into chaos.</description>
        <pubDate>Sun, 04 Jan 2026 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/2025-retrospective/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/2025-retrospective/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/2025-retrospective/cover.jpg" width="1536" height="1024" />
        
        
        <category>2025</category>
        
        <category>retrospective</category>
        
        
        <category>Miscellaneous</category>
        
      </item>
    
      <item>
        <title>YOW! 2025</title>
        <description>I have been eyeing the YOW! conferences for probably more than a decade. They occur in Australia, and feature top industry experts. I was thus overjoyed when they invited me to speak on the YOW! tour earlier this year. Here&amp;#8217;s a summary of my amazing time there.   My participation   YOW! takes place in three different cities: Melbourne, Brisbane, and Sidney. I presented my brand new talk on WebAssembly on Kubernetes in each city.</description>
        <pubDate>Sun, 14 Dec 2025 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/yow-2025/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/yow-2025/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/yow-2025/cover.jpg" width="4032" height="3024" />
        
        
        <category>conferences</category>
        
        <category>review</category>
        
        
        <category>Miscellaneous</category>
        
      </item>
    
      <item>
        <title>Yet another Rust ownership tutorial</title>
        <description>One of the most important concepts to master in Rust is ownership and borrowing. Tons and tons of articles are solely dedicated to this narrow subject. This one tries to explain the concept with examples. I hope it helps you.     Ownership is a set of rules that govern how a Rust program manages memory. All programs have to manage the way they use a computer’s memory while running.</description>
        <pubDate>Sun, 07 Dec 2025 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/yet-another-rust-ownership-tutorial/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/yet-another-rust-ownership-tutorial/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/yet-another-rust-ownership-tutorial/cover.jpg" width="1792" height="1024" />
        
        
        <category>rust</category>
        
        
        <category>Development</category>
        
      </item>
    
      <item>
        <title>My second Cloudflare Tunnel</title>
        <description>I decided to stop using Twitter, but for my own content and supporting Ukraine against its barbarian invaders, I understood the contemporary media landscape was quite fragmented. I bet on Mastodon, Bluesky, and LinkedIn. My flow is the following: when I read a piece I find interesting, I schedule it for publication.</description>
        <pubDate>Sun, 30 Nov 2025 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/second-cloudflare-tunnel/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/second-cloudflare-tunnel/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/second-cloudflare-tunnel/cover.jpg" width="1792" height="1024" />
        
        
        <category>cloudflare</category>
        
        <category>cloudflare tunnel</category>
        
        <category>otp</category>
        
        <category>authentication</category>
        
        
        <category>Technical</category>
        
      </item>
    
      <item>
        <title>My first real Rust project</title>
        <description>I have been learning Rust for a couple of years, and using it for pet projects and demos alike. Working for a JVM-heavy company, I thought it would be my fate forever. Last week, I had a nice surprise: I convinced my management that using Rust for a particular project was the right choice. It&amp;#8217;s not a huge project, but I want to describe my experience using Rust in a &apos;real&apos; project.   The project   Our main software platform has baked-in health sensors for monitoring.</description>
        <pubDate>Sun, 23 Nov 2025 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/first-real-rust-project/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/first-real-rust-project/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/first-real-rust-project/cover.jpg" width="1536" height="1024" />
        
        
        <category>rust</category>
        
        
        <category>Development</category>
        
      </item>
    
      <item>
        <title>Are you really wasting your time in Java without these 10 libraries?</title>
        <description>I recently read and shared You’re Wasting Time in Java Without These 10 Libraries. I commented on it a bit in my newsletter, but given the amount and intensity of reactions, I think a full-blown post is in order.</description>
        <pubDate>Sun, 16 Nov 2025 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/wasting-time-without-10-libraries/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/wasting-time-without-10-libraries/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/wasting-time-without-10-libraries/cover.jpg" width="1536" height="1024" />
        
        
        <category>libraries</category>
        
        <category>opinion</category>
        
        
        <category>Java</category>
        
      </item>
    
      <item>
        <title>XML Schema Validation 1.1 in Java</title>
        <description>This week, I received an interesting task: dusting off a legacy Java application. The application analyzes specific XML files in proprietary format. I know XML doesn&amp;#8217;t sound sexy to junior developers, but it has an amazing benefit. One can validate a file against a grammar. Such grammar is called an XSD, the acronym for XML Schema Definition. Fun fact: you write XSDs in XML.   In this post, I explain the problem, what I tried, and the final working solution.</description>
        <pubDate>Sun, 09 Nov 2025 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/xml-schema-validation-1-1/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/xml-schema-validation-1-1/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/xml-schema-validation-1-1/cover.jpg" width="1536" height="1024" />
        
        
        <category>xml</category>
        
        <category>xsd</category>
        
        <category>validation</category>
        
        <category>xerces</category>
        
        
        <category>Java</category>
        
      </item>
    
      <item>
        <title>Choosing a dependency</title>
        <description>Fun fact, I thought I had already written this post, but when I wanted to reference it, I found out that I didn&amp;#8217;t. In this post, I&amp;#8217;d like to describe my approach when choosing a dependency. I&amp;#8217;ll first define what I mean by dependency in the context of this post. Then, I&amp;#8217;ll list a grid of several criteria to analyze possible dependencies with.   What is a dependency?</description>
        <pubDate>Sun, 02 Nov 2025 00:00:00 +0000</pubDate>
        <link>https://blog.frankel.ch/choosing-dependency/</link>
        <guid isPermaLink="true">https://blog.frankel.ch/choosing-dependency/</guid>
        



        <media:content url="https://blog.frankel.ch/assets/resources/choosing-dependency/cover.jpg" width="1536" height="1024" />
        
        
        <category>software engineering</category>
        
        <category>dependency</category>
        
        
        <category>Development</category>
        
      </item>
    
  </channel>
</rss>
