<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>morling.dev -- Blog</title>
    <link>https://www.morling.dev/blog/</link>
    <description>Recent content in Blogs on Gunnar Morling</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <copyright>© 2019 - 2026 Gunnar Morling</copyright>
    <lastBuildDate>Sun, 31 May 2026 21:36:00 +0100</lastBuildDate>
    
	<atom:link href="https://www.morling.dev/blog/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Improved Column Reader API, First Cut of Geospatial Support: Hardwood 1.0.0.CR1 Is Available</title>
      <link>https://www.morling.dev/blog/improved-column-reader-api-geospatial-support-hardwood-1-0-0-cr1-available/</link>
      <pubDate>Sun, 31 May 2026 21:36:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/improved-column-reader-api-geospatial-support-hardwood-1-0-0-cr1-available/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_reworked_columnreader_api&#34;&gt;Reworked ColumnReader API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_geospatial_support&#34;&gt;Geospatial Support&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_documentation_overhaul&#34;&gt;Documentation Overhaul&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_further_fixes_and_improvements&#34;&gt;Further Fixes and Improvements&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;I am happy to announce the release of &lt;a href=&#34;https://hardwood.dev/1.0.0.CR1/&#34;&gt;Hardwood 1.0.0.CR1&lt;/a&gt;!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;This first candidate release of Hardwood 1.0 brings a substantially improved API for columnar access to Apache Parquet files,
initial support for Parquet’s &lt;code&gt;GEOMETRY&lt;/code&gt;/&lt;code&gt;GEOGRAPHY&lt;/code&gt; column types, and many other improvements to the core library as well as the Hardwood CLI.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>VARIANT Support, Interactive Parquet File TUI: Hardwood 1.0.0.Beta2 Is Out</title>
      <link>https://www.morling.dev/blog/variant-support-interactive-parquet-file-tui-hardwood-1-0-0-beta2-is-out/</link>
      <pubDate>Wed, 29 Apr 2026 18:45:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/variant-support-interactive-parquet-file-tui-hardwood-1-0-0-beta2-is-out/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_variant_support&#34;&gt;VARIANT Support&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_hardwood_cli_tui&#34;&gt;Hardwood CLI TUI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_unified_reader_api&#34;&gt;Unified Reader API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_performance_improvements&#34;&gt;Performance Improvements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_wrapping_up&#34;&gt;Wrapping Up&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;I am happy to announce the release of Hardwood 1.0.0.Beta2!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;The latest version of this &lt;a href=&#34;https://hardwood.dev&#34;&gt;new parser for Apache Parquet&lt;/a&gt; comes with support for &lt;code&gt;VARIANT&lt;/code&gt; columns,
an interactive text-based UI (TUI) for examining and analysing the structure of Parquet files,
significantly improved performance, more efficient reading of files from object storage, and much more.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Hardwood Reaches Beta: S3, Predicate Push-Down, CLI, and More</title>
      <link>https://www.morling.dev/blog/hardwood-reaches-beta-s3-predicate-push-down-cli/</link>
      <pubDate>Thu, 02 Apr 2026 19:20:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/hardwood-reaches-beta-s3-predicate-push-down-cli/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_s3_backend&#34;&gt;S3 Backend&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_predicate_push_down&#34;&gt;Predicate Push-Down&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_avro_bindings&#34;&gt;Avro Bindings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_hardwood_cli&#34;&gt;hardwood-cli&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_wrapping_up&#34;&gt;Wrapping Up&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;I am pleased to announce the release of Hardwood 1.0.0.Beta1!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/hardwood-hq/hardwood&#34;&gt;Hardwood&lt;/a&gt; is a new parser for Apache Parquet, optimized for minimal dependencies and great performance.
Since the project’s initial release just &lt;a href=&#34;https://www.morling.dev/blog/hardwood-new-parser-for-apache-parquet/&#34;&gt;a few weeks back&lt;/a&gt;, a small yet very active community has come together and evolved Hardwood significantly.
Today, we are shipping an S3 backend, allowing to parse files directly from object storage,
predicate pushdown for both local and remote files, Avro bindings, a CLI for inspecting Parquet files, and much more.
We’re also excited to launch a website for the project, &lt;a href=&#34;https://hardwood.dev&#34;&gt;hardwood.dev&lt;/a&gt;, which contains the documentation and API reference.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Let’s dig in.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Hardwood: A New Parser for Apache Parquet</title>
      <link>https://www.morling.dev/blog/hardwood-new-parser-for-apache-parquet/</link>
      <pubDate>Thu, 26 Feb 2026 14:30:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/hardwood-new-parser-for-apache-parquet/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_why_hardwood&#34;&gt;Why Hardwood?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_hello_hardwood&#34;&gt;Hello, Hardwood!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_parsing_performance&#34;&gt;Parsing Performance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_built_with_ai_not_by_ai&#34;&gt;Built With AI, Not By AI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_whats_next&#34;&gt;What’s Next?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Today, it’s my great pleasure to announce the first public release of Hardwood, a new parser for the Apache Parquet file format, optimized for minimal dependencies and great performance.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/hardwood-hq/hardwood&#34;&gt;Hardwood&lt;/a&gt; is open-source (Apache License 2.0) and supports Java 21 or newer. You can grab it from &lt;a href=&#34;https://central.sonatype.com/search?q=hardwood&amp;amp;namespace=dev.hardwood&#34;&gt;Maven Central&lt;/a&gt; and start parsing your Parquet files with ease and efficiency.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>You Gotta Push If You Wanna Pull</title>
      <link>https://www.morling.dev/blog/you-gotta-push-if-you-wanna-pull/</link>
      <pubDate>Sun, 07 Dec 2025 10:05:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/you-gotta-push-if-you-wanna-pull/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_materialized_views&#34;&gt;Materialized Views&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_embracing_data_duplication&#34;&gt;Embracing Data Duplication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_streams_for_machines_tables_for_humans&#34;&gt;Streams for machines, tables for humans&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Historically, data management systems have been built around the notion of &lt;em&gt;pull queries&lt;/em&gt;: users query data which, for instance, is stored in tables in an RDBMS, Parquet files in a data lake, or a full-text index in Elasticsearch. When a user issues a query, the engine will produce the result set at that point in time by churning through the data set and finding all matching records (oftentimes sped up by utilizing indexes).&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>On Idempotency Keys</title>
      <link>https://www.morling.dev/blog/on-idempotency-keys/</link>
      <pubDate>Tue, 25 Nov 2025 13:10:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/on-idempotency-keys/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_uuids&#34;&gt;UUIDs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_monotonically_increasing_sequences&#34;&gt;Monotonically Increasing Sequences&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_deriving_idempotency_keys_from_the_transaction_log&#34;&gt;Deriving Idempotency Keys From the Transaction Log&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_discussion&#34;&gt;Discussion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;In distributed systems, there’s a common understanding that it is not possible to guarantee exactly-once delivery of messages.
&lt;a href=&#34;https://medium.com/@jaykreps/exactly-once-support-in-apache-kafka-55e1fdd0a35f&#34;&gt;What is possible&lt;/a&gt; though is &lt;em&gt;exactly-once processing&lt;/em&gt;. By adding a unique idempotency key to each message, you can enable consumers to recognize and ignore duplicate messages, i.e. messages which they have received and successfully processed before.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Building a Durable Execution Engine With SQLite</title>
      <link>https://www.morling.dev/blog/building-durable-execution-engine-with-sqlite/</link>
      <pubDate>Thu, 20 Nov 2025 13:10:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/building-durable-execution-engine-with-sqlite/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_hello_persistasaurus&#34;&gt;Hello Persistasaurus!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_capturing_execution_state&#34;&gt;Capturing Execution State&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_delayed_executions&#34;&gt;Delayed Executions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_human_interaction&#34;&gt;Human Interaction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_managing_state&#34;&gt;Managing State&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_wrapping_up&#34;&gt;Wrapping Up&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Lately, there has been a lot of excitement around Durable Execution (DE) engines.
The basic idea of DE is to take (potentially long-running) multi-step workflows,
such as processing a purchase order or a user sign-up,
and make their individual steps persistent.
If a flow gets interrupted while running, for instance due to a machine failure,
the DE engine can resume it from the last successfully executed step and drive it to completion.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>&#34;You Don&#39;t Need Kafka, Just Use Postgres&#34; Considered Harmful</title>
      <link>https://www.morling.dev/blog/you-dont-need-kafka-just-use-postgres-considered-harmful/</link>
      <pubDate>Mon, 03 Nov 2025 18:02:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/you-dont-need-kafka-just-use-postgres-considered-harmful/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Looking to make it to the front page of HackerNews? Then writing a post arguing that &amp;#34;Postgres is enough&amp;#34;, or why &amp;#34;you don’t need Kafka at your scale&amp;#34; is a pretty failsafe way of achieving exactly that. No matter how often it has been discussed before, this topic is always doing well. And sure, what’s not to love about that? I mean, it has it all: Postgres, everybody’s most favorite RDBMS—​check! Keeping things lean and easy—​sure, count me in! A somewhat spicy take—​bring it on!&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Let&#39;s Take a Look at... Lower Java Tail Latencies With ZGC</title>
      <link>https://www.morling.dev/blog/lower-java-tail-latencies-with-zgc/</link>
      <pubDate>Wed, 17 Sep 2025 17:09:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/lower-java-tail-latencies-with-zgc/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_zgc_allocation_stalls&#34;&gt;ZGC Allocation Stalls&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_summary&#34;&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph teaser&#34;&gt;
&lt;p&gt;In the &amp;#34;Let’s Take a Look at…​!&amp;#34; blog series I am exploring interesting projects, developments and technologies in the data and streaming space. This can be KIPs and FLIPs, open-source projects, services, relevant improvements to Java and the JVM, and more. The idea is to get some hands-on experience, learn about potential use cases and applications, and understand the trade-offs involved. If you think there’s a specific subject I should take a look at, let me know in the comments below.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Java 25 &lt;a href=&#34;https://www.oracle.com/news/announcement/oracle-releases-java-25-2025-09-16/&#34;&gt;was released&lt;/a&gt; earlier this week,
and it is the first Java release with long-term support (LTS) which ships with Generational ZGC as the one (and only) flavor of the ZGC garbage collector.
&lt;a href=&#34;https://openjdk.org/jeps/333&#34;&gt;ZGC&lt;/a&gt; itself is a relatively new concurrent collector, originally added in Java 11.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Postgres Replication Slots: Confirmed Flush LSN vs. Restart LSN</title>
      <link>https://www.morling.dev/blog/postgres-replication-slots-confirmed-flush-lsn-vs-restart-lsn/</link>
      <pubDate>Tue, 05 Aug 2025 13:55:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/postgres-replication-slots-confirmed-flush-lsn-vs-restart-lsn/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_confirmed_flush_sn_tracking_consumer_progress&#34;&gt;confirmed_flush_sn: Tracking Consumer Progress&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_restart_lsn_handling_concurrent_transactions&#34;&gt;restart_lsn: Handling Concurrent Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_mid_transaction_recovery&#34;&gt;Mid-Transaction Recovery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_looking_forward_streaming_in_progress_transactions&#34;&gt;Looking Forward: Streaming In-Progress Transactions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Replication slots in Postgres keep track of how far consumers have read a replication stream.
After a restart, consumers—​either Postgres read replicas or external tools for change data capture (CDC), like &lt;a href=&#34;https://debezium.io/&#34;&gt;Debezium&lt;/a&gt;—resume reading from the last confirmed log sequence number (LSN) of their replication slot. The slot prevents the database from disposing of required log segments, allowing safe resumption after downtime.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;In this post, we are going to take a look at why Postgres replication slots don’t have one but two LSN-related attributes: &lt;code&gt;restart_lsn&lt;/code&gt; and &lt;code&gt;confirmed_flush_lsn&lt;/code&gt;.
Understanding the difference between the two is crucial for troubleshooting replication issues, optimizing WAL retention, and avoiding common pitfalls in production environments.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Converting Future to CompletableFuture With Java Virtual Threads</title>
      <link>https://www.morling.dev/blog/future-to-completablefuture-with-java-virtual-threads/</link>
      <pubDate>Thu, 17 Jul 2025 10:25:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/future-to-completablefuture-with-java-virtual-threads/</guid>
      <description>&lt;div class=&#34;paragraph teaser&#34;&gt;
&lt;p&gt;This post explores how virtual threads in Java 21+ provide an elegant solution for converting legacy &lt;code&gt;Future&lt;/code&gt; objects into &lt;code&gt;CompletableFuture&lt;/code&gt; instances.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Since Java 8, the &lt;a href=&#34;https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/CompletableFuture.html&#34;&gt;&lt;code&gt;CompletableFuture&lt;/code&gt;&lt;/a&gt; API provides a convenient way for performing asynchronous operations in a functional, composable way.
This makes it very simple to call some long-running methods—​for instance involving external I/O—​asynchronously and process each result as soon as it is available, without blocking on any threads:&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Mastering Postgres Replication Slots: Preventing WAL Bloat and Other Production Issues</title>
      <link>https://www.morling.dev/blog/mastering-postgres-replication-slots/</link>
      <pubDate>Tue, 08 Jul 2025 13:55:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/mastering-postgres-replication-slots/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_use_the_pgoutput_logical_decoding_output_plug_in&#34;&gt;Use the pgoutput Logical Decoding Output Plug-in&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_define_a_maximum_replication_slot_size&#34;&gt;Define a Maximum Replication Slot Size&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_enable_heartbeats&#34;&gt;Enable Heartbeats&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_use_table_level_publications&#34;&gt;Use Table-level Publications&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_use_column_and_row_filters&#34;&gt;Use Column and Row Filters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_enable_fail_over_slots&#34;&gt;Enable Fail-Over Slots&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_consider_using_replica_identity_full&#34;&gt;Consider Using Replica Identity FULL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_monitor_monitor_monitor&#34;&gt;Monitor, Monitor, Monitor!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_drop_unused_replication_slots&#34;&gt;Drop Unused Replication Slots&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_summary&#34;&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Over the last couple of years, I’ve helped dozens of users and organizations to build Change Data Capture (CDC) pipelines for their Postgres databases. A key concern in that process is setting up and managing replication slots, which are Postgres&amp;#39; mechanism for making sure that any segments of the write-ahead log (WAL) of the database are kept around until they have been processed by registered replication consumers.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;When not being careful, a replication slot may cause unduly large amounts of WAL segments to be retained by the database. This post describes best practices helping to prevent this and other issues, discussing aspects like heartbeats, replication slot failover, monitoring, the management of Postgres publications, and more. While this is primarily based on my experience of using replication slots via &lt;a href=&#34;https://debezium.io/documentation/reference/stable/connectors/postgresql.html&#34;&gt;Debezium’s Postgres connector&lt;/a&gt;, the principles are generally applicable and are worth considering also when using other CDC tools for Postgres based on logical replication.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>This AI Agent Should Have Been a SQL Query</title>
      <link>https://www.morling.dev/blog/this-ai-agent-should-have-been-sql-query/</link>
      <pubDate>Wed, 18 Jun 2025 15:30:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/this-ai-agent-should-have-been-sql-query/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_agents_need_to_interact_with_llms&#34;&gt;Agents Need to Interact With LLMs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_agents_should_be_event_driven&#34;&gt;Agents Should Be Event-Driven&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_agents_need_context&#34;&gt;Agents Need Context&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_agents_require_memory&#34;&gt;Agents Require Memory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_when_sql_is_not_enough&#34;&gt;When SQL Is Not Enough&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_parting_thoughts&#34;&gt;Parting Thoughts&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph teaser&#34;&gt;
&lt;p&gt;AI Agents have improved in leaps and bounds in recent times, moving beyond simple chatbots to sophisticated, autonomous systems. This post explores a novel approach to building agentic systems: using the power of streaming SQL queries. Discover how platforms like Apache Flink can transform the development of AI Agents, offering benefits in consistency, scalability, and developer experience.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Backfilling Postgres TOAST Columns in Debezium Data Change Events</title>
      <link>https://www.morling.dev/blog/backfilling-postgres-toast-columns-debezium-change-events/</link>
      <pubDate>Mon, 26 May 2025 16:40:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/backfilling-postgres-toast-columns-debezium-change-events/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_debezium_reselect_postprocessor&#34;&gt;Debezium Reselect Postprocessor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_flink_datastream_api&#34;&gt;Flink DataStream API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_flink_sql_with_over_aggregation&#34;&gt;Flink SQL With OVER Aggregation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_flink_process_table_functions&#34;&gt;Flink Process Table Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_summary_and_discussion&#34;&gt;Summary and Discussion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph teaser&#34;&gt;
&lt;p&gt;Postgres logical replication, while powerful for capturing real-time data changes, presents challenges with TOAST columns,
whose values can be absent from data change events in specific situations.
This post discusses how Debezium addresses this through its built-in reselect post processor,
then explores more robust solutions leveraging Apache Flink’s capabilities for stateful stream processing,
including Flink SQL and the brand-new process table functions (PTFs) in Flink 2.1.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>&#34;Streaming vs. Batch&#34; Is a Wrong Dichotomy, and I Think It&#39;s Confusing</title>
      <link>https://www.morling.dev/blog/streaming-vs-batch-wrong-dichotomy/</link>
      <pubDate>Wed, 14 May 2025 10:10:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/streaming-vs-batch-wrong-dichotomy/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Often times, &amp;#34;Stream vs. Batch&amp;#34; is discussed as if it’s one &lt;em&gt;or&lt;/em&gt; the other, but to me this does not make that much sense really.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>What If We Could Rebuild Kafka From Scratch?</title>
      <link>https://www.morling.dev/blog/what-if-we-could-rebuild-kafka-from-scratch/</link>
      <pubDate>Thu, 24 Apr 2025 16:25:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/what-if-we-could-rebuild-kafka-from-scratch/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;The last few days I spent some time digging into the recently announced &lt;a href=&#34;https://cwiki.apache.org/confluence/display/KAFKA/KIP-1150%3A+Diskless+Topics&#34;&gt;KIP-1150&lt;/a&gt; (&amp;#34;Diskless Kafka&amp;#34;), as well &lt;a href=&#34;https://github.com/AutoMQ/automq&#34;&gt;AutoMQ’s Kafka fork&lt;/a&gt;, tightly integrating Apache Kafka and object storage, such as S3. Following the example set by WarpStream, these projects aim to substantially improve the experience of using Kafka in cloud environments, providing better elasticity, drastically reducing cost, and paving the way towards native lakehouse integration.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;This got me thinking, if we were to start all over and develop a durable cloud-native event log from scratch—​Kafka.next if you will—​which traits and characteristics would be desirable for this to have? Separating storage and compute and object store support would be table stakes, but what else should be there? Having used Kafka for many years for building event-driven applications as well as for running realtime ETL and change data capture pipelines, here’s my personal wishlist:&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>A Deep Dive Into Ingesting Debezium Events From Kafka With Flink SQL</title>
      <link>https://www.morling.dev/blog/ingesting-debezium-events-from-kafka-with-flink-sql/</link>
      <pubDate>Wed, 16 Apr 2025 11:25:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/ingesting-debezium-events-from-kafka-with-flink-sql/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_flink_sql_connectors_for_apache_kafka&#34;&gt;Flink SQL Connectors for Apache Kafka&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_the_apache_kafka_sql_connector_in_append_only_mode&#34;&gt;The Apache Kafka SQL Connector in Append-Only Mode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_the_apache_kafka_sql_connector_as_a_changelog_source&#34;&gt;The Apache Kafka SQL Connector As a Changelog Source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_the_upsert_kafka_sql_connector&#34;&gt;The Upsert Kafka SQL Connector&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_summary&#34;&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Over the years, I’ve spoken quite a bit about the use cases for processing &lt;a href=&#34;https://2023.javazone.no/program/355869fa-5aa0-43a7-abd2-7c5250e10bcd&#34;&gt;Debezium data change events with Apache Flink&lt;/a&gt;,
such as metadata enrichment, building denormalized data views, and creating data contracts for your CDC streams.
One detail I haven’t covered in depth so far is how to actually ingest Debezium change events from a Kafka topic into Flink,
in particular via Flink SQL.
Several connectors and data formats exist for this, which can make things somewhat confusing at first.
So let’s dive into the different options and the considerations around them!&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Building a Native Binary for Apache Kafka on macOS</title>
      <link>https://www.morling.dev/blog/building-native-binary-for-apache-kafka-macos/</link>
      <pubDate>Mon, 07 Apr 2025 12:25:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/building-native-binary-for-apache-kafka-macos/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_kip_974_docker_image_for_graalvm_based_native_kafka_broker&#34;&gt;KIP-974: Docker Image for GraalVM based Native Kafka Broker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph teaser&#34;&gt;
&lt;p&gt;With help of the GraalVM configuration developed for KIP-974 (Docker Image for GraalVM based Native Kafka Broker),
you can easily build a self-contained native binary for Apache Kafka.
Read on to learn how you can build a native Kafka executable yourself,
starting in milli-seconds, making it a perfect fit for development and testing purposes.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;When I wrote about &lt;a href=&#34;https://www.morling.dev/blog/jep-483-aot-class-loading-linking/&#34;&gt;ahead-of-time class loading and linking in Java 24&lt;/a&gt; recently,
I also published the start-up time for Apache Kafka as a native binary for comparison.
This was done via Docker, as there’s no pre-built native binary of Kafka available for the operating system I’m running on, macOS.
But there is a native Kafka container image, so this is what I chose for the sake of convenience.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Now, running in a container adds a little bit of overhead of course,
so it wasn’t a surprise when Thomas Würthinger, lead of the GraalVM project at Oracle,
&lt;a href=&#34;https://bsky.app/profile/thomaswue.dev/post/3lloypreatk2s&#34;&gt;brought up the question&lt;/a&gt; what the value would be when running Kafka natively on macOS.
Needless to say I can’t leave this kind of nice nerd snipe pass,
so I set out to learn how to build a native Kafka binary on macOS, using GraalVM.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Let&#39;s Take a Look at... JEP 483: Ahead-of-Time Class Loading &amp; Linking!</title>
      <link>https://www.morling.dev/blog/jep-483-aot-class-loading-linking/</link>
      <pubDate>Thu, 27 Mar 2025 14:00:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/jep-483-aot-class-loading-linking/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_building_an_aot_cache_for_apache_kafka&#34;&gt;Building an AOT Cache for Apache Kafka&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_aot_caching_with_apache_flink&#34;&gt;AOT Caching With Apache Flink&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_summary&#34;&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph teaser&#34;&gt;
&lt;p&gt;In the &amp;#34;Let’s Take a Look at…​!&amp;#34; blog series I am exploring interesting projects, developments and technologies in the data and streaming space. This can be KIPs and FLIPs, open-source projects, services, relevant improvements to Java and the JVM, and more. The idea is to get some hands-on experience, learn about potential use cases and applications, and understand the trade-offs involved. If you think there’s a specific subject I should take a look at, let me know in the comments below.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://openjdk.org/projects/jdk/24/&#34;&gt;Java 24&lt;/a&gt; got released last week,
and what a meaty release it is:
more than twenty Java Enhancement Proposals (JEPs) have been shipped,
including highlights such as compact object headers (&lt;a href=&#34;https://openjdk.org/jeps/450&#34;&gt;JEP 450&lt;/a&gt;, I hope to spend some time diving into that one some time soon),
a new class-file API (&lt;a href=&#34;https://openjdk.org/jeps/484&#34;&gt;JEP 484&lt;/a&gt;),
and more flexible constructor bodies (&lt;a href=&#34;https://openjdk.org/jeps/492&#34;&gt;JEP 492&lt;/a&gt;, third preview).
One other JEP which might fly a bit under the radar is &lt;a href=&#34;https://openjdk.org/jeps/483&#34;&gt;JEP 483&lt;/a&gt; (&amp;#34;Ahead-of-Time Class Loading &amp;amp; Linking&amp;#34;).
It promises to reduce the start-up time of Java applications without requiring any modifications to the application itself,
what’s not to be liked about that?
Let’s take a closer look!&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>The Synchrony Budget</title>
      <link>https://www.morling.dev/blog/the-synchrony-budget/</link>
      <pubDate>Tue, 18 Mar 2025 14:00:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/the-synchrony-budget/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;For building a system of distributed services, one concept I think is very valuable to keep in mind is what I call the &lt;em&gt;synchrony budget&lt;/em&gt;:
as much as possible, a service should minimize the number of synchronous requests which it makes to other services.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Let&#39;s Take a Look at... KIP-932: Queues for Kafka!</title>
      <link>https://www.morling.dev/blog/kip-932-queues-for-kafka/</link>
      <pubDate>Wed, 05 Mar 2025 12:35:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/kip-932-queues-for-kafka/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_towards_queue_support_in_kafkaintroducing_share_groups&#34;&gt;Towards Queue Support in Kafka—​Introducing Share Groups&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_share_groups_in_action&#34;&gt;Share Groups in Action&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_retry_behavior_and_state_management&#34;&gt;Retry Behavior and State Management&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_share_group_state_persistence&#34;&gt;Share Group State Persistence&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_summary_and_outlook&#34;&gt;Summary and Outlook&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph teaser&#34;&gt;
&lt;p&gt;In the &amp;#34;Let’s Take a Look at…​!&amp;#34; blog series I am going to explore interesting projects, developments and technologies in the data and streaming space. This can be KIPs and FLIPs, open-source projects, services, and more. The idea is to get some hands-on experience, learn about potential use cases and applications, and understand the trade-offs involved. If you think there’s a specific subject I should take a look at, let me know in the comments below!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;span class=&#34;image&#34;&gt;&lt;img src=&#34;https://www.morling.dev/images/kip_932_1.jpg&#34; alt=&#34;kip 932 1&#34; width=&#34;333px&#34;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;That guy above? Yep, that’s me, whenever someone says &amp;#34;Kafka queue&amp;#34;. Because, that’s not what Apache Kafka is. At its core, Kafka is a distributed durable event log. Producers write events to a topic, organized in partitions which are distributed amongst the brokers of a Kafka cluster. Consumers, organized in groups, divide the partitions they process amongst themselves, so that each partition of a topic is read by exactly one consumer in the group.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Get Running with Apache Flink on Kubernetes, part 2 of 2</title>
      <link>https://www.morling.dev/blog/get-running-with-apache-flink-on-kubernetes-2/</link>
      <pubDate>Tue, 28 Jan 2025 00:00:00 +0000</pubDate>
      
      <guid>https://www.morling.dev/blog/get-running-with-apache-flink-on-kubernetes-2/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_fault_tolerance_and_high_availability&#34;&gt;Fault Tolerance and High Availability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_manually_triggering_savepoints&#34;&gt;Manually Triggering Savepoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_observability&#34;&gt;Observability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_bonus_managing_flink_jobs_with_the_heimdall_ui&#34;&gt;Bonus: Managing Flink Jobs With the Heimdall UI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_summary_and_discussion&#34;&gt;Summary and Discussion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;em&gt;This post originally appeared on the &lt;a href=&#34;https://www.decodable.co/blog/get-running-with-apache-flink-on-kubernetes-2&#34;&gt;Decodable blog&lt;/a&gt;. All rights reserved.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Welcome back to this two-part blog post series about running Apache Flink on Kubernetes, using the Flink Kubernetes operator.
In &lt;a href=&#34;https://www.morling.dev/blog/get-running-with-apache-flink-on-kubernetes-1&#34;&gt;part one&lt;/a&gt;, we discussed installation and setup of the operator, different deployment types, how to deploy Flink jobs using custom Kubernetes resources, and how to create container images for your own Flink jobs.
In this part, we’ll focus on aspects such as fault tolerance and high availability of your Flink jobs running on Kubernetes, savepoint management, observability, and more.
You can find the complete source code for all the examples shown in this series in the Decodable &lt;a href=&#34;https://github.com/decodableco/examples/blob/main/flink-on-kubernetes/&#34;&gt;examples repository&lt;/a&gt; on GitHub: on GitHub.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Get Running with Apache Flink on Kubernetes, part 1 of 2</title>
      <link>https://www.morling.dev/blog/get-running-with-apache-flink-on-kubernetes-1/</link>
      <pubDate>Tue, 21 Jan 2025 00:00:00 +0000</pubDate>
      
      <guid>https://www.morling.dev/blog/get-running-with-apache-flink-on-kubernetes-1/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_installation_and_setup&#34;&gt;Installation and Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_deployment_types&#34;&gt;Deployment Types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_deploying_your_first_flink_job_on_kubernetes&#34;&gt;Deploying Your First Flink Job on Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_building_custom_job_images&#34;&gt;Building Custom Job Images&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;em&gt;This post originally appeared on the &lt;a href=&#34;https://www.decodable.co/blog/get-running-with-apache-flink-on-kubernetes-1&#34;&gt;Decodable blog&lt;/a&gt;. All rights reserved.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Kubernetes is a widely used deployment platform for Apache Flink.
While Flink has had native support for Kubernetes for quite a while, it is in particular the operator pattern which makes deploying Flink jobs onto Kubernetes clusters a compelling option: you define jobs in a declarative resource, and a control loop running in a component called a Kubernetes operator takes care of provisioning and maintaining (e.g.
scaling, updating) all the required resources.
Automation is the keyword here, significantly reducing the manual effort required for running Flink jobs in production.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Failover Replication Slots with Postgres 17</title>
      <link>https://www.morling.dev/blog/failover-replication-slots-with-postgres-17/</link>
      <pubDate>Tue, 03 Dec 2024 00:00:00 +0000</pubDate>
      
      <guid>https://www.morling.dev/blog/failover-replication-slots-with-postgres-17/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_hello_failover_slots&#34;&gt;Hello, Failover Slots!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_failover_slots_in_decodable&#34;&gt;Failover Slots in Decodable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_wrapping_up&#34;&gt;Wrapping Up&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;em&gt;This post originally appeared on the &lt;a href=&#34;https://www.decodable.co/blog/failover-replication-slots-with-postgres-17&#34;&gt;Decodable blog&lt;/a&gt;. All rights reserved.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Postgres read replicas are commonly used not only to distribute query load amongst multiple nodes, but also to ensure high availability (HA) of the database.
If the primary node of a Postgres cluster fails, a read replica can be promoted to be the new primary, processing write (and read) requests from thereon.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Thoughts On Moving Debezium to the Commonhaus Foundation</title>
      <link>https://www.morling.dev/blog/thoughts-on-moving-debezium-to-commonhaus-foundation/</link>
      <pubDate>Wed, 27 Nov 2024 17:25:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/thoughts-on-moving-debezium-to-commonhaus-foundation/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;If you are following the news around Debezium—​an open-source platform for Change Data Capture (CDC) for a variety of databases—​you may have seen the announcement that the project is in the process of &lt;a href=&#34;https://debezium.io/blog/2024/11/04/debezium-moving-to-commonhaus/&#34;&gt;moving to the Commonhaus Foundation&lt;/a&gt;. I think this is excellent news for the Debezium project, its community, and open-source CDC at large. In this post I’d like to share some more context on why I am so excited about this development.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Building OpenJDK From Source On macOS</title>
      <link>https://www.morling.dev/blog/building-openjdk-from-source-on-macos/</link>
      <pubDate>Sat, 16 Nov 2024 15:25:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/building-openjdk-from-source-on-macos/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Every now and then, it can come in very handy to build OpenJDK from source yourself,
for instance if you want to explore a feature which is under development on a branch for which no builds are published.
For some reason I always thought that building OpenJDK is a very complex processing,
requiring the installation of arcane tool chains etc.
But as it turns out, this actually not true:
the project does a great job of documenting what’s needed and only a few steps are necessary to build your very own JDK.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Revisiting the Outbox Pattern</title>
      <link>https://www.morling.dev/blog/revisiting-the-outbox-pattern/</link>
      <pubDate>Thu, 31 Oct 2024 00:00:00 +0000</pubDate>
      
      <guid>https://www.morling.dev/blog/revisiting-the-outbox-pattern/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_recap_whats_the_outbox_pattern&#34;&gt;Recap: What’s The Outbox Pattern?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_implementation_considerations&#34;&gt;Implementation Considerations&lt;/a&gt;
&lt;ul class=&#34;sectlevel2&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_polling_vs_log_based_cdc&#34;&gt;Polling vs. Log-Based CDC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_the_outbox_table&#34;&gt;The Outbox Table&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_pg_logical_emit_message&#34;&gt;pg_logical_emit_message()&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_format_considerations&#34;&gt;Format Considerations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_backfills&#34;&gt;Backfills&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_idempotency_for_consumers&#34;&gt;Idempotency for Consumers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_criticisms_of_the_outbox_pattern&#34;&gt;Criticisms of the Outbox pattern&lt;/a&gt;
&lt;ul class=&#34;sectlevel2&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_database_overhead&#34;&gt;Database Overhead&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_complexity&#34;&gt;Complexity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_latency&#34;&gt;Latency&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_discussion&#34;&gt;Discussion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_alternatives_to_the_outbox_pattern&#34;&gt;Alternatives to the Outbox Pattern&lt;/a&gt;
&lt;ul class=&#34;sectlevel2&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_dapr&#34;&gt;Dapr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_read_yourself&#34;&gt;Read-yourself&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_stream_processing_on_raw_change_event_streams&#34;&gt;Stream Processing on &amp;#34;Raw&amp;#34; Change Event Streams&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_2pc&#34;&gt;2PC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_durable_execution&#34;&gt;Durable Execution&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_summary&#34;&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;em&gt;This post originally appeared on the &lt;a href=&#34;https://www.decodable.co/blog/revisiting-the-outbox-pattern&#34;&gt;Decodable blog&lt;/a&gt;. All rights reserved.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Over the last few years, the outbox pattern has become a common solution for implementing data exchange flows between microservices.
It allows services to safely and reliably update their own local datastore and at the same time send out notifications to other services via data streaming platforms such as Apache Kafka.
But time isn’t standing still: people ask about disadvantages of the pattern (&lt;em&gt;is the database becoming a bottleneck?&lt;/em&gt;), alternative solutions such as &amp;#34;listen-to-yourself&amp;#34; have been proposed, Kafka is about to get support for participating in 2-phase commit (2PC) transactions, and more.
It’s time to take another look at the outbox pattern, what it is and how to implement it, whether it’s still relevant in 2024, and which alternatives exist!&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>CDC Is a Feature Not a Product</title>
      <link>https://www.morling.dev/blog/cdc-is-a-feature-not-a-product/</link>
      <pubDate>Fri, 18 Oct 2024 15:55:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/cdc-is-a-feature-not-a-product/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;During and after my time as the lead of &lt;a href=&#34;https://debezium.io/&#34;&gt;Debezium&lt;/a&gt;,
a widely used open-source platform for Change Data Capture (CDC) for a variety of database,
I got repeatedly asked whether I’d be interested in creating a company around CDC.
VCs, including wellknown household names, did and do reach out to me,
pitching this idea.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>How I Am Setting Up VMs On Hetzner Cloud</title>
      <link>https://www.morling.dev/blog/how-i-am-setting-up-vms-on-hetzner-cloud/</link>
      <pubDate>Sun, 06 Oct 2024 20:25:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/how-i-am-setting-up-vms-on-hetzner-cloud/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_creating_instances&#34;&gt;Creating Instances&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_configuring_ssh&#34;&gt;Configuring SSH&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_provisioning_software&#34;&gt;Provisioning Software&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_try_it_out_yourself&#34;&gt;Try It Out Yourself&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Whenever I’ve need a Linux box for some testing or experimentation,
or projects like the &lt;a href=&#34;https://www.morling.dev/blog/1brc-results-are-in/&#34;&gt;One Billion Row Challenge&lt;/a&gt; a few months back,
my go-to solution is &lt;a href=&#34;https://www.hetzner.com/&#34;&gt;Hetzner Online&lt;/a&gt;, a data center operator here in Europe.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Their prices for VMs are unbeatable, starting with 3,92 €/month for two shared vCPUs (either x64 or AArch64), four GB of RAM, and 20 TB of network traffic
(these are prices for their German data centers, they vary between regions).
four dedicated cores with 16 GB, e.g. for running a small web server, will cost you 28.55 €/month.
Getting a box with similar specs on AWS would set you back a multiple of that, with the (outbound) network cost being the largest chunk.
So it’s not a big surprise that more and more people realize the advantages of this offering,
most notably Ruby on Rails creator &lt;a href=&#34;https://x.com/dhh/&#34;&gt;David Heinemeier Hansson&lt;/a&gt;,
who has been singing the praise for Hetzner’s dedicated servers, but also their VM instances, quite a bit on &lt;a href=&#34;https://x.com/search?q=from%3Adhh%20hetzner&amp;amp;src=typed_query&amp;amp;f=live&#34;&gt;Twitter&lt;/a&gt; lately.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Leader Election With S3 Conditional Writes</title>
      <link>https://www.morling.dev/blog/leader-election-with-s3-conditional-writes/</link>
      <pubDate>Mon, 26 Aug 2024 09:15:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/leader-election-with-s3-conditional-writes/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_the_algorithm&#34;&gt;The Algorithm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_obtaining_the_lock&#34;&gt;Obtaining the Lock&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_expiring_a_lock&#34;&gt;Expiring a Lock&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_lock_validity&#34;&gt;Lock Validity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_fencing_off_zombies&#34;&gt;Fencing Off Zombies&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;In distributed systems, for instance when scaling out some workload to multiple compute nodes,
it is a common requirement to select a &lt;em&gt;leader&lt;/em&gt; for performing a given task:
only one of the nodes should process the records from a Kafka topic partition, write to a file system, call a remote API, etc.
Otherwise, multiple workers may end up doing the same task twice, overwriting each other’s data, and worse.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Shell Spell: Extracting and Propagating Multiple Values With jq</title>
      <link>https://www.morling.dev/blog/extracting-and-propagating-multiple-values-with-jq/</link>
      <pubDate>Sat, 06 Jul 2024 11:20:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/extracting-and-propagating-multiple-values-with-jq/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;In my day job at &lt;a href=&#34;https://www.decodable.co/&#34;&gt;Decodable&lt;/a&gt;,
I am currently working with Terraform to provision some cloud infrastructure for an upcoming hands-on lab.
Part of this set-up is a Postgres database on Amazon RDS,
which I am creating using the &lt;a href=&#34;https://developer.hashicorp.com/terraform/tutorials/aws/aws-rds&#34;&gt;Terraform AWS modules&lt;/a&gt;.
Now, once my database was up and running,
I wanted to extract two dynamically generated values from Terraform:
the random password created for the root user, and the database host URL.
On my way down the rabbit hole for finding a CLI command for doing this efficiently,
I learned a few interesting shell details which I’d like to share.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>A Zipping Gatherer</title>
      <link>https://www.morling.dev/blog/zipping-gatherer/</link>
      <pubDate>Mon, 18 Mar 2024 18:12:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/zipping-gatherer/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;The other day, I was looking for means of &lt;a href=&#34;https://twitter.com/gunnarmorling/status/1764305703047438361&#34;&gt;zipping two Java streams&lt;/a&gt;:
connecting them element by element—​essentially a join based on stream offset position—​and emitting an output stream with the results.
Unfortunately, there is no &lt;code&gt;zip()&lt;/code&gt; method offered by the Java Streams API itself.
While it was considered for inclusion in early preview versions,
the method was removed before the API went GA with Java 8 and you have to resort to 3rd party libraries such as &lt;a href=&#34;https://guava.dev/releases/snapshot-jre/api/docs/com/google/common/collect/Streams.html#zip(java.util.stream.Stream,java.util.stream.Stream,java.util.function.BiFunction)&#34;&gt;Google Guava&lt;/a&gt; if you need this functionality.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>A Taxonomy Of Data Change Events</title>
      <link>https://www.morling.dev/blog/taxonomy-of-data-change-events/</link>
      <pubDate>Wed, 13 Mar 2024 00:00:00 +0000</pubDate>
      
      <guid>https://www.morling.dev/blog/taxonomy-of-data-change-events/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_full_events&#34;&gt;Full Events&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_delta_events&#34;&gt;Delta Events&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_id_only_events&#34;&gt;Id-only Events&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_change_event_metadata&#34;&gt;Change Event Metadata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_comparison&#34;&gt;Comparison&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;em&gt;This post originally appeared on the &lt;a href=&#34;https://www.decodable.co/blog/taxonomy-of-data-change-events&#34;&gt;Decodable blog&lt;/a&gt;. All rights reserved.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Data change events are at the core of Change Data Capture (CDC) solutions such as &lt;a href=&#34;https://debezium.io/&#34;&gt;Debezium&lt;/a&gt;.
They describe the changes made to a specific record in a database and allow event consumers to take action based on this information, enabling a wide range of &lt;a href=&#34;https://www.morling.dev/blog/cdc-use-cases&#34;&gt;use cases&lt;/a&gt;, such as real-time ETL (by propagating the updated data into downstream data stores such as data warehouses, analytics databases, or fulltext search indexes), microservices data exchange, or audit logging.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Last Updated Columns With Postgres</title>
      <link>https://www.morling.dev/blog/last-updated-columns-with-postgres/</link>
      <pubDate>Tue, 20 Feb 2024 09:15:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/last-updated-columns-with-postgres/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;In many applications it’s a requirement to keep track of when a record was created and updated the last time.
Often, this is implemented by having columns such as &lt;code&gt;created_at&lt;/code&gt; and &lt;code&gt;updated_at&lt;/code&gt; within each table.
To make things as simple as possible for application developers,
the database itself should take care of maintaining these values automatically when a record gets inserted or updated.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Filtering Process Output With tee</title>
      <link>https://www.morling.dev/blog/filtering-process-output-with-tee/</link>
      <pubDate>Sat, 10 Feb 2024 11:11:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/filtering-process-output-with-tee/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Recently I ran into a situation where it was necessary to capture the output of a Java process on the &lt;code&gt;stdout&lt;/code&gt; stream,
and at the same time a filtered subset of the output in a log file.
The former, so that the output gets picked up by the Kubernetes logging infrastructure.
The letter for further processing on our end:
we were looking to detect when the JVM stops due to an &lt;code&gt;OutOfMemoryError&lt;/code&gt;, passing on that information to some error classifier.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>1BRC—The Results Are In!</title>
      <link>https://www.morling.dev/blog/1brc-results-are-in/</link>
      <pubDate>Sun, 04 Feb 2024 16:34:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/1brc-results-are-in/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_results&#34;&gt;Results&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_bonus_result_32_cores_64_threads&#34;&gt;Bonus Result: 32 Cores, 64 Threads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_bonus_result_10k_key_set&#34;&gt;Bonus Result: 10K Key Set&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_thank_you&#34;&gt;Thank You!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_which_challenge_will_be_next&#34;&gt;Which Challenge Will Be Next?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Oh what a wild ride the last few weeks have been.
The &lt;a href=&#34;https://www.morling.dev/blog/one-billion-row-challenge/&#34;&gt;One Billion Row Challenge&lt;/a&gt; (1BRC for short),
something I had expected to be interesting to a dozen folks or so at best,
has gone kinda viral, with hundreds of people competing and engaging.
In Java, as intended, but also &lt;a href=&#34;https://github.com/gunnarmorling/1brc/discussions/categories/show-and-tell&#34;&gt;beyond&lt;/a&gt;:
folks implemented the challenge in languages such as Go, Rust, C/C++, C#, Fortran, or Erlang, as well databases (Postgres, Oracle, Snowflake, etc.), and tools like awk.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;It’s really incredible how far people have pushed the limits here.
Pull request by pull request, the execution times for solving the problem layed out in the challenge — aggregating random temperature values from a file with 1,000,000,000 rows — improved by two orders of magnitudes in comparison to the initial baseline implementation.
Today I am happy to share the final results, as the challenge closed for new entries after exactly one month on Jan 31
and all submissions have been reviewed.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>The One Billion Row Challenge</title>
      <link>https://www.morling.dev/blog/one-billion-row-challenge/</link>
      <pubDate>Mon, 01 Jan 2024 00:00:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/one-billion-row-challenge/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;em&gt;Update Jan 4: Wow, this thing really took off!&lt;/em&gt;
&lt;em&gt;1BRC is discussed at a couple of places on the internet, including &lt;a href=&#34;https://news.ycombinator.com/item?id=38851337&#34;&gt;Hacker News&lt;/a&gt;, &lt;a href=&#34;https://lobste.rs/s/u2qcnf/one_billion_row_challenge&#34;&gt;lobste.rs&lt;/a&gt;, and &lt;a href=&#34;https://old.reddit.com/r/programming/comments/18x0x0u/the_one_billion_row_challenge/&#34;&gt;Reddit&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;em&gt;For folks to show-case non-Java solutions, there is a &lt;a href=&#34;https://github.com/gunnarmorling/1brc/discussions/categories/show-and-tell&#34;&gt;&amp;#34;Show &amp;amp; Tell&amp;#34;&lt;/a&gt; now, check that one out for 1BRC implementations in Rust, Go, C++, and others.&lt;/em&gt;
&lt;em&gt;Some interesting related write-ups include &lt;a href=&#34;https://rmoff.net/2024/01/03/1%EF%B8%8F%E2%83%A3%EF%B8%8F-1brc-in-sql-with-duckdb/&#34;&gt;1BRC in SQL with DuckDB&lt;/a&gt; by Robin Moffatt and &lt;a href=&#34;https://ftisiot.net/posts/1brows/&#34;&gt;1 billion rows challenge in PostgreSQL and ClickHouse&lt;/a&gt; by Francesco Tisiot.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;em&gt;Thanks a lot for all the submissions, this is going way beyond what I’d have expected!&lt;/em&gt;
&lt;em&gt;I am behind a bit with evalutions due to the sheer amount of entries, I will work through them bit by bit.&lt;/em&gt;
&lt;em&gt;I have also made a few clarifications to &lt;a href=&#34;https://github.com/gunnarmorling/1brc#faq&#34;&gt;the rules&lt;/a&gt; of the challenge; please make sure to read them before submitting any entries.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Let’s kick off 2024 true coder style—​I’m excited to announce the &lt;a href=&#34;https://github.com/gunnarmorling/onebrc&#34;&gt;One Billion Row Challenge&lt;/a&gt; (1BRC), running from Jan 1 until Jan 31.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Your mission, should you decide to accept it, is deceptively simple:
write a Java program for retrieving temperature measurement values from a text file and calculating the min, mean, and max temperature per weather station.
There’s just one caveat: the file has &lt;strong&gt;1,000,000,000 rows&lt;/strong&gt;!&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Logical Replication From Postgres 16 Stand-By Servers—Debezium and Failover Slots</title>
      <link>https://www.morling.dev/blog/logical-replication-from-postgres-stand-by-servers-debezium-and-failover-slots/</link>
      <pubDate>Tue, 19 Dec 2023 00:00:00 +0000</pubDate>
      
      <guid>https://www.morling.dev/blog/logical-replication-from-postgres-stand-by-servers-debezium-and-failover-slots/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_stand_by_logical_replication_with_debezium&#34;&gt;Stand-By Logical Replication With Debezium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_towards_fail_over_slots&#34;&gt;Towards Fail-Over Slots&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_wrap_up&#34;&gt;Wrap-Up&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;em&gt;This post originally appeared on the &lt;a href=&#34;https://www.decodable.co/blog/logical-replication-from-postgres-16-stand-by-servers-part-2-of-2&#34;&gt;Decodable blog&lt;/a&gt;. All rights reserved.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Welcome back to this series about logical replication from Postgres 16 stand-by servers, in which we’ll discuss how to use this feature with Debezium—a popular open-source platform for Change Data Capture (CDC) for a wide range of databases—as well as how to manage logical replication in case of failover scenarios, i.e.
a situation where your primary Postgres server becomes unavailable and a stand-by server needs to take over.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Using Stand-by Servers for Postgres Logical Replication</title>
      <link>https://www.morling.dev/blog/stand-by-servers-for-postgres-logical-replication/</link>
      <pubDate>Tue, 19 Dec 2023 00:00:00 +0000</pubDate>
      
      <guid>https://www.morling.dev/blog/stand-by-servers-for-postgres-logical-replication/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_what_is_postgres_logical_replication&#34;&gt;What is Postgres Logical Replication?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_why_logical_replication_on_stand_by_servers&#34;&gt;Why Logical Replication On Stand-By Servers?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_provisioning_a_testing_environment&#34;&gt;Provisioning a Testing Environment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_testing_things_out&#34;&gt;Testing Things Out&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;em&gt;This post originally appeared on the &lt;a href=&#34;https://www.decodable.co/blog/postgres-logical-replication&#34;&gt;Decodable blog&lt;/a&gt;. All rights reserved.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;For users of Change Data Capture (CDC), one of the most exciting features in Postgres version 16 (released in September this year) is the support for logical replication from stand-by servers.
Instead of connecting to your primary server, you can now point CDC tools such as Debezium to a replica server, which is very interesting for instance from a load distribution perspective.
I am going to take a closer look at this new feature in this two-part blog series:&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Tracking Java Native Memory With JDK Flight Recorder</title>
      <link>https://www.morling.dev/blog/tracking-java-native-memory-with-jdk-flight-recorder/</link>
      <pubDate>Sun, 17 Dec 2023 19:29:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/tracking-java-native-memory-with-jdk-flight-recorder/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_an_example&#34;&gt;An Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_tracking_rss&#34;&gt;Tracking RSS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;As regular readers of this blog will now, &lt;a href=&#34;https://openjdk.org/jeps/328&#34;&gt;JDK Flight Recorder&lt;/a&gt; (JFR) is one of my favorite tools of the Java platform.
This low-overhead event recording engine built into the JVM is invaluable for observing the runtime characteristics of Java applications and identifying any potential performance issues.
JFR continues to become better and better with every new release,
with one recent addition being support for native memory tracking (NMT).&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Getting Started With PyFlink on Kubernetes</title>
      <link>https://www.morling.dev/blog/getting-started-with-pyflink-on-kubernetes/</link>
      <pubDate>Thu, 07 Dec 2023 00:00:00 +0000</pubDate>
      
      <guid>https://www.morling.dev/blog/getting-started-with-pyflink-on-kubernetes/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_what_is_pyflink_and_why_should_you_care&#34;&gt;What Is PyFlink and Why Should You Care?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_prerequisites&#34;&gt;Prerequisites&lt;/a&gt;
&lt;ul class=&#34;sectlevel2&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_installing_the_flink_kubernetes_operator&#34;&gt;Installing the Flink Kubernetes Operator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_installing_strimzi_and_apache_kafka&#34;&gt;Installing Strimzi and Apache Kafka&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_a_simple_pyflink_job&#34;&gt;A Simple PyFlink Job&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_building_a_container_image_with_your_pyflink_job&#34;&gt;Building a Container Image With Your PyFlink Job&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_deploying_a_pyflink_job_on_kubernetes&#34;&gt;Deploying a PyFlink Job On Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;em&gt;This post originally appeared on the &lt;a href=&#34;https://www.decodable.co/blog/getting-started-with-pyflink-on-kubernetes&#34;&gt;Decodable blog&lt;/a&gt;. All rights reserved.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;The other day, I wanted to get my feet wet with PyFlink.
While there is a fair amount of related information out there, I couldn’t find really up-to-date documentation on using current versions of PyFlink with Flink on Kubernetes.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>&#34;Change Data Capture Breaks Encapsulation&#34;. Does it, though?</title>
      <link>https://www.morling.dev/blog/change-data-capture-breaks-encapsulation-does-it-though/</link>
      <pubDate>Tue, 21 Nov 2023 00:00:00 +0000</pubDate>
      
      <guid>https://www.morling.dev/blog/change-data-capture-breaks-encapsulation-does-it-though/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_cdca_quick_primer&#34;&gt;CDC—​A Quick Primer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_does_cdc_break_encapsulation&#34;&gt;Does CDC Break Encapsulation?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_entering_data_contracts&#34;&gt;Entering Data Contracts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_implementation_approaches_for_data_contracts&#34;&gt;Implementation Approaches For Data Contracts&lt;/a&gt;
&lt;ul class=&#34;sectlevel2&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_the_outbox_pattern&#34;&gt;The Outbox Pattern&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_stream_processing&#34;&gt;Stream Processing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_streaming_data_contractsbeyond_the_basics&#34;&gt;Streaming Data Contracts—​Beyond the Basics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_handling_schema_changes&#34;&gt;Handling Schema Changes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_summary&#34;&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;em&gt;This post originally appeared on the &lt;a href=&#34;https://www.decodable.co/blog/change-data-capture-breaks-encapsulation-does-it-though&#34;&gt;Decodable blog&lt;/a&gt;. All rights reserved.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Having worked on Debezium—​an open-source platform for Change Data Capture (CDC)—​for several years, one concern I’ve heard repeatedly is this: aren’t you breaking the encapsulation of your application when you expose change event feeds directly from your database?
After all, CDC exposes your internal persistent data model to the outside world, which may have unintended consequences, e.g.
in terms of data exposure but also when it comes to changes to the schema of your data, which may break downstream consumers.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Can Debezium Lose Events?</title>
      <link>https://www.morling.dev/blog/can-debezium-lose-events/</link>
      <pubDate>Tue, 14 Nov 2023 15:00:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/can-debezium-lose-events/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;This question came up on the Data Engineering sub-reddit the other day:
&lt;a href=&#34;https://old.reddit.com/r/dataengineering/comments/17ttw5e/can_debezium_loose_updates/&#34;&gt;Can Debezium lose any events&lt;/a&gt;?
I.e. can there be a situation where a record in a database get inserted, updated, or deleted, but Debezium fails to capture that event from the transaction log and propagate it to downstream consumers?&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>CDC Use Cases: 7 Ways to Put CDC to Work</title>
      <link>https://www.morling.dev/blog/cdc-use-cases/</link>
      <pubDate>Thu, 02 Nov 2023 00:00:00 +0000</pubDate>
      
      <guid>https://www.morling.dev/blog/cdc-use-cases/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_what_is_cdc&#34;&gt;What is CDC?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_cdc_tools&#34;&gt;CDC Tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_analytics_data_platforms&#34;&gt;Analytics Data Platforms&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_application_caches&#34;&gt;Application Caches&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_full_text_search&#34;&gt;Full-Text Search&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_audit_logs&#34;&gt;Audit Logs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_continuous_queries&#34;&gt;Continuous Queries&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_microservices_data_exchange&#34;&gt;Microservices Data Exchange&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_monolith_to_microservices_migration&#34;&gt;Monolith-to-Microservices Migration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_summary&#34;&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;em&gt;This post originally appeared on the &lt;a href=&#34;https://www.decodable.co/blog/cdc-use-cases&#34;&gt;Decodable blog&lt;/a&gt;. All rights reserved.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Change Data Capture (CDC) is a powerful tool in data engineering and has seen a tremendous uptake in organizations of all kinds over the last few years.
This is because it enables the tight integration of transactional databases into many other systems in your business at a very low latency.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Finding Java Thread Leaks With JDK Flight Recorder and a Bit Of SQL</title>
      <link>https://www.morling.dev/blog/finding-java-thread-leaks-with-jdk-flight-recorder-and-bit-of-sql/</link>
      <pubDate>Tue, 28 Feb 2023 22:16:10 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/finding-java-thread-leaks-with-jdk-flight-recorder-and-bit-of-sql/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;The other day at work, we had a situation where we suspected a thread leak in one particular service,
i.e. code which continuously starts new threads, without taking care of ever stopping them again.
Each thread requires a bit of memory for its stack space,
so starting an unbounded number of threads can be considered as a form of memory leak, causing your application to run out of memory eventually.
In addition, the more threads there are, the more overhead the operating system incurs for scheduling them,
until the scheduler itself will consume most of the available CPU resources.
Thus it’s vital to detect and fix this kind of problem early on.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Getting Started With Java Development in 2023 — An Opinionated Guide</title>
      <link>https://www.morling.dev/blog/getting-started-with-java-development-2023/</link>
      <pubDate>Sun, 15 Jan 2023 22:10:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/getting-started-with-java-development-2023/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_distribution&#34;&gt;📦 Distribution&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_version&#34;&gt;📆 Version&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_installation&#34;&gt;🔧 Installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_your_first_java_program&#34;&gt;💡 Your First Java Program&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_learning_the_language&#34;&gt;📚 Learning the Language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_️_build_tool&#34;&gt;👷‍♀️ Build Tool&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_editor&#34;&gt;📝 Editor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_libraries&#34;&gt;🧱 Libraries&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_application_framework&#34;&gt;🐢 Application Framework&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_container_base_image&#34;&gt;🐳 Container Base Image&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_next_steps&#34;&gt;🔭 Next Steps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;27 years of age, and alive and kicking — The Java platform regularly comes out amongst the top contenders in rankings like the &lt;a href=&#34;https://www.tiobe.com/tiobe-index/&#34;&gt;TIOBE index&lt;/a&gt;.
In my opinion, rightly so. The language is very actively maintained and constantly improved;
its underlying runtime, the Java Virtual Machine (JVM),
is one of, if not the most, advanced runtime environments for managed programming languages.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;There is a massive eco-system of Java libraries which make it a great tool for a large number of use cases,
ranging from command-line and desktop applications, over web apps and backend web services, to datastores and stream processing platforms.
With upcoming features like &lt;a href=&#34;https://openjdk.org/jeps/426&#34;&gt;support for vectorized computations&lt;/a&gt; (SIMD),
light-weight &lt;a href=&#34;https://openjdk.org/projects/loom&#34;&gt;virtual threads&lt;/a&gt;,
improved &lt;a href=&#34;https://openjdk.org/projects/panama/&#34;&gt;integration with native code&lt;/a&gt;,
&lt;a href=&#34;https://openjdk.org/projects/valhalla/&#34;&gt;value objects and user-defined primitives&lt;/a&gt;, and others,
Java is becoming an excellent tool for solving a larger number of software development tasks than ever before.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Oh... This is Prod?!</title>
      <link>https://www.morling.dev/blog/oh_this_is_prod/</link>
      <pubDate>Thu, 05 Jan 2023 22:10:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/oh_this_is_prod/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;I strongly believe that you should avoid connecting to production environments from local developer machines as much as possible.
But sometimes, e.g. in order to analyse some specific kinds of failures,
doing so can be inevitable.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Now, if this is the case, I really, really want to be sure that I’m aware of the environment I am working in.
I absolutely want to avoid a situation as in the catchy title of this post,
when for instance you realize that you just ran some integration test against a production environment.
In the context of working with the AWS CLI tool this means I’d like to be aware of the currently active &lt;a href=&#34;https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html&#34;&gt;profile&lt;/a&gt; by means of coloring my shell accordingly.
Here’s how I’ve set this up using &lt;a href=&#34;https://iterm2.com/&#34;&gt;iTerm2&lt;/a&gt; and &lt;a href=&#34;https://www.zsh.org/&#34;&gt;zsh&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Is your Blocking Queue... Blocking?</title>
      <link>https://www.morling.dev/blog/is-your-blocking-queue-blocking/</link>
      <pubDate>Tue, 03 Jan 2023 22:10:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/is-your-blocking-queue-blocking/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_emitting_custom_events&#34;&gt;Emitting Custom Events&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_filtering_thread_park_events&#34;&gt;Filtering &amp;#34;Thread Park&amp;#34; Events&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_towards_real_time_analysis_of_jfr_events&#34;&gt;Towards Real-Time Analysis of JFR Events&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Java’s &lt;a href=&#34;https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/BlockingQueue.html&#34;&gt;&lt;code&gt;BlockingQueue&lt;/code&gt;&lt;/a&gt; hierarchy is widely used for coordinating work between different producer and consumer threads.
When set up with a maximum capacity (i.e. a &lt;em&gt;bounded queue&lt;/em&gt;), no more elements can be added by producers to the queue once it is full, until a consumer has taken at least one element.
For scenarios where new work may arrive more quickly than it can be consumed, this applies means of back-pressure,
ensuring the application doesn’t run out of memory eventually, while enqueuing more and more work items.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Maven, What Are You Waiting For?!</title>
      <link>https://www.morling.dev/blog/maven-what-are-you-waiting-for/</link>
      <pubDate>Sun, 18 Dec 2022 13:45:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/maven-what-are-you-waiting-for/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;As part of my &lt;a href=&#34;https://www.morling.dev/blog/why-i-joined-decodable/&#34;&gt;new job&lt;/a&gt; at Decodable,
I am also planning to contribute to the &lt;a href=&#34;https://flink.apache.org/&#34;&gt;Apache Flink&lt;/a&gt; project
(as Decodable’s fully-managed &lt;a href=&#34;https://www.decodable.co/product&#34;&gt;stream processing platform&lt;/a&gt; is based on Flink).
Right now, I am in the process of familiarizing myself with the Flink code base,
and as such I am of course building the project from source, too.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Postgres 15: Logical Decoding Row Filters With Debezium</title>
      <link>https://www.morling.dev/blog/postgres-15-logical-decoding-row-filters-with-debezium/</link>
      <pubDate>Thu, 15 Dec 2022 00:00:00 +0000</pubDate>
      
      <guid>https://www.morling.dev/blog/postgres-15-logical-decoding-row-filters-with-debezium/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_using_logical_decoding_row_filters_with_debezium&#34;&gt;Using Logical Decoding Row Filters With Debezium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_observing_filtered_change_events&#34;&gt;Observing Filtered Change Events&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_wrap_up&#34;&gt;Wrap-Up&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;em&gt;This post originally appeared on the &lt;a href=&#34;https://www.decodable.co/blog/postgres-15-logical-decoding-row-filters-with-debezium&#34;&gt;Decodable blog&lt;/a&gt;. All rights reserved.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Since &lt;a href=&#34;https://www.postgresql.org/docs/current/logicaldecoding-explanation.html&#34;&gt;logical decoding&lt;/a&gt; was added to Postgres in version 9.4, this powerful feature for capturing changes from the write-ahead log of the database has been continuously improved.
&lt;a href=&#34;https://www.postgresql.org/about/news/postgresql-15-released-2526/&#34;&gt;Postgres 15&lt;/a&gt;, released in October this year, added support for fine-grained control over which columns (by means of &lt;em&gt;column lists&lt;/em&gt;) and rows (via &lt;em&gt;row filters&lt;/em&gt;) should be exported from captured tables.
This means, in relational terminology, projections and filters are now natively supported by Postgres change event publications.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>The Insatiable Postgres Replication Slot</title>
      <link>https://www.morling.dev/blog/insatiable-postgres-replication-slot/</link>
      <pubDate>Wed, 30 Nov 2022 14:00:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/insatiable-postgres-replication-slot/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_the_observation&#34;&gt;The Observation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_the_solution&#34;&gt;The Solution&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_take_away&#34;&gt;Take Away&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;While working on a demo for processing change events from Postgres with Apache Flink,
I noticed an interesting phenomenon:
A Postgres database which I had set up for that demo on Amazon RDS, ran out of disk space.
The machine had a disk size of 200 GiB which was fully used up in the course of less than two weeks.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Now a common cause for this kind of issue are replication slots which are not advanced:
in that case, Postgres will hold on to all WAL segments after the latest log sequence number (&lt;a href=&#34;https://pgpedia.info/l/LSN-log-sequence-number.html&#34;&gt;LSN&lt;/a&gt;) which was confirmed for that slot.
Indeed I had set up a replication slot (via the &lt;a href=&#34;https://www.decodable.co/connectors/postgres-cdc&#34;&gt;Decodable CDC source connector for Postgres&lt;/a&gt;, which is based on &lt;a href=&#34;https://debezium.io&#34;&gt;Debezium&lt;/a&gt;).
I then had stopped that connector, causing the slot to become inactive.
The problem was though that I was really sure that there was no traffic in that database whatsoever!
What could cause a WAL growth of ~18 GB/day then?&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Running a Quarkus Native Application on Render</title>
      <link>https://www.morling.dev/blog/running-quarkus-native-app-on-render/</link>
      <pubDate>Mon, 28 Nov 2022 11:45:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/running-quarkus-native-app-on-render/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_java_applications_on_render&#34;&gt;Java Applications on Render&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_configuration_details&#34;&gt;Configuration Details&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_docker_hub_access_token&#34;&gt;Docker Hub Access Token&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_github_actions&#34;&gt;GitHub Actions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;This is a quick run down of the steps required for running JVM applications,
built using Quarkus and GraalVM, on Render.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://render.com/&#34;&gt;Render&lt;/a&gt; is a cloud platform for running websites and applications.
Like most other comparable services such as &lt;a href=&#34;https://fly.io/&#34;&gt;fly.io&lt;/a&gt;,
it offers a decent free tier, which lets you try out the service without any financial commitment.
&lt;em&gt;Unlike&lt;/em&gt; most other services,
with Render, you don’t need to provide a credit card in order to use the free tier.
Which means there’s no risk of surprise bills, as often is the case with pay-per-use models,
where a malicious actor could DDOS your service and drive up cost for consumed CPU resources or egress bandwidth indefinitely.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Why I Joined Decodable</title>
      <link>https://www.morling.dev/blog/why-i-joined-decodable/</link>
      <pubDate>Thu, 03 Nov 2022 15:00:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/why-i-joined-decodable/</guid>
      <description>Table of Contents The Space: Real-Time Stream Processing The Environment: A Start-up The Team: One of a Kind Outlook It’s my first week as a software engineer at Decodable, a start-up building a serverless real-time data platform! When I shared this news on social media yesterday, folks were not only super supportive and excited for me (thank you so much for all the nice words and wishes!), but some also asked about the reasons behind my decision for switching jobs and going to a start-up, after having worked for Red Hat for the last few years.</description>
    </item>
    
    <item>
      <title>An Ideation for Kubernetes-native Kafka Connect</title>
      <link>https://www.morling.dev/blog/ideation-kubernetes-native-kafka-connect/</link>
      <pubDate>Tue, 06 Sep 2022 14:20:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/ideation-kubernetes-native-kafka-connect/</guid>
      <description>Table of Contents Standalone or Distributed? Issues with Kafka Connect on Kubernetes A Vision for Kubernetes-native Kafka Connect Kafka Connect, part of the Apache Kafka project, is a development framework and runtime for connectors which either ingest data into Kafka clusters (source connectors) or propagate data from Kafka into external systems (sink connectors). A diverse ecosystem of ready-made connectors has come to life on top of Kafka Connect, which lets you connect all kinds of data stores, APIs, and other systems to Kafka in a no-code approach.</description>
    </item>
    
    <item>
      <title>Testing Kafka Connectors</title>
      <link>https://www.morling.dev/blog/testing-kafka-connectors/</link>
      <pubDate>Thu, 25 Aug 2022 09:20:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/testing-kafka-connectors/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_unit_tests&#34;&gt;Unit Tests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_integration_tests&#34;&gt;Integration Tests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_wrap_up&#34;&gt;Wrap-Up&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://kafka.apache.org/documentation/#connect&#34;&gt;Kafka Connect&lt;/a&gt; is a key factor for the wide-spread adoption of Apache Kafka:
a framework and runtime environment for connectors,
it makes the task of getting data either into Kafka or out of Kafka solely a matter of configuration,
rather than a bespoke programming job.
There’s dozens, if not hundreds, of readymade source and sink connectors,
allowing you to create no-code data pipelines between all kinds of databases, APIs, and other systems.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;There may be situations though where there is no existing connector matching your requirements,
in which case you can &lt;a href=&#34;https://kafka.apache.org/documentation/#connect_development&#34;&gt;implement your own&lt;/a&gt; custom connector using the Kafka Connect framework.
Naturally, this raises the question of how to test such a Kafka connector,
making sure it propagates the data between the connected external system and Kafka correctly and completely.
In this blog post I’d like to focus on testing approaches for Kafka Connect &lt;em&gt;source&lt;/em&gt; connectors,
i.e. connectors like &lt;a href=&#34;https://debezium.io/&#34;&gt;Debezium&lt;/a&gt;, which ingest data from an external system into Kafka.
Very similar strategies can be employed for testing sink connectors, though.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Ten Tips to Make Conference Talks Suck Less</title>
      <link>https://www.morling.dev/blog/ten-tips-make-conference-talks-suck-less/</link>
      <pubDate>Thu, 23 Jun 2022 10:15:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/ten-tips-make-conference-talks-suck-less/</guid>
      <description>Table of Contents 1. 💦 Rehearse, Rehearse, Rehearse 2. 🎬 Start With a Mission 3. 📖 Tell a Story 4. 👀 Look at the Audience, Not Your Slides 5. 🧹 Put Less Text on Your Slides. Much Less 6. ✂️ Tailor the Talk Towards Your Audience 7. 3️⃣ Rule of Three 8. 🚑 Have a Fallback Plan for Demos 9. 💪 Play to Your Strengths 10. 🔄 Circle Back Every so often, I come across some conference talk which is highly interesting in terms of its actual contents, but which unfortunately is presented in a less than ideal way.</description>
    </item>
    
    <item>
      <title>Loom and Thread Fairness</title>
      <link>https://www.morling.dev/blog/loom-and-thread-fairness/</link>
      <pubDate>Fri, 27 May 2022 09:20:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/loom-and-thread-fairness/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_project_loom&#34;&gt;Project Loom&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_scheduling&#34;&gt;Scheduling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_discussion&#34;&gt;Discussion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Project Loom (&lt;a href=&#34;https://openjdk.java.net/jeps/425&#34;&gt;JEP 425&lt;/a&gt;) is probably amongst the most awaited feature additions to Java ever;
its implementation of virtual threads (or &amp;#34;green threads&amp;#34;) promises developers the ability to create highly concurrent applications,
for instance with hundreds of thousands of open HTTP connections,
sticking to the well-known thread-per-request programming model,
without having to resort to less familiar and often more complex to use reactive approaches.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Having been in the workings for several years, Loom got merged into the mainline of OpenJDK &lt;a href=&#34;https://github.com/openjdk/jdk/commit/9583e3657e43cc1c6f2101a64534564db2a9bd84&#34;&gt;just recently&lt;/a&gt; and is available as a preview feature in the latest &lt;a href=&#34;https://jdk.java.net/19/&#34;&gt;Java 19 early access builds&lt;/a&gt;.
I.e. it’s the perfect time to get your hands onto virtual threads and explore the new feature.
In this post I’m going to share an interesting aspect I learned about thread scheduling fairness for CPU-bound workloads running on Loom.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Running JDK Mission Control on Apple M1</title>
      <link>https://www.morling.dev/blog/running-jmc-on-apple-m1/</link>
      <pubDate>Tue, 17 May 2022 09:20:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/running-jmc-on-apple-m1/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://jdk.java.net/jmc/8/&#34;&gt;JDK Mission Control&lt;/a&gt; (JMC) is invaluable for analysing performance data recording using &lt;a href=&#34;https://openjdk.java.net/jeps/328&#34;&gt;JDK Flight Recorder&lt;/a&gt; (JFR).
The other day, I ran into a problem when trying to run JMC on my Mac Mini M1.
Mostly for my own reference, here’s what I did to overcome it.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>The Code Review Pyramid</title>
      <link>https://www.morling.dev/blog/the-code-review-pyramid/</link>
      <pubDate>Thu, 10 Mar 2022 16:45:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/the-code-review-pyramid/</guid>
      <description>Table of Contents FAQ When it comes to code reviews, it’s a common phenomenon that there is much focus and long-winded discussions around mundane aspects like code formatting and style, whereas important aspects (does the code change do what it is supposed to do, is it performant, is it backwards-compatible for existing clients, and many others) tend to get less attention.
To raise awareness for the issue and providing some guidance on aspects to focus on, I shared a small visual on Twitter the other day, which I called the &amp;#34;Code Review Pyramid&amp;#34;.</description>
    </item>
    
    <item>
      <title>The JDK Flight Recorder File Format</title>
      <link>https://www.morling.dev/blog/jdk-flight-recorder-file-format/</link>
      <pubDate>Sun, 20 Feb 2022 21:15:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/jdk-flight-recorder-file-format/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;The &lt;a href=&#34;https://openjdk.java.net/jeps/328&#34;&gt;JDK Flight Recorder&lt;/a&gt; (JFR) is one of Java’s secret weapons;
deeply integrated into the Hotspot VM, it’s a high-performance event collection framework,
which lets you collect metrics on runtime aspects like object allocation and garbage collection,
class loading, file and network I/O, and lock contention, do method profiling, and much more.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;JFR data is persisted in recording files
(since Java 14, also &lt;a href=&#34;https://openjdk.java.net/jeps/349&#34;&gt;&amp;#34;realtime&amp;#34; event streaming&lt;/a&gt; is supported),
which can be loaded for analysis into tools like JDK Mission Control (JMC),
or the &lt;em&gt;jfr&lt;/em&gt; utility coming with OpenJDK itself.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>What&#39;s in a Good Error Message?</title>
      <link>https://www.morling.dev/blog/whats-in-a-good-error-message/</link>
      <pubDate>Wed, 12 Jan 2022 19:20:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/whats-in-a-good-error-message/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_context&#34;&gt;Context&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_the_error_itself&#34;&gt;The Error Itself&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_mitigation&#34;&gt;Mitigation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_general_best_practices&#34;&gt;General Best Practices&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;As software developers, we’ve all come across those annoying, not-so-useful error messages when using some library or framework: &lt;em&gt;&amp;#34;Couldn’t parse config file&amp;#34;&lt;/em&gt;, &lt;em&gt;&amp;#34;Lacking permission for this operation&amp;#34;&lt;/em&gt;, etc.
Ok, ok, so &lt;em&gt;something&lt;/em&gt; went wrong apparently; but what exactly? What config file? Which permissions? And what should you do about it?
Error messages lacking this kind of information quickly create a feeling of frustration and helplessness.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;So what makes a good error message then?
To me, it boils down to three pieces of information which should be conveyed by an error message:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;ulist&#34;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Context:&lt;/strong&gt; What led to the error? What was the code trying to do when it failed?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The error itself:&lt;/strong&gt; What exactly failed?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mitigation:&lt;/strong&gt; What needs to be done in order to overcome the error?&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Announcing the First Release of kcctl</title>
      <link>https://www.morling.dev/blog/announcing-first-release-of-kcctl/</link>
      <pubDate>Tue, 21 Dec 2021 17:48:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/announcing-first-release-of-kcctl/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_discussion_and_outlook&#34;&gt;Discussion and Outlook&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;🧸 &lt;em&gt;It’s Casey. Casey Cuddle.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;I am very happy to announce the first stable release of &lt;a href=&#34;https://github.com/kcctl/kcctl&#34;&gt;kcctl&lt;/a&gt;,
a modern and intuitive command line client for &lt;a href=&#34;https://kafka.apache.org/documentation/#connect&#34;&gt;Apache Kafka Connect&lt;/a&gt;!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Forget about having to memorize and type the right REST API paths and curl flags;
with kcctl, managing your Kafka connectors is done via concise and logically structured commands,
modeled after the semantics of the kubectl tool known from Kubernetes.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Introducing the OSS Quickstart Archetype</title>
      <link>https://www.morling.dev/blog/introducing-oss-quickstart-archetype/</link>
      <pubDate>Thu, 02 Dec 2021 18:30:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/introducing-oss-quickstart-archetype/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_the_challenge&#34;&gt;The Challenge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_the_oss_quickstart_archetype&#34;&gt;The OSS Quickstart Archetype&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_outlook&#34;&gt;Outlook&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;I am very happy to announce the availability of the &lt;a href=&#34;https://github.com/moditect/oss-quickstart&#34;&gt;OSS Quickstart Archetype&lt;/a&gt;!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Part of the &lt;a href=&#34;https://github.com/moditect/&#34;&gt;ModiTect&lt;/a&gt; family of open-source projects,
this is a Maven archetype which makes it very easy to bootstrap new Maven-based open-source projects,
satisfying common requirements such as configuring plug-in versions, and adhering to best practices like auto-formatting the source code.
Think &lt;a href=&#34;https://maven.apache.org/archetypes/maven-archetype-quickstart/scm.html&#34;&gt;Maven Quickstart Archetype&lt;/a&gt; and friends, but more modern, complete, and opinionated.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>O Kafka, Where Art Thou?</title>
      <link>https://www.morling.dev/blog/kafka-where-art-thou/</link>
      <pubDate>Mon, 29 Nov 2021 18:55:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/kafka-where-art-thou/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;The other day, I came across an &lt;a href=&#34;https://www.reddit.com/r/java/comments/r2z17a/has_any_one_attempted_to_write_logs_directly_to/&#34;&gt;interesting thread&lt;/a&gt; in the Java sub-reddit, with someone asking:
&amp;#34;Has anyone attempted to write logs directly to Kafka?&amp;#34;.
This triggered a number of thoughts and questions for myself,
in particular how one should deal in an application when an attempt to send messages to Kafka fails,
for instance due to some network connectivity issue?
What do you do when you cannot reach the Kafka broker?&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Refining The Return Type Of Java Methods Without Breaking Backwards-Compatibility</title>
      <link>https://www.morling.dev/blog/refining-return-type-java-methods-without-breaking-backwards-compatibility/</link>
      <pubDate>Mon, 22 Nov 2021 18:30:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/refining-return-type-java-methods-without-breaking-backwards-compatibility/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_the_problem&#34;&gt;The Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_bridge_methods_to_the_rescue&#34;&gt;Bridge Methods to the Rescue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_creating_bridge_methods_ourselves&#34;&gt;Creating Bridge Methods Ourselves&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;If you work on any kind of software library,
ensuring backwards-compatibility is a key concern:
if there’s one thing which users really dislike, it is breaking changes in a new version of a library.
The rules of what can (and cannot) be changed in a Java API without breaking existing consumers are well defined in the Java language specification (JLS),
but things can get pretty interesting in certain corner cases.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;The Eclipse team provides a &lt;a href=&#34;https://wiki.eclipse.org/Evolving_Java-based_APIs_2&#34;&gt;comprehensive overview&lt;/a&gt; about API evolution guidelines in their wiki.
When I shared the link to this great resource on Twitter the other day,
I received an &lt;a href=&#34;https://twitter.com/lukaseder/status/1462358911072317440&#34;&gt;interesting reply&lt;/a&gt; from Lukas Eder:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;quoteblock&#34;&gt;
&lt;blockquote&gt;
I wish Java had a few tools to prevent some cases of binary compatibility breakages. E.g. when refining a method return type, I’d like to keep the old method around in byte code (but not in source code).
&lt;br/&gt;
&lt;br/&gt;
I think kotlin has such tools?
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;In the remainder of this post,
I’d like to provide some more insight into that problem mentioned by Lukas,
and how it can be addressed using an open-source tool called &lt;a href=&#34;https://github.com/dmlloyd/bridger&#34;&gt;Bridger&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>JDK Flight Recorder Events in GraalVM Native Binaries</title>
      <link>https://www.morling.dev/blog/jfr-events-in-graalvm-native-binaries/</link>
      <pubDate>Fri, 12 Nov 2021 18:30:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/jfr-events-in-graalvm-native-binaries/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;If you have followed this blog for a while,
you’ll know that I am a big fan of &lt;a href=&#34;https://openjdk.java.net/jeps/328&#34;&gt;JDK Flight Recorder&lt;/a&gt; (JFR),
the low-overhead diagnostics and profiling framework built into the HotSpot Java virtual machine.
And indeed, until recently, this meant &lt;em&gt;only&lt;/em&gt; HotSpot:
Folks compiling their Java applications into &lt;a href=&#34;https://www.graalvm.org/reference-manual/native-image/&#34;&gt;GraalVM native binaries&lt;/a&gt; could not benefit from all the JFR goodness so far.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Debezium and Friends – Conference Talks 2021</title>
      <link>https://www.morling.dev/blog/debezium-talks-2021/</link>
      <pubDate>Tue, 02 Nov 2021 10:50:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/debezium-talks-2021/</guid>
      <description>Table of Contents Don’t Fear Outdated Caches – Change Data Capture to the Rescue! Change Data Streaming Patterns in Distributed Systems Analyzing Real-time Order Deliveries using CDC with Debezium and Pinot Dissecting our Legacy: The Strangler Fig Pattern with Apache Kafka, Debezium and MongoDB Bonus: Debezium at the Trino Community Broadcast Learning More If you love to attend conferences around the world without actually leaving the comfort of your house, 2021 certainly was (and is!</description>
    </item>
    
    <item>
      <title>What&#39;s on My Desk?</title>
      <link>https://www.morling.dev/blog/whats-on-my-desk/</link>
      <pubDate>Sun, 24 Oct 2021 10:30:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/whats-on-my-desk/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_the_screen&#34;&gt;The Screen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_compute&#34;&gt;Compute&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_cameras&#34;&gt;Cameras&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_work_in_progress_teleprompter&#34;&gt;Work in Progress: Teleprompter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_lighting&#34;&gt;Lighting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_audio&#34;&gt;Audio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_whats_next&#34;&gt;What’s Next?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;imageblock&#34;&gt;
&lt;div class=&#34;content&#34;&gt;
&lt;img src=&#34;https://www.morling.dev/images/desk_complete.jpg&#34; alt=&#34;desk complete&#34;/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;I’ve been working from home exclusively for the last nine years,
but it was only last year that I started to look into ways for expanding my computer set-up and go beyond the usual combination of having a laptop with your regular external screen.
The global COVID-19 pandemic, the prospect of having more calls with colleagues than ever (no physical meetings), and the constantly increasing need for recording talks for online conferences and meet-ups made me reevaluate things and steadily improve and fine tune my set-up, in particular in regards to better video and audio quality.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Executable JavaDoc Code Snippets</title>
      <link>https://www.morling.dev/blog/executable-javadoc-code-snippets/</link>
      <pubDate>Mon, 18 Oct 2021 08:30:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/executable-javadoc-code-snippets/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_including_snippets_from_your_test_directory&#34;&gt;Including Snippets From Your Test Directory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_summary&#34;&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;It has been just a few weeks since the &lt;a href=&#34;https://www.infoq.com/news/2021/09/java17-released/&#34;&gt;release of Java 17&lt;/a&gt;, but the first changes scheduled for Java 18 begin to show up in early access builds.
One feature in particular that excites me as a maintainer of different Java libraries is &lt;a href=&#34;https://openjdk.java.net/jeps/413&#34;&gt;JEP 413&lt;/a&gt; (&amp;#34;Code Snippets in Java API Documentation&amp;#34;).&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Resource Bundle Look-ups in Modular Java Applications</title>
      <link>https://www.morling.dev/blog/resource-bundle-lookups-in-modular-java-applications/</link>
      <pubDate>Sun, 29 Aug 2021 18:30:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/resource-bundle-lookups-in-modular-java-applications/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_the_resourcebundleprovider_interface&#34;&gt;The &lt;code&gt;ResourceBundleProvider&lt;/code&gt; Interface&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_resource_bundle_providers&#34;&gt;Resource Bundle Providers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_running_on_the_classpath&#34;&gt;Running on the Classpath&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_discussion_and_wrap_up&#34;&gt;Discussion and Wrap-Up&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;The &lt;a href=&#34;https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/ResourceBundle.html&#34;&gt;&lt;code&gt;ResourceBundle&lt;/code&gt;&lt;/a&gt; class is Java’s workhorse for managing and retrieving locale specific resources,
such as error messages of internationalized applications.
With the advent of the module system in Java 9, specifics around discovering and loading resource bundles have changed quite a bit, in particular when it comes to retrieving resource bundles across the boundaries of named modules.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;In this blog post I’d like to discuss how resource bundles can be used in a multi-module application
(i.e. a &amp;#34;modular monolith&amp;#34;) for internationalizing error messages.
The following requirements should be satisified:&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Introducing JfrUnit 1.0.0.Alpha1</title>
      <link>https://www.morling.dev/blog/introducing-jfrunit-1-0-0-alpha1/</link>
      <pubDate>Wed, 04 Aug 2021 19:10:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/introducing-jfrunit-1-0-0-alpha1/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_getting_started_with_jfrunit&#34;&gt;Getting Started With JfrUnit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_groovier_tests_with_spock&#34;&gt;Groovier Tests With Spock&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_outlook&#34;&gt;Outlook&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;em&gt;Unit testing, for performance&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;It’s with great pleasure that I’m announcing the first official release of JfrUnit today!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/moditect/jfrunit&#34;&gt;JfrUnit&lt;/a&gt; is an extension to JUnit which allows you to assert &lt;a href=&#34;https://openjdk.java.net/jeps/328&#34;&gt;JDK Flight Recorder&lt;/a&gt; events in your unit tests.
This capability opens up a number of interesting use cases in the field of testing JVM-based applications:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;ulist&#34;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;You can use JfrUnit to ensure your application produces the &lt;a href=&#34;blog/rest-api-monitoring-with-custom-jdk-flight-recorder-events/&#34;&gt;custom JFR events&lt;/a&gt; you expect it to emit&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can use JfrUnit to identify potential performance regressions of your application by means of tracking JFR events e.g. for garbage collection, memory allocation and network I/O&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can use JfrUnit together with &lt;a href=&#34;https://wiki.openjdk.java.net/display/jmc/The+JMC+Agent&#34;&gt;JMC Agent&lt;/a&gt; for whitebox tests of your application, ensuring specific methods are invoked with the expected parameters and return values&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Three Plus Some Lovely Kafka Trends</title>
      <link>https://www.morling.dev/blog/three-plus-some-lovely-kafka-trends/</link>
      <pubDate>Fri, 28 May 2021 10:30:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/three-plus-some-lovely-kafka-trends/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_cambrian_explosion_of_connectors&#34;&gt;Cambrian Explosion of Connectors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_democratization_of_data_pipelines&#34;&gt;Democratization of Data Pipelines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_stream_processing_for_everyone&#34;&gt;Stream Processing for Everyone&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_honorable_mentions&#34;&gt;Honorable Mentions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Over the course of the last few months, I’ve had the pleasure to serve on the &lt;a href=&#34;https://www.kafka-summit.org/&#34;&gt;Kafka Summit&lt;/a&gt; program committee and review several hundred session abstracts for the three Summits happening this year (Europe, APAC, Americas).
That’s not only a big honour, but also a unique opportunity to learn what excites people currently in the Kafka eco-system
(and yes, it’s a fair amount of work, too ;).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;While voting on the proposals, and also generally aspiring to stay informed of what’s going on in the Kafka community at large, I noticed a few repeating themes and topics which I thought would be interesting to share
(without touching on any specific talks of course).
At first I meant to put this out via a Twitter thread, but then it became a bit too long for that, so I decided to write this quick blog post instead.
Here it goes!&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Exploring ZooKeeper-less Kafka</title>
      <link>https://www.morling.dev/blog/exploring-zookeeper-less-kafka/</link>
      <pubDate>Mon, 17 May 2021 18:45:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/exploring-zookeeper-less-kafka/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_trying_zk_less_kafka_yourself&#34;&gt;Trying ZK-less Kafka Yourself&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_taking_brokers_down&#34;&gt;Taking Brokers Down&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_wrap_up&#34;&gt;Wrap-Up&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Sometimes, less is more.
One case where that’s certainly true is dependencies.
And so it shouldn’t come at a surprise that the &lt;a href=&#34;https://kafka.apache.org/&#34;&gt;Apache Kafka&lt;/a&gt; community is eagerly awaiting the removal of the dependency to the &lt;a href=&#34;https://zookeeper.apache.org/&#34;&gt;ZooKeeper&lt;/a&gt; service,
which currently is used for storing Kafka metadata (e.g. about topics and partitions) as well as for the purposes of leader election in the cluster.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;The Kafka improvement proposal &lt;a href=&#34;https://cwiki.apache.org/confluence/display/KAFKA/KIP-500%3A+Replace+ZooKeeper+with+a+Self-Managed+Metadata+Quorum&#34;&gt;KIP-500&lt;/a&gt;
(&amp;#34;Replace ZooKeeper with a Self-Managed Metadata Quorum&amp;#34;)
promises to make life better for users in many regards:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;ulist&#34;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Better getting started and operational experience by requiring to run only one system, Kafka, instead of two&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Removing potential for discrepancies of metadata state between ZooKeeper and the Kafka controller&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Simplifying configuration, for instance when it comes to security&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Better scalability, e.g. in terms of number of partitions; faster execution of operations like topic creation&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>The Anatomy of ct.sym — How javac Ensures Backwards Compatibility</title>
      <link>https://www.morling.dev/blog/the-anatomy-of-ct-sym-how-javac-ensures-backwards-compatibility/</link>
      <pubDate>Mon, 26 Apr 2021 18:45:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/the-anatomy-of-ct-sym-how-javac-ensures-backwards-compatibility/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;One of the ultimate strengths of Java is its strong notion of backwards compatibility:
Java applications and libraries built many years ago oftentimes run without problems on current JVMs,
and the compiler of current JDKs can produce byte code, that is executable with earlier Java versions.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;For instance, JDK 16 supports byte code levels going back as far as to Java 1.7;
But: &lt;em&gt;hic sunt dracones&lt;/em&gt;.
The emitted byte code level is just one part of the story.
It’s equally important to consider which APIs of the JDK are used by the compiled code,
and whether they are available in the targeted Java runtime version.
As an example, let’s consider this simple &amp;#34;Hello World&amp;#34; program:&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>FizzBuzz – SIMD Style!</title>
      <link>https://www.morling.dev/blog/fizzbuzz-simd-style/</link>
      <pubDate>Mon, 08 Mar 2021 16:25:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/fizzbuzz-simd-style/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_whats_simd_anyways&#34;&gt;What’s SIMD Anyways?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_vectorizing_fizzbuzz&#34;&gt;Vectorizing FizzBuzz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_examining_the_native_code&#34;&gt;Examining the Native Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_avoiding_scalar_processing_of_tail_elements&#34;&gt;Avoiding Scalar Processing of Tail Elements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_wrap_up&#34;&gt;Wrap-Up&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Java 16 is around the corner, so there’s no better time than now for learning more about the features which the new version will bring.
After exploring the support for &lt;a href=&#34;https://www.morling.dev/blog/talking-to-postgres-through-java-16-unix-domain-socket-channels/&#34;&gt;Unix domain sockets&lt;/a&gt; a while ago,
I’ve lately been really curious about the incubating Vector API,
as defined by &lt;a href=&#34;https://openjdk.java.net/jeps/338&#34;&gt;JEP 338&lt;/a&gt;,
developed under the umbrella of &lt;a href=&#34;https://openjdk.java.net/projects/panama/&#34;&gt;Project Panama&lt;/a&gt;,
which aims at &amp;#34;interconnecting JVM and native code&amp;#34;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;&lt;em&gt;Vectors?!?&lt;/em&gt;
Of course this is not about renewing the ancient Java collection types like &lt;code&gt;java.util.Vector&lt;/code&gt;
(&amp;lt;insert some pun about this here&amp;gt;),
but rather about an API which lets Java developers take advantage of the vector calculation capabilities you can find in most CPUs these days.
Now I’m by no means an expert on low-level programming leveraging specific CPU instructions,
but exactly that’s why I hope to make the case with this post that the new Vector API makes these capabilities approachable to a wide audience of Java programmers.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Talking to Postgres Through Java 16 Unix-Domain Socket Channels</title>
      <link>https://www.morling.dev/blog/talking-to-postgres-through-java-16-unix-domain-socket-channels/</link>
      <pubDate>Sun, 31 Jan 2021 20:25:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/talking-to-postgres-through-java-16-unix-domain-socket-channels/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_the_postgres_jdbc_driver&#34;&gt;The Postgres JDBC Driver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_the_vert_x_postgres_client&#34;&gt;The Vert.x Postgres Client&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_other_use_cases&#34;&gt;Other Use Cases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Reading a blog post about what’s &lt;a href=&#34;https://www.loicmathieu.fr/wordpress/en/informatique/java-16-quoi-de-neuf/&#34;&gt;coming up in JDK 16&lt;/a&gt; recently,
I learned that one of the new features is support for Unix domain sockets (&lt;a href=&#34;https://openjdk.java.net/jeps/380&#34;&gt;JEP 380&lt;/a&gt;).
Before Java 16, you’d have to resort to 3rd party libraries like &lt;a href=&#34;https://github.com/jnr/jnr-unixsocket&#34;&gt;jnr-unixsocket&lt;/a&gt; in order to use them.
If you haven’t heard about &lt;a href=&#34;https://en.wikipedia.org/wiki/Unix_domain_socket&#34;&gt;Unix domain sockets&lt;/a&gt; before,
they are &amp;#34;data communications [endpoints] for exchanging data between processes executing on the same host operating system&amp;#34;.
Don’t be put off by the name btw.;
Unix domain sockets are also supported by macOS and even Windows since &lt;a href=&#34;https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/&#34;&gt;version 10&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>jlink&#39;s Missing Link: API Signature Validation</title>
      <link>https://www.morling.dev/blog/jlinks-missing-link-api-signature-validation/</link>
      <pubDate>Mon, 28 Dec 2020 12:20:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/jlinks-missing-link-api-signature-validation/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_the_example&#34;&gt;The Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_the_api_signature_check_jlink_plug_in&#34;&gt;The API Signature Check jlink Plug-in&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_summary&#34;&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Discussions around Java’s &lt;a href=&#34;https://openjdk.java.net/jeps/282&#34;&gt;jlink&lt;/a&gt; tool typically center around savings in terms of (disk) space.
Instead of shipping an entire JDK,
a custom runtime image created with jlink contains only those JDK modules which an application actually requires,
resulting in smaller distributables and &lt;a href=&#34;blog/smaller-faster-starting-container-images-with-jlink-and-appcds/&#34;&gt;container images&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;But the contribution of jlink — as a part of the Java module system at large — to the development of Java application’s is bigger than that:
with the notion of &lt;em&gt;link time&lt;/em&gt; it defines an optional complement to the well known phases &lt;em&gt;compile time&lt;/em&gt; and application &lt;em&gt;run-time&lt;/em&gt;:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;quoteblock&#34;&gt;
&lt;blockquote&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Link time is an opportunity to do whole-world optimizations that are otherwise difficult at compile time or costly at run-time. An example would be to optimize a computation when all its inputs become constant (i.e., not unknown). A follow-up optimization would be to remove code that is no longer reachable.&lt;/p&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>ByteBuffer and the Dreaded NoSuchMethodError</title>
      <link>https://www.morling.dev/blog/bytebuffer-and-the-dreaded-nosuchmethoderror/</link>
      <pubDate>Mon, 21 Dec 2020 17:45:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/bytebuffer-and-the-dreaded-nosuchmethoderror/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_how_to_prevent_this_situation&#34;&gt;How to Prevent This Situation?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;The other day, a user in the &lt;a href=&#34;https://debezium.io/&#34;&gt;Debezium&lt;/a&gt; community reported an interesting issue;
They were using Debezium with Java 1.8 and got an odd &lt;code&gt;NoSuchMethodError&lt;/code&gt;:&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Towards Continuous Performance Regression Testing</title>
      <link>https://www.morling.dev/blog/towards-continuous-performance-regression-testing/</link>
      <pubDate>Wed, 16 Dec 2020 17:45:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/towards-continuous-performance-regression-testing/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_getting_started_with_jfrunit&#34;&gt;Getting Started With JfrUnit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_case_study_1_spotting_increased_memory_allocation&#34;&gt;Case Study 1: Spotting Increased Memory Allocation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_case_study_2_identifying_increased_io_with_the_database&#34;&gt;Case Study 2: Identifying Increased I/O With the Database&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_discussion&#34;&gt;Discussion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_summary_and_outlook&#34;&gt;Summary and Outlook&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Functional unit and integration tests are a standard tool of any software development organization,
helping not only to ensure correctness of newly implemented code,
but also to identify regressions — bugs in existing functionality introduced by a code change.
The situation looks different though when it comes to regressions related to non-functional requirements, in particular performance-related ones:
How to detect increased response times in a web application?
How to identify decreased throughput?&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;These aspects are typically hard to test in an automated and reliable way in the development workflow,
as they are dependent on the underlying hardware and the workload of an application.
For instance assertions on the duration of specific requests of a web application typically cannot be run in a meaningful way on a developer laptop,
which differs from the actual production hardware
(ironically, nowadays both is an option, the developer laptop being less or more powerful than the actual production environment).
When run in a virtualized or containerized CI environment, such tests are prone to severe measurement distortions due to concurrent load of other applications and jobs.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;This post introduces the &lt;a href=&#34;https://github.com/gunnarmorling/jfrunit&#34;&gt;JfrUnit&lt;/a&gt; open-source project, which offers a fresh angle to this topic by supporting assertions not on metrics like latency/throughput themselves, but on &lt;em&gt;indirect metrics&lt;/em&gt; which may impact those.
JfrUnit allows you define expected values for metrics such as memory allocation, database I/O, or number of executed SQL statements, for a given workload and asserts the actual metrics values — which are obtained from &lt;a href=&#34;https://openjdk.java.net/jeps/328&#34;&gt;JDK Flight Recorder&lt;/a&gt; events — against these expected values.
Starting off from a defined base line, future failures of such assertions are an indicator for potential performance regressions in an application, as a code change may have introduced higher GC pressure,
the retrieval of unneccessary data from the database, or SQL problems commonly induced by ORM tools, like N+1 SELECT statements.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Smaller, Faster-starting Container Images With jlink and AppCDS</title>
      <link>https://www.morling.dev/blog/smaller-faster-starting-container-images-with-jlink-and-appcds/</link>
      <pubDate>Sun, 13 Dec 2020 20:30:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/smaller-faster-starting-container-images-with-jlink-and-appcds/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_creating_a_modular_runtime_image_for_a_quarkus_application&#34;&gt;Creating a Modular Runtime Image for a Quarkus Application&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_adding_an_appcds_archive_to_a_custom_runtime_image&#34;&gt;Adding an AppCDS Archive to a Custom Runtime Image&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_creating_a_linux_container_image&#34;&gt;Creating a Linux Container Image&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_lets_see_some_numbers&#34;&gt;Let’s See Some Numbers!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;A few months ago I &lt;a href=&#34;https://www.morling.dev/blog/building-class-data-sharing-archives-with-apache-maven/&#34;&gt;wrote about&lt;/a&gt; how you could speed up your Java application’s start-up times using application class data sharing (&lt;a href=&#34;http://openjdk.java.net/jeps/350&#34;&gt;AppCDS&lt;/a&gt;),
based on the example of a simple &lt;a href=&#34;https://quarkus.io/&#34;&gt;Quarkus&lt;/a&gt; application.
Since then, quite some progress has been made in this area:
Quarkus 1.6 brought &lt;a href=&#34;https://quarkus.io/guides/maven-tooling#quarkus-package-pkg-package-config_quarkus.package.create-appcds&#34;&gt;built-in support for AppCDS&lt;/a&gt;,
so that now you just need to provide the &lt;em&gt;-Dquarkus.package.create-appcds=true&lt;/em&gt; option when building your project,
and you’ll find an AppCDS file in the &lt;em&gt;target&lt;/em&gt; folder.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Things get more challenging though when combining AppCDS with custom Java runtime images,
as produced using the &lt;a href=&#34;https://docs.oracle.com/en/java/javase/15/docs/specs/man/jlink.html&#34;&gt;jlink&lt;/a&gt; tool added in Java 9.
Combining custom runtime images with AppCDS is very attractive,
in particular when looking at the deployment of Java applications via Linux containers.
Instead of putting the full Java runtime into the container image, you only add those JDK modules which your application actually requires.
(Parts of) what you save in image size by doing so,
can be used for adding an AppCDS archive to your container image.
The result will be a container image which still is smaller than before — and thus is faster to push to a container registry, distribute to worker nodes in a Kubernetes cluster, etc. — and which starts up significantly faster.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Quarkus and Testcontainers</title>
      <link>https://www.morling.dev/blog/quarkus-and-testcontainers/</link>
      <pubDate>Sat, 28 Nov 2020 17:45:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/quarkus-and-testcontainers/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_bonus_schema_creation&#34;&gt;Bonus: Schema Creation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;The &lt;a href=&#34;https://www.testcontainers.org/&#34;&gt;Testcontainers&lt;/a&gt; project is invaluable for spinning up containerized resources during your (JUnit) tests,
e.g. databases or Kafka clusters.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;For users of JUnit 5, the project provides the &lt;a href=&#34;https://www.testcontainers.org/quickstart/junit_5_quickstart/&#34;&gt;&lt;code&gt;@Testcontainers&lt;/code&gt;&lt;/a&gt; extension, which controls the lifecycle of containers used by a test.
When testing a &lt;a href=&#34;https://quarkus.io/&#34;&gt;Quarkus&lt;/a&gt; application though, this is at odds with Quarkus&amp;#39; own &lt;a href=&#34;https://quarkus.io/guides/getting-started-testing#recap-of-http-based-testing-in-jvm-mode&#34;&gt;&lt;code&gt;@QuarkusTest&lt;/code&gt;&lt;/a&gt; extension;
it’s a recommended &lt;a href=&#34;https://bsideup.github.io/posts/testcontainers_fixed_ports/&#34;&gt;best practice&lt;/a&gt; to avoid fixed ports for any containers started by Testcontainers.
Instead, you should rely on Docker to automatically allocate random free ports.
This avoids conflicts between concurrently running tests,
e.g. amongst multiple Postgres containers,
started up by several parallel job runs in a CI environment, all trying to allocate Postgres&amp;#39; default port 5432.
Obtaining the randomly assigned port and passing it into the Quarkus bootstrap process isn’t possible though when combining the two JUnit extensions.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Class Unloading in Layered Java Applications</title>
      <link>https://www.morling.dev/blog/class-unloading-in-layered-java-applications/</link>
      <pubDate>Wed, 14 Oct 2020 17:45:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/class-unloading-in-layered-java-applications/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_do_we_really_need_plug_ins&#34;&gt;Do We Really Need Plug-ins?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_plug_ins_in_layered_java_applications&#34;&gt;Plug-ins in Layered Java Applications&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_class_unloading_in_practice&#34;&gt;Class Unloading in Practice&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_if_things_go_wrong&#34;&gt;If Things Go Wrong&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_learning_more&#34;&gt;Learning More&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Layers are sort of the secret sauce of the Java platform module system (JPMS):
by providing fine-grained control over how individual JPMS modules and their classes are loaded by the JVM,
they enable advanced usages like loading multiple versions of a given module, or dynamically adding and removing modules at application runtime.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;The &lt;a href=&#34;https://www.morling.dev/blog/introducing-layrry-runner-and-api-for-modularized-java-applications/&#34;&gt;Layrry&lt;/a&gt; API and launcher provides a small plug-in API based on top of layers,
which for instance can be used to dynamically add plug-ins contributing new views and widgets to a running JavaFX application.
If such plug-in gets removed from the application again,
all its classes need to be unloaded by the JVM, avoiding an ever-increasing memory consumption if for instance a plug-in gets updated multiple times.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;In this blog post I’m going to explore how to ensure classes from removed plug-in layers are unloaded in a timely manner,
and how to find the culprit in case some class fails to be unloaded.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Building hsdis for OpenJDK 15</title>
      <link>https://www.morling.dev/blog/building-hsdis-for-openjdk-15/</link>
      <pubDate>Mon, 05 Oct 2020 20:30:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/building-hsdis-for-openjdk-15/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Lately I’ve been fascinated by the possibility to analyse the assembly code emitted by the Java JIT (just-in-time) compiler.
So far I had only looked only into Java class files using &lt;em&gt;javap&lt;/em&gt;;
diving into the world of assembly code feels a bit like Alice must have felt when falling down the rabbit whole into wonderland.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Introducing JmFrX: A Bridge From JMX to JDK Flight Recorder</title>
      <link>https://www.morling.dev/blog/introducing-jmfrx-a-bridge-from-jmx-to-jdk-flight-recorder/</link>
      <pubDate>Tue, 18 Aug 2020 17:30:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/introducing-jmfrx-a-bridge-from-jmx-to-jdk-flight-recorder/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_why_jmfrx&#34;&gt;Why JmFrX?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_how_to_use_jmfrx&#34;&gt;How To Use JmFrX&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_customizing_event_formats&#34;&gt;Customizing Event Formats&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_how_it_works&#34;&gt;How It Works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_takeaways&#34;&gt;Takeaways&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;I’m excited to share the news about an open-source utility I’ve been working on lately:
&lt;a href=&#34;https://github.com/gunnarmorling/jmfrx&#34;&gt;JmFrX&lt;/a&gt;,
a tool for capturing JMX data with JDK Flight Recorder.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;When using JMX (&lt;a href=&#34;https://en.wikipedia.org/wiki/Java_Management_Extensions&#34;&gt;Java Management Extensions&lt;/a&gt;), The Java platform’s standard for monitoring and managing applications,
JmFrX allows you to periodically record the attributes from any JMX MBean into &lt;a href=&#34;https://openjdk.java.net/jeps/328&#34;&gt;JDK Flight Recorder&lt;/a&gt; (JFR) files,
which you then can analyse using &lt;a href=&#34;https://openjdk.java.net/projects/jmc/&#34;&gt;JDK Mission Control&lt;/a&gt; (JMC).&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>How I Built a Serverless Search for My Blog</title>
      <link>https://www.morling.dev/blog/how-i-built-a-serverless-search-for-my-blog/</link>
      <pubDate>Wed, 29 Jul 2020 17:30:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/how-i-built-a-serverless-search-for-my-blog/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_why_serverless&#34;&gt;Why Serverless?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_solution_overview&#34;&gt;Solution Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_data_extraction&#34;&gt;Data Extraction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_search_backend_implementation&#34;&gt;Search Backend Implementation&lt;/a&gt;
&lt;ul class=&#34;sectlevel2&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_apache_lucene_in_a_graalvm_native_binary&#34;&gt;Apache Lucene in a GraalVM Native Binary&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_the_search_http_service&#34;&gt;The Search HTTP Service&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_wiring_things_up&#34;&gt;Wiring Things Up&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_deployment_to_aws_lambda&#34;&gt;Deployment to AWS Lambda&lt;/a&gt;
&lt;ul class=&#34;sectlevel2&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_building_quarkus_applications_for_aws_lambda&#34;&gt;Building Quarkus Applications for AWS Lambda&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_identity_and_access_management&#34;&gt;Identity and Access Management&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_performance&#34;&gt;Performance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_cost_control&#34;&gt;Cost Control&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_wrap_up_and_outlook&#34;&gt;Wrap-Up and Outlook&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph teaser&#34;&gt;
&lt;p&gt;I have built a custom search functionality for this blog,
based on Java and the Apache Lucene full-text search library,
compiled into a native binary using the Quarkus framework and GraalVM.
It is deployed as a Serverless application running on AWS Lambda,
providing search results without any significant cold start delay.
If you thought Java wouldn’t be the right language for this job, keep reading;
in this post I’m going to give an overview over the implementation of this feature and my learnings along the way.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Building Class Data Sharing Archives with Apache Maven</title>
      <link>https://www.morling.dev/blog/building-class-data-sharing-archives-with-apache-maven/</link>
      <pubDate>Thu, 11 Jun 2020 17:30:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/building-class-data-sharing-archives-with-apache-maven/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_manually_creating_cds_archives&#34;&gt;Manually Creating CDS Archives&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_using_the_cds_archive&#34;&gt;Using the CDS Archive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_creating_cds_archives_in_your_maven_build&#34;&gt;Creating CDS Archives in Your Maven Build&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_what_do_you_gain&#34;&gt;What Do You Gain?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_wrap_up&#34;&gt;Wrap-Up&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Ahead-of-time compilation (AOT) is &lt;em&gt;the&lt;/em&gt; big topic in the Java ecosystem lately:
by compiling Java code to native binaries, developers and users benefit from vastly improved start-up times and reduced memory usage.
The &lt;a href=&#34;https://www.graalvm.org/&#34;&gt;GraalVM&lt;/a&gt; project made huge progress towards AOT-compiled Java applications,
and &lt;a href=&#34;https://mail.openjdk.java.net/pipermail/discuss/2020-April/005429.html&#34;&gt;Project Leyden&lt;/a&gt; promises to standardize AOT in a future version of the Java platform.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;This makes it easy to miss out on significant performance improvements which have been made on the JVM in recent Java versions,
in particular when it comes to &lt;a href=&#34;https://cl4es.github.io/2019/11/20/OpenJDK-Startup-Update.html&#34;&gt;faster start-up times&lt;/a&gt;.
Besides a range of improvements related to class loading, linking and bytecode verification,
substantial work has been done around &lt;a href=&#34;https://docs.oracle.com/en/java/javase/14/vm/class-data-sharing.html&#34;&gt;class data sharing&lt;/a&gt; (CDS).
Faster start-ups are beneficial in many ways:
shorter turnaround times during development,
quicker time-to-first-response for users in coldstart scenarios,
cost savings when billed by CPU time in the cloud.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;With CDS, class metadata is persisted in an archive file,
which during subsequent application starts is mapped into memory.
This is faster than loading the actual class files, resulting in reduced start-up times.
When starting multiple JVM processes on the same host, read-only archives of class metadata can also be shared between the VMs, so that less memory is consumed overall.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Single Message Transformations - The Swiss Army Knife of Kafka Connect</title>
      <link>https://www.morling.dev/blog/single-message-transforms-swiss-army-knife-of-kafka-connect/</link>
      <pubDate>Thu, 14 May 2020 15:30:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/single-message-transforms-swiss-army-knife-of-kafka-connect/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_format_conversions&#34;&gt;Format Conversions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_ensuring_backwards_compatibility&#34;&gt;Ensuring Backwards Compatibility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_filtering_and_routing&#34;&gt;Filtering and Routing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_tombstone_handling&#34;&gt;Tombstone Handling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_externalizing_large_payloads&#34;&gt;Externalizing Large Payloads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_limitations&#34;&gt;Limitations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_learning_more&#34;&gt;Learning More&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Do you remember Angus &amp;#34;Mac&amp;#34; MacGyver?
The always creative protagonist of the popular 80ies/90ies TV show, who could solve about any problem with nothing more than a Swiss Army knife, duct tape, shoe strings and a paper clip?&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;The single message transformations (SMTs) of Kafka Connect are almost as versatile as MacGyver’s Swiss Army knife:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;ulist&#34;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;How to change the timezone or format of date/time message fields?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;How to change the topic a specific message gets sent to?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;How to filter out specific records?&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;SMTs can be the answer to these and many other questions that come up in the context of Kafka Connect.
Applied to source or sink connectors,
SMTs allow to modify Kafka records before they are sent to Kafka, or after they are consumed from a topic, respectively.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>The Emitter Parameter Pattern for Flexible SPI Contracts</title>
      <link>https://www.morling.dev/blog/emitter-parameter-pattern-for-flexible-spis/</link>
      <pubDate>Mon, 04 May 2020 17:30:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/emitter-parameter-pattern-for-flexible-spis/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_an_example&#34;&gt;An Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_the_emitter_parameter_pattern&#34;&gt;The Emitter Parameter Pattern&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;For libraries and frameworks it’s a common requirement to make specific aspects customizeable via &lt;a href=&#34;https://en.wikipedia.org/wiki/Service_provider_interface&#34;&gt;service provider interfaces&lt;/a&gt; (SPIs):
contracts to be implemented by the application developer, which then are invoked by framework code,
adding new or replacing existing functionality.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Often times, the method implementations of such an SPI need to return value(s) to the framework.
An alternative to return values are &amp;#34;emitter parameters&amp;#34;:
passed by the framework to the SPI method, they offer an &lt;em&gt;API&lt;/em&gt; for receiving value(s) via method calls.
Certainly not revolutionary or even a new idea,
I find myself using emitter parameters more and more in libraries and frameworks I work on.
Hence I’d like to discuss some advantages I perceive about the emitter parameter pattern.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Plug-in Architectures With Layrry and the Java Module System</title>
      <link>https://www.morling.dev/blog/plugin-architectures-with-layrry-and-the-java-module-system/</link>
      <pubDate>Tue, 21 Apr 2020 18:54:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/plugin-architectures-with-layrry-and-the-java-module-system/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_an_example_the_greeter_cli_app&#34;&gt;An Example: The Greeter CLI App&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_application_plug_ins_with_layrry&#34;&gt;Application Plug-ins With Layrry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_finding_plug_in_implementations_with_the_java_service_loader&#34;&gt;Finding Plug-in Implementations With the Java Service Loader&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_seeing_it_in_action&#34;&gt;Seeing it in Action&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Making applications extensible with some form of plug-ins is a very common pattern in software design:
based on well-defined APIs provided by the application core, plug-ins can customize an application’s behavior and provide new functionality.
Examples include desktop applications like IDEs or web browsers, build tools such as Apache Maven or Gradle, as well as server-side applications such as Apache Kafka Connect,
a runtime for Kafka connectors plug-ins.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;In this post I’m going to explore how the &lt;a href=&#34;https://www.jcp.org/en/jsr/detail?id=376&#34;&gt;Java Platform Module System&lt;/a&gt;&amp;#39;s notion of module layers can be leveraged for implementing plug-in architectures on the JVM.
We’ll also discuss how &lt;a href=&#34;https://github.com/moditect/layrry&#34;&gt;Layrry&lt;/a&gt;, a launcher and runtime for layered Java applications, can help with this task.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Introducing Layrry: A Launcher and API for Modularized Java Applications</title>
      <link>https://www.morling.dev/blog/introducing-layrry-runner-and-api-for-modularized-java-applications/</link>
      <pubDate>Sun, 29 Mar 2020 21:31:00 +0200</pubDate>
      
      <guid>https://www.morling.dev/blog/introducing-layrry-runner-and-api-for-modularized-java-applications/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_why_layrry&#34;&gt;Why Layrry?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_an_example&#34;&gt;An Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_module_layers_to_the_rescue&#34;&gt;Module Layers to the Rescue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_the_layrry_launcher&#34;&gt;The Layrry Launcher&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_using_the_layrry_api&#34;&gt;Using the Layrry API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_next_steps&#34;&gt;Next Steps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;One of the biggest changes in recent Java versions has been the introduction of the &lt;a href=&#34;http://openjdk.java.net/projects/jigsaw/spec/&#34;&gt;module system&lt;/a&gt; in Java 9.
It allows to organize Java applications and their dependencies in strongly encapsulated modules, utilizing explicit and well-defined module APIs and relationships.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;In this post I’m going to introduce the &lt;a href=&#34;https://github.com/moditect/layrry&#34;&gt;Layrry&lt;/a&gt; open-source project, a launcher and Java API for executing modularized Java applications.
Layrry helps Java developers to assemble modularized applications from dependencies using their Maven coordinates and execute them using module layers.
Layers go beyond the capabilities of the &amp;#34;flat&amp;#34; module path specified via the &lt;em&gt;--module-path&lt;/em&gt; parameter of the &lt;em&gt;java&lt;/em&gt; command,
e.g. allowing to use multiple versions of one module within one and the same application.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Reworking Git Branches with git filter-branch</title>
      <link>https://www.morling.dev/blog/reworking-git-branches-with-git-filter-branch/</link>
      <pubDate>Mon, 16 Mar 2020 00:00:10 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/reworking-git-branches-with-git-filter-branch/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_the_problem&#34;&gt;The Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_the_solution&#34;&gt;The Solution&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;Within &lt;a href=&#34;https://debezium.io/&#34;&gt;Debezium&lt;/a&gt;, the project I’m working on at Red Hat, we recently encountered an &amp;#34;interesting&amp;#34; situation where we had to resolve a rather difficult merge conflict.
As others where interested in how we addressed the issue, and also for our own future reference,
I’m going to give a quick run down of the problem we encountered and how we solved it.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Monitoring REST APIs with Custom JDK Flight Recorder Events</title>
      <link>https://www.morling.dev/blog/rest-api-monitoring-with-custom-jdk-flight-recorder-events/</link>
      <pubDate>Wed, 29 Jan 2020 15:30:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/rest-api-monitoring-with-custom-jdk-flight-recorder-events/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_custom_flight_recorder_events&#34;&gt;Custom Flight Recorder Events&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_creating_jfr_recordings&#34;&gt;Creating JFR Recordings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_event_settings&#34;&gt;Event Settings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_jfr_event_streaming&#34;&gt;JFR Event Streaming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_microprofile_metrics&#34;&gt;MicroProfile Metrics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_summary_and_related_work&#34;&gt;Summary and Related Work&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;The &lt;a href=&#34;https://openjdk.java.net/jeps/328&#34;&gt;JDK Flight Recorder&lt;/a&gt; (JFR) is an invaluable tool for gaining deep insights into the performance characteristics of Java applications.
Open-sourced in JDK 11, JFR provides a low-overhead framework for collecting events from Java applications, the JVM and the operating system.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;In this blog post we’re going to explore how custom, application-specific JFR events can be used to monitor a REST API, allowing to track request counts, identify long-running requests and more.
We’ll also discuss how the JFR &lt;a href=&#34;https://openjdk.java.net/jeps/349&#34;&gt;Event Streaming API&lt;/a&gt; new in Java 14 can be used to export live events,
making them available for monitoring and alerting via tools such as Prometheus and Grafana.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Enforcing Java Record Invariants With Bean Validation</title>
      <link>https://www.morling.dev/blog/enforcing-java-record-invariants-with-bean-validation/</link>
      <pubDate>Mon, 20 Jan 2020 17:30:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/enforcing-java-record-invariants-with-bean-validation/</guid>
      <description>Table of Contents Record Invariants and Bean Validation Implementation Advantages Limitations Wrap-Up Record types are one of the most awaited features in Java 14; they promise to &amp;#34;provide a compact syntax for declaring classes which are transparent holders for shallowly immutable data&amp;#34;. One example where records should be beneficial are data transfer objects (DTOs), as e.g. found in the remoting layer of enterprise applications. Typically, certain rules should be applied to the attributes of such DTO, e.</description>
    </item>
    
    <item>
      <title>Using Java 13 Text Blocks (Only) for Your Tests</title>
      <link>https://www.morling.dev/blog/using-java-13-text-blocks-for-tests/</link>
      <pubDate>Mon, 13 Jan 2020 17:30:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/using-java-13-text-blocks-for-tests/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_an_example&#34;&gt;An Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_configuration&#34;&gt;Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_should_you_do_this&#34;&gt;Should You Do This?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;When Java 9 was introduced in 2017,
it was the last major version published under the old release scheme.
Since then, a &lt;a href=&#34;https://www.infoq.com/news/2017/09/Java6Month/&#34;&gt;six month release cadence&lt;/a&gt; has been adopted.
This means developers don’t have to wait years for new APIs and language features,
but they can get their hands onto the latest additions twice a year.
In this post I’d like to describe how you can try out new language features such as &lt;a href=&#34;http://openjdk.java.net/jeps/355&#34;&gt;Java 13 text blocks&lt;/a&gt; in the test code of your project,
while keeping your main code still compatible with older Java versions.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Quarkus Qute – A Test Ride</title>
      <link>https://www.morling.dev/blog/quarkus-qute-test-ride/</link>
      <pubDate>Fri, 03 Jan 2020 10:00:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/quarkus-qute-test-ride/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_the_basics&#34;&gt;The Basics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_combining_html_and_data_apis&#34;&gt;Combining HTML and Data APIs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_template_organization&#34;&gt;Template Organization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_error_handling&#34;&gt;Error Handling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_search&#34;&gt;Search&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_smoother_user_experience_via_unpoly&#34;&gt;Smoother User Experience via Unpoly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_bonus_using_webjars&#34;&gt;Bonus: Using WebJars&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_wrap_up&#34;&gt;Wrap Up&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;One of the long-awaited features in Quarkus was support for server-side templating:
until recently, Quarkus supported only client-side web frameworks which obtain there data by calling a REST API on the backend.
This has changed with &lt;a href=&#34;https://quarkus.io/blog/quarkus-1-1-0-final-released/&#34;&gt;Quarkus 1.1&lt;/a&gt;: it comes with a brand-new template engine named &lt;a href=&#34;https://quarkus.io/guides/qute&#34;&gt;Qute&lt;/a&gt;,
which allows to build web applications using server-side templates.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Automatically Deploying a Hugo Website via GitHub Actions</title>
      <link>https://www.morling.dev/blog/automatically-deploying-hugo-website-via-github-actions/</link>
      <pubDate>Thu, 26 Dec 2019 10:00:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/automatically-deploying-hugo-website-via-github-actions/</guid>
      <description>&lt;div id=&#34;toc&#34; class=&#34;toc&#34;&gt;
&lt;div id=&#34;toctitle&#34;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&#34;sectlevel1&#34;&gt;
&lt;li&gt;&lt;a href=&#34;#_github_actions_to_the_rescue&#34;&gt;GitHub Actions To the Rescue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_registering_a_deploy_key&#34;&gt;Registering a Deploy Key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_defining_the_workflow&#34;&gt;Defining the Workflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;As a software engineer, I like to automate tedious tasks as much as possible.
The deployment of this website is no exception:
it is built using the &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt; static site generator and hosted on &lt;a href=&#34;https://pages.github.com/&#34;&gt;GitHub Pages&lt;/a&gt;;
so wouldn’t it be nice if the rendered website would automatically be published whenever an update is pushed to its source code repository?&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Time for a New Blog</title>
      <link>https://www.morling.dev/blog/time-for-new-blog/</link>
      <pubDate>Thu, 26 Dec 2019 10:00:00 +0100</pubDate>
      
      <guid>https://www.morling.dev/blog/time-for-new-blog/</guid>
      <description>&lt;div class=&#34;paragraph&#34;&gt;
&lt;p&gt;It has been quite a while since the last post on my old &lt;a href=&#34;http://musingsofaprogrammingaddict.blogspot.com/&#34;&gt;personal blog&lt;/a&gt;;
since then, I’ve mostly focused on writing about my day-work on the &lt;a href=&#34;https://debezium.io/blog/&#34;&gt;Debezium blog&lt;/a&gt; as well as &lt;a href=&#34;https://in.relation.to/gunnar-morling/&#34;&gt;some posts&lt;/a&gt; about more general technical topics on the Hibernate team blog.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
  </channel>
</rss>
