<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Johannes Bechberger on foojay.io - Friends Of OpenJDK</title><link>https://foojay.io/today/author/johannes-bechberger/</link><description>Articles written by Johannes Bechberger on foojay.io - Friends Of OpenJDK</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Mon, 13 Apr 2026 06:35:00 +0000</lastBuildDate><atom:link href="https://foojay.io/today/author/johannes-bechberger/index.xml" rel="self" type="application/rss+xml"/><item><title>Foojay Podcast #93: Update Your JDK, Read More Code, and Talk to Your Users: Interviews From VoxxedDays Amsterdam</title><link>https://foojay.io/today/foojay-podcast-93/</link><pubDate>Mon, 13 Apr 2026 06:35:00 +0000</pubDate><guid>https://foojay.io/today/foojay-podcast-93/</guid><description>&lt;p&gt;In this episode of the Foojay Podcast, we&amp;rsquo;re bringing you something special: a full batch of hallway-track conversations recorded live at VoxxedDays Amsterdam.&lt;/p&gt;&#10;&lt;p&gt;Fifteen guests, one conference, and one theme that kept coming back, whether we planned it or not: Java has grown up quietly, steadily, and in ways that still surprise people who haven&amp;rsquo;t looked lately. We talked about migrating between versions, new features in the latest Java releases, authorization done right, AI-assisted coding, cryptography, containers, open-source contributions, GDPR data experiments, and, yes, the things people hate about Java but secretly love.&lt;/p&gt;</description></item><item><title>CAP in the Pocket</title><link>https://foojay.io/today/cap-in-the-pocket-developing-java-applications-on-your-phone/</link><pubDate>Mon, 07 Jul 2025 15:27:26 +0000</pubDate><guid>https://foojay.io/today/cap-in-the-pocket-developing-java-applications-on-your-phone/</guid><description>&lt;p&gt;Smartphones are more powerful then ever, with processors rivaling old laptops. So let&amp;rsquo;s try to use them like a laptop to develop web-applications on the go.&lt;/p&gt;&#10;&lt;p&gt;Below I&amp;rsquo;ll show you how to do use run and develop a &lt;a href="https://cap.cloud.sap/docs/java/" target="_blank" rel="noopener noreferrer"&gt;CAP Java&lt;/a&gt; &lt;a href="https://spring.io/projects/spring-boot" target="_blank" rel="noopener noreferrer"&gt;Spring Boot&lt;/a&gt; application on your smartphone and how to run &lt;a href="https://code.visualstudio.com/" target="_blank" rel="noopener noreferrer"&gt;VSCode&lt;/a&gt; locally to develop and modify it. This, of course, works only on Android phones, as they are a Linux at their core.&#10;&lt;img src="https://foojay.io/today/cap-in-the-pocket-developing-java-applications-on-your-phone/Screenshot-May-8-2025-1_28_58-PM-2000x90-26d30ae3.png" alt="" width="1600" height="720" loading="lazy" decoding="async"&gt;&lt;/p&gt;</description></item><item><title>A Glance into JFR Class and Method Tagging</title><link>https://foojay.io/today/a-glance-into-jfr-class-and-method-tagging/</link><pubDate>Mon, 17 Feb 2025 09:26:02 +0000</pubDate><guid>https://foojay.io/today/a-glance-into-jfr-class-and-method-tagging/</guid><description>&lt;p&gt;Ever wonder how the JDK Flight Recorder (JFR) keeps track of the classes and methods it has collected for stack traces and more?&lt;/p&gt;&#10;&lt;p&gt;In this short article, I&amp;rsquo;ll explore JFR tagging and how it works in the OpenJDK.&lt;/p&gt;&#10;&lt;h2 id="tags"&gt;Tags&lt;/h2&gt;&#10;&lt;p&gt;JFR files consist of self-contained chunks. Every chunk contains:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;metadata&lt;/li&gt;&#10;&lt;li&gt;events&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://mail.openjdk.org/pipermail/hotspot-jfr-dev/2020-February/001154.html" target="_blank" rel="noopener noreferrer"&gt;mappings of IDs to actual values&lt;/a&gt;, the IDs are used in the events in place of stack traces, classes, methods, strings, &amp;hellip;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;The maximum chunk size is usually 12MB, but you can configure it:&lt;/p&gt;</description></item><item><title>The slow Death of the onjcmd Debugger Feature</title><link>https://foojay.io/today/the-slow-death-of-the-onjcmd-debugger-feature/</link><pubDate>Sat, 18 Jan 2025 10:47:30 +0000</pubDate><guid>https://foojay.io/today/the-slow-death-of-the-onjcmd-debugger-feature/</guid><description>&lt;p&gt;Almost to the day, one and a quarter years ago, I published my blog post called &lt;a href="https://foojay.io/today/level-up-your-java-debugging-skills-with-on-demand-debugging/"&gt;Level-up your Java Debugging Skills with on-demand Debugging&lt;/a&gt;. In this artucle, I wrote about multiple rarely known and rarely used features of the Java debugging agent, including the onjcmd feature.&lt;/p&gt;&#10;&lt;p&gt;To quote my own article:&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;h2 id="jcmd-triggered-debugging"&gt;JCmd triggered debugging&lt;/h2&gt;&#10;&lt;p&gt;There are often cases where the code that you want to debug is executed later in your program&amp;rsquo;s run or after a specific issue appears. So don&amp;rsquo;t waste time running the debugging session from the start of your program, but use the &lt;code&gt;onjcmd=y&lt;/code&gt; option to tell the JDWP agent to wait with the debugging session till it is triggered via &lt;code&gt;jcmd&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Who instruments the instrumenters?</title><link>https://foojay.io/today/who-instruments-the-instrumenters/</link><pubDate>Thu, 30 May 2024 16:25:45 +0000</pubDate><guid>https://foojay.io/today/who-instruments-the-instrumenters/</guid><description>&lt;h2 id="fixing-bugs-in-spring-boot-and-mockito-by-instrumenting-them"&gt;Fixing bugs in Spring Boot and Mockito by instrumenting them&lt;/h2&gt;&#10;&lt;p&gt;Have you ever wondered how libraries like &lt;a href="https://spring.io/" target="_blank" rel="noopener noreferrer"&gt;Spring&lt;/a&gt; and &lt;a href="https://site.mockito.org/" target="_blank" rel="noopener noreferrer"&gt;Mockito&lt;/a&gt; modify your code at run-time to implement all their advanced features?&lt;/p&gt;&#10;&lt;p&gt;Wouldn&amp;rsquo;t it be cool to get a peek behind the curtains?&lt;/p&gt;&#10;&lt;p&gt;This is the premise of my &lt;a href="https://github.com/parttimenerd/meta-agent" target="_blank" rel="noopener noreferrer"&gt;meta-agent&lt;/a&gt;, a Java agent to instrument instrumenters, to get these insights and what this blog post is about.&lt;/p&gt;&#10;&lt;p&gt;This article is a collaboration with &lt;a href="https://www.linkedin.com/in/mika%C3%ABl-francoeur/" target="_blank" rel="noopener noreferrer"&gt;Mikaël Francoeur&lt;/a&gt;, who had the idea for the meta-agent and wrote most of this post. So it&amp;rsquo;s my first ever post-collaboration. But I start with a short introduction to the agent itself before Mikaël takes over with real-world examples.&lt;/p&gt;</description></item><item><title>Hello eBPF: XDP-based Packet Filter (9)</title><link>https://foojay.io/today/hello-ebpf-xdp-based-packet-filter-9/</link><pubDate>Mon, 13 May 2024 07:13:38 +0000</pubDate><guid>https://foojay.io/today/hello-ebpf-xdp-based-packet-filter-9/</guid><description>&lt;p&gt;&lt;strong&gt;Welcome back to my &lt;a href="https://mostlynerdless.de/blog/tag/hello-ebpf/" target="_blank" rel="noopener noreferrer"&gt;series on ebpf&lt;/a&gt;. In the last blog post, we learned how &lt;a href="https://mostlynerdless.de/blog/2024/04/09/hello-ebpf-generating-c-code-8/" target="_blank" rel="noopener noreferrer"&gt;annotation processors can&lt;/a&gt; generate C code, simplifying writing eBPF applications.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;This week, we&amp;rsquo;ll use this work together with new support for XDP to create a simple package blocker for eBPF (&lt;a href="https://github.com/parttimenerd/hello-ebpf/blob/main/bpf/src/main/java/me/bechberger/ebpf/samples/XDPPacketFilter.java" target="_blank" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;):&lt;/p&gt;&#10;&lt;pre class="EnlighterJSRAW" data-enlighter-language="shell"&gt;./run_bpf.sh XDPPacketFilter twitter.com&lt;/pre&gt;&lt;p&gt;This blocks all incoming IPv4 packages from &lt;code&gt;twitter.com&lt;/code&gt;. We see how it works in this blog post. First, we start with some background on networking and explain what XDP is.&lt;/p&gt;</description></item><item><title>Hello eBPF: Generating C Code (8)</title><link>https://foojay.io/today/hello-ebpf-generating-c-code-8/</link><pubDate>Wed, 24 Apr 2024 13:11:40 +0000</pubDate><guid>https://foojay.io/today/hello-ebpf-generating-c-code-8/</guid><description>&lt;p&gt;&lt;strong&gt;Welcome back to my &lt;a href="https://mostlynerdless.de/blog/tag/hello-ebpf/" target="_blank" rel="noopener noreferrer"&gt;series on ebpf&lt;/a&gt;. In the last article, we learned how to&lt;a href="https://mostlynerdless.de/blog/2024/03/25/hello-ebpf-auto-layouting-structs-7/" target="_blank" rel="noopener noreferrer"&gt;auto-layout struct members and auto-generate BPFStructTypes for annotated Java records&lt;/a&gt;. We&amp;rsquo;re going to extend this work today.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;This is a rather short article, but the implementation and fixing all the bugs took far more time then expected.&lt;/em&gt;&lt;/p&gt;&#10;&lt;h2 id="generating-struct-definitions"&gt;Generating Struct Definitions&lt;/h2&gt;&#10;&lt;p&gt;We saw in the last article how powerful Java annotation processing is for generating Java code; this week, we&amp;rsquo;ll tackle the generation of C code: In the previous article, we still had to write the C struct and map definitions ourselves, but writing&lt;/p&gt;</description></item><item><title>Hello eBPF: Auto Layouting Structs (7)</title><link>https://foojay.io/today/hello-ebpf-auto-layouting-structs-7/</link><pubDate>Sun, 14 Apr 2024 16:19:50 +0000</pubDate><guid>https://foojay.io/today/hello-ebpf-auto-layouting-structs-7/</guid><description>&lt;p&gt;&lt;strong&gt;Welcome back to my &lt;a href="https://mostlynerdless.de/blog/tag/hello-ebpf/" target="_blank" rel="noopener noreferrer"&gt;series on ebpf&lt;/a&gt;. In the last article, &lt;a href="https://mostlynerdless.de/blog/2024/03/12/hello-ebpf-ring-buffers-in-libbpf-6/" target="_blank" rel="noopener noreferrer"&gt;we learned how to use ring buffers with libbpf&lt;/a&gt; for efficient communication. This week, we&amp;rsquo;re looking into the memory layout and alignment of structs transferred between the kernel and user-land.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Alignment is essential; it specifies how the compiler layouts the structs and variables and where to put the data in memory. Take, for example, the struct that we defined in the previous article in the &lt;a href="https://github.com/parttimenerd/hello-ebpf/blob/main/bpf/src/main/java/me/bechberger/ebpf/samples/RingSample.java" target="_blank" rel="noopener noreferrer"&gt;RingSample&lt;/a&gt;:&lt;/p&gt;</description></item><item><title>To Brussels, Canada and back</title><link>https://foojay.io/today/to-brussels-canada-and-back/</link><pubDate>Tue, 26 Mar 2024 10:53:11 +0000</pubDate><guid>https://foojay.io/today/to-brussels-canada-and-back/</guid><description>&lt;p&gt;Last year was my first year blogging, speaking at conferences, meeting incredible people, and seeing places I&amp;rsquo;ve never been before.&lt;/p&gt;&#10;&lt;p&gt;It was at times quite arduous but at the same time energizing, as you can read in my post Looking back on one year of speaking and blogging. I didn&amp;rsquo;t want it to be a one-off year, so I dutifully started a new article series on eBPF and applied for conferences&amp;hellip;&lt;/p&gt;</description></item><item><title>Hello eBPF: Ring buffers in libbpf (6)</title><link>https://foojay.io/today/hello-ebpf-ring-buffers-in-libbpf-6/</link><pubDate>Tue, 19 Mar 2024 17:54:22 +0000</pubDate><guid>https://foojay.io/today/hello-ebpf-ring-buffers-in-libbpf-6/</guid><description>&lt;p&gt;&lt;strong&gt;Welcome back to my article series on eBPF. Some weeks ago, &lt;a href="https://foojay.io/today/hello-ebpf-developing-ebpf-apps-in-java-1/"&gt;I got started in using libbpf instead of libbcc&lt;/a&gt;. This week, I show you how to use ring buffers, port the code from Ansil H&amp;rsquo;s blog post eBPF for Linux Admins: Part IX from C to Java, and add tests to the underlying map implementation.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;My libbpf-based implementation advances slower than the bcc-based, as I thoroughly test all added functionality and develop a proper Java API, not just a clone.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Hello eBPF: First steps with libbpf (5)</title><link>https://foojay.io/today/hello-ebpf-first-steps-with-libbpf-5/</link><pubDate>Thu, 07 Mar 2024 13:51:35 +0000</pubDate><guid>https://foojay.io/today/hello-ebpf-first-steps-with-libbpf-5/</guid><description>&lt;p&gt;&lt;strong&gt;Welcome back to my blog series on eBPF. Two weeks ago, I showed you &lt;a href="https://mostlynerdless.de/blog/2024/02/12/hello-ebpf-tail-calls-and-your-first-ebpf-application-4/" target="_blank" rel="noopener noreferrer"&gt;how to write your own eBPF application using my hello-ebpf library based on libbcc&lt;/a&gt;. This week, I show you why using libbcc is not the best idea and start working with the newer &lt;a href="https://libbpf.readthedocs.io/en/latest/" target="_blank" rel="noopener noreferrer"&gt;libbpf&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;With my current libbcc-based approach, we essentially embed the executed eBPF program into our programs as a string into our applications and compile them on the fly for every run:&lt;/p&gt;</description></item><item><title>Hello eBPF: Tail calls and your first eBPF application (4)</title><link>https://foojay.io/today/hello-ebpf-tail-calls-and-your-first-ebpf-application-4/</link><pubDate>Fri, 23 Feb 2024 08:44:51 +0000</pubDate><guid>https://foojay.io/today/hello-ebpf-tail-calls-and-your-first-ebpf-application-4/</guid><description>&lt;p&gt;Welcome back to my series on eBPF. Two weeks ago, I showed you &lt;a href="https://foojay.io/today/hello-ebpf-recording-data-in-event-buffers-3/"&gt;how to use perf event buffers to stream data from the eBPF program to the Java application&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;This week, we will finish chapter 2 of the Learning eBPF book, learn how to use tail calls and the hello-ebpf project as a library and implement one of the book&amp;rsquo;s exercises.&lt;/p&gt;&#10;&lt;p&gt;We start with function and tail calls:&lt;/p&gt;&#10;&lt;h2 id="function-calls"&gt;Function Calls&lt;/h2&gt;&#10;&lt;p&gt;Regular C programs are divided into functions that call each other; so far in this series, all our eBPF programs consisted of just a single function that calls kernel functions. But can we call other eBPF functions? End of 2017, Daniel Borkman et al. introduced the ability to call other functions defined in eBPF:&lt;/p&gt;</description></item><item><title>Is JDWP's onjcmd feature worth using?</title><link>https://foojay.io/today/is-jdwps-onjcmd-feature-worth-using/</link><pubDate>Mon, 12 Feb 2024 11:25:22 +0000</pubDate><guid>https://foojay.io/today/is-jdwps-onjcmd-feature-worth-using/</guid><description>&lt;p&gt;A few months ago, I told you about the onjcmd feature in my blog post &lt;a href="https://foojay.io/today/level-up-your-java-debugging-skills-with-on-demand-debugging/"&gt;Level-up your Java Debugging Skills with on-demand Debugging&lt;/a&gt; (which is coming to JavaLand 2024). The short version is that adding onjcmd=y to the list of JDWP options allows you to delay accepting the incoming connection request in the JDWP agent until &lt;code&gt;jcmd &amp;lt;JVM pid&amp;gt; VM.start_java_debugging&lt;/code&gt; is called.&lt;/p&gt;&#10;&lt;p&gt;The main idea is that the JDWP agent&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;only listens on the debugging port after it is triggered, which could have some security benefits&lt;/li&gt;&#10;&lt;li&gt;and that the JDWP agent causes less overhead while waiting, compared to just accepting connections from the beginning.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;The first point is debatable; one can find arguments for and against it. But for the second point, we can run some benchmarks. After renewed discussions, I started benchmarking to conclude whether the onjcmd feature improves on-demand debugging performance. &lt;em&gt;Spoiler alert: It doesn&amp;rsquo;t.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Hello eBPF: Recording data in event buffers (3)</title><link>https://foojay.io/today/hello-ebpf-recording-data-in-event-buffers-3/</link><pubDate>Fri, 02 Feb 2024 14:45:02 +0000</pubDate><guid>https://foojay.io/today/hello-ebpf-recording-data-in-event-buffers-3/</guid><description>&lt;p&gt;&lt;strong&gt;Welcome back to my article series on eBPF. Last week, I showed you how the &lt;a href="https://foojay.io/today/hello-ebpf-recording-data-in-basic-ebpf-maps-2/"&gt;eBPF program and Java application can communicate using eBPF maps&lt;/a&gt;. This allowed us to write an application that counts the number of &lt;code&gt;execve&lt;/code&gt; calls per user.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;This week, I&amp;rsquo;ll show you briefly how to use another kind of eBPF maps, the perf event buffer, and run tests with docker and &lt;a href="https://junit.org/junit5/docs/current/user-guide/" target="_blank" rel="noopener noreferrer"&gt;JUnit 5&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;This article is shorter than the previous one as I&amp;rsquo;m preparing for the OpenJDK committers workshop in Brussels and my &lt;a href="https://fosdem.org/2024/schedule/speaker/WS77F8/" target="_blank" rel="noopener noreferrer"&gt;Python and Java DevRoom talks&lt;/a&gt; at FOSDEM. I&amp;rsquo;m happy to meet my readers; say hi when you&amp;rsquo;re there.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Hello eBPF: Recording data in basic eBPF maps (2)</title><link>https://foojay.io/today/hello-ebpf-recording-data-in-basic-ebpf-maps-2/</link><pubDate>Thu, 18 Jan 2024 15:50:44 +0000</pubDate><guid>https://foojay.io/today/hello-ebpf-recording-data-in-basic-ebpf-maps-2/</guid><description>&lt;p&gt;Welcome back to my article series on eBPF.&lt;/p&gt;&#10;&lt;p&gt;Last week, I introduced &lt;a href="https://mostlynerdless.de/blog/2023/12/31/hello-ebpf-developing-ebpf-apps-in-java-1/" target="_blank" rel="noopener noreferrer"&gt;eBPF, the series, and the project&lt;/a&gt; and showed how you can write a &lt;a href="https://github.com/parttimenerd/hello-ebpf/blob/spotless/bcc/src/main/java/me/bechberger/ebpf/samples/chapter2/HelloWorld.java" target="_blank" rel="noopener noreferrer"&gt;simple eBPF application&lt;/a&gt; with Java that prints &amp;ldquo;Hello World!&amp;rdquo; whenever a process calls &lt;code&gt;execve&lt;/code&gt;:&lt;/p&gt;&#10;&lt;pre class="EnlighterJSRAW" data-enlighter-language="java"&gt;public class HelloWorld {&#10; public static void main(String[] args) {&#10; try (BPF b = BPF.builder(&amp;#34;&amp;#34;&amp;#34;&#10; int hello(void *ctx) {&#10; bpf_trace_printk(&amp;#34;Hello, World!&amp;#34;);&#10; return 0;&#10; }&#10; &amp;#34;&amp;#34;&amp;#34;).build()) {&#10; var syscall = b.get_syscall_fnname(&amp;#34;execve&amp;#34;);&#10; b.attach_kprobe(syscall, &amp;#34;hello&amp;#34;);&#10; b.trace_print();&#10; }&#10; }&#10;}&lt;/pre&gt;&lt;p&gt;But what if we want to send more information from our eBPF program to our userland application than just some logs?&lt;/p&gt;</description></item><item><title>Hello eBPF: Developing eBPF Apps in Java (1)</title><link>https://foojay.io/today/hello-ebpf-developing-ebpf-apps-in-java-1/</link><pubDate>Tue, 09 Jan 2024 16:34:56 +0000</pubDate><guid>https://foojay.io/today/hello-ebpf-developing-ebpf-apps-in-java-1/</guid><description>&lt;p&gt;&lt;strong&gt;eBPF allows you to attach programs directly to hooks in the Linux kernel without loading kernel modules, like hooks for networking or executing programs.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;This has historically been used for writing custom package filters in firewalls. Still, nowadays, it is used for monitoring and tracing, becoming an ever more critical building block of modern observability tools. To quote from &lt;a href="https://ebpf.io/what-is-ebpf/" target="_blank" rel="noopener noreferrer"&gt;ebpf.io&lt;/a&gt;:&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;/blockquote&gt;&#10;&lt;figure class="aligncenter size-full is-resized"&gt;&#10; &lt;img src="https://foojay.io/today/hello-ebpf-developing-ebpf-apps-in-java-1/image-20-e3856a18.png" alt="" style="width:524px;height:auto" loading="lazy" class="is-zoomable"&gt;&lt;/figure&gt;&#10;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;Historically, the operating system has always been an ideal place to implement observability, security, and networking functionality due to the kernel&amp;rsquo;s privileged ability to oversee and control the entire system. At the same time, an operating system kernel is hard to evolve due to its central role and high requirement towards stability and security. The rate of innovation at the operating system level has thus traditionally been lower compared to functionality implemented outside of the operating system.&lt;a href="https://ebpf.io/static/e293240ecccb9d506587571007c36739/f2674/overview.png" target="_blank" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Looking Back on One Year of Speaking and Blogging</title><link>https://foojay.io/today/looking-back-on-one-year-of-speaking-and-blogging/</link><pubDate>Fri, 05 Jan 2024 17:49:04 +0000</pubDate><guid>https://foojay.io/today/looking-back-on-one-year-of-speaking-and-blogging/</guid><description>&lt;p&gt;&lt;strong&gt;2023 was an adventurous year for me: I came into my blogging rhythm, blogging every one to two weeks, resulting in 39 articles, many of them on Foojay.io, spoke at my first conferences, around 14 overall, 22 if you include JUGs and online conferences, and continued working on my &lt;a href="https://mostlynerdless.de/blog/2023/12/04/profiling-maven-projects-with-my-intellij-profiler-plugin/" target="_blank" rel="noopener noreferrer"&gt;IntelliJ plugin&lt;/a&gt;, as well as my proposal for a &lt;a href="https://openjdk.org/jeps/435" target="_blank" rel="noopener noreferrer"&gt;new profiling API&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;This article is a recollection of the year&amp;rsquo;s highlights. If you want a complete list of my presentations, visit my &lt;a href="https://mostlynerdless.de/talks/" target="_blank" rel="noopener noreferrer"&gt;Talks&lt;/a&gt; page or the &lt;a href="https://github.com/SAP/SapMachine/wiki/Presentations" target="_blank" rel="noopener noreferrer"&gt;Presentations&lt;/a&gt; page in the SapMachine Wiki.&lt;/p&gt;</description></item><item><title>Using AI to Create JFR Event Descriptions</title><link>https://foojay.io/today/using-ai-to-create-jfr-event-descriptions/</link><pubDate>Fri, 29 Dec 2023 05:42:16 +0000</pubDate><guid>https://foojay.io/today/using-ai-to-create-jfr-event-descriptions/</guid><description>&lt;p&gt;JFR (JDK Flight Recorder) is the default profiler for OpenJDK (see &lt;a href="https://mostlynerdless.de/blog/category/java-servicability/profiling/" target="_blank" rel="noopener noreferrer"&gt;my other blog posts&lt;/a&gt; for more information).&lt;/p&gt;&#10;&lt;p&gt;What makes JFR stand out from the other profilers is the ability to log many, many different events that contain lots of information, like information on class loading, JIT compilation, and garbage collection.&lt;/p&gt;&#10;&lt;p&gt;You can see a list of all available events on my &lt;a href="https://sap.github.io/SapMachine/jfrevents/" target="_blank" rel="noopener noreferrer"&gt;JFR Event Collection&lt;/a&gt; website:&#10;&lt;img src="https://foojay.io/today/using-ai-to-create-jfr-event-descriptions/image-10-2000x1604-8922453a.jpg" alt="" width="1600" height="1283" loading="lazy" decoding="async"&gt;&lt;/p&gt;&#10;&lt;p&gt;This website gives an overview of the events, with descriptions from the OpenJDK, their properties, examples, configurations, and the JDK versions in which every event is present. However, few descriptions are available, and the available texts are mostly single sentences.&lt;/p&gt;</description></item><item><title>Writing C Code in Java</title><link>https://foojay.io/today/writing-c-code-in-java/</link><pubDate>Wed, 20 Dec 2023 09:21:56 +0000</pubDate><guid>https://foojay.io/today/writing-c-code-in-java/</guid><description>&lt;p&gt;&lt;img src="https://foojay.io/today/writing-c-code-in-java/panama-2000x981-0ceeab3a.jpg" alt="" width="1600" height="785" loading="lazy" decoding="async"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;The Foreign Function &amp;amp; Memory API (also called Project Panama) has come a long way since it started. You can find the latest version implemented in JDK 21 as a preview feature (use &lt;code&gt;--enable-preview&lt;/code&gt; to enable it) which is specified by the &lt;a href="https://openjdk.org/jeps/454" target="_blank" rel="noopener noreferrer"&gt;JEP 454&lt;/a&gt;:&lt;/strong&gt;&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;By efficiently invoking foreign functions (i.e., code outside the JVM), and by safely accessing foreign memory (i.e., memory not managed by the JVM), the API enables Java programs to call native libraries and process native data without the brittleness and danger of JNI.&#10;&lt;a href="https://openjdk.org/jeps/454" target="_blank" rel="noopener noreferrer"&gt;JEP 454&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Profiling Maven Projects with my IntelliJ Profiler Plugin</title><link>https://foojay.io/today/profiling-maven-projects-with-my-intellij-profiler-plugin/</link><pubDate>Thu, 14 Dec 2023 10:41:34 +0000</pubDate><guid>https://foojay.io/today/profiling-maven-projects-with-my-intellij-profiler-plugin/</guid><description>&lt;h3 id="or-i-just-released-version-0011-with-a-cool-new-feature-that-i-cant-wait-to-tell-you-about"&gt;Or: I just released version 0.0.11 with a cool new feature that I can&amp;rsquo;t wait to tell you about&amp;hellip;&lt;/h3&gt;&#10;&lt;p&gt;According to the recent &lt;a href="https://www.jetbrains.com/lp/devecosystem-2023/java/" target="_blank" rel="noopener noreferrer"&gt;JetBrains survey&lt;/a&gt;, most people use Maven as their build system and build Spring Boot applications with Java. Yet my profiling plugin for IntelliJ only supports profiling pure Java run configurations. Configurations where the JVM gets passed the main class to run. This is great for tiny examples where you directly right-click on the &lt;code&gt;main&lt;/code&gt; method and profile the whole application using the context menu:&#10;&lt;img src="https://foojay.io/today/profiling-maven-projects-with-my-intellij-profiler-plugin/image-2-a3dd1d7e.jpg" alt="" width="1570" height="644" loading="lazy" decoding="async"&gt;&lt;/p&gt;</description></item><item><title>Who Killed the JVM? Attaching a Debugger Twice</title><link>https://foojay.io/today/who-killed-the-jvm-attaching-a-debugger-twice/</link><pubDate>Wed, 06 Dec 2023 17:17:47 +0000</pubDate><guid>https://foojay.io/today/who-killed-the-jvm-attaching-a-debugger-twice/</guid><description>&lt;p&gt;A few weeks back, I told you about on-demand debugging in my &lt;a href="https://mostlynerdless.de/blog/2023/10/03/level-up-your-java-debugging-skills-with-on-demand-debugging/" target="_blank" rel="noopener noreferrer"&gt;Level-up your Java Debugging Skills with on-demand Debugging&lt;/a&gt; blog post, enabling you to delay a debugging session until:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;You gave orders via &lt;code&gt;jcmd&lt;/code&gt; (&lt;code&gt;onjcmd=y&lt;/code&gt; option), a feature contributed by the &lt;a href="https://sapmachine.io" target="_blank" rel="noopener noreferrer"&gt;SapMachine&lt;/a&gt; team&lt;/li&gt;&#10;&lt;li&gt;the program threw a specific exception (&lt;code&gt;onthrow=&amp;lt;exception&amp;gt;&lt;/code&gt;)&lt;/li&gt;&#10;&lt;li&gt;The program threw an uncaught exception (&lt;code&gt;onuncaught=y&lt;/code&gt;)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;This is quite useful because the JDWP agent has to do substantial initialization before it can start listening for the attaching debugger:&lt;/p&gt;</description></item><item><title>Custom Events in the Blocky World: Using JFR in Minecraft</title><link>https://foojay.io/today/custom-events-in-the-blocky-world-using-jfr-in-minecraft/</link><pubDate>Tue, 28 Nov 2023 19:12:50 +0000</pubDate><guid>https://foojay.io/today/custom-events-in-the-blocky-world-using-jfr-in-minecraft/</guid><description>&lt;p&gt;I was searching for some JFR-related settings on the internet when I stumbled upon the &lt;a href="https://minecraft.fandom.com/wiki/Commands/jfr" target="_blank" rel="noopener noreferrer"&gt;&lt;code&gt;/jfr&lt;/code&gt; command&lt;/a&gt; that exists in &lt;a href="https://www.minecraft.net" target="_blank" rel="noopener noreferrer"&gt;Minecraft&lt;/a&gt;:&lt;/p&gt;&#10;&lt;figure class="aligncenter size-full is-resized"&gt;&#10; &lt;img src="https://foojay.io/today/custom-events-in-the-blocky-world-using-jfr-in-minecraft/image-2-636eafaf.jpg" alt="" style="width:614px;height:auto" loading="lazy" class="is-zoomable"&gt;&lt;/figure&gt;&#10;&#10;&lt;p&gt;This, of course, intrigued me, especially as Minecraft apparently adds some custom JFR events:&#10;&lt;a href="https://minecraft.fandom.com/wiki/Commands/jfr" target="_blank" rel="noopener noreferrer"&gt;&lt;img src="https://foojay.io/today/custom-events-in-the-blocky-world-using-jfr-in-minecraft/image-3-b9708eb4.png" alt="" width="933" height="234" loading="lazy" decoding="async"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;So I had to check it out. I downloaded and started the &lt;a href="https://www.minecraft.net/en-us/download/server" target="_blank" rel="noopener noreferrer"&gt;Java server&lt;/a&gt;, got a demo account, and connected to my local instance. &lt;em&gt;This works with a demo account when you launch the demo world, enable the cheat mode in the settings, kick yourself via &amp;ldquo;/kick @p,&amp;rdquo; and then select your own server. I found this via &lt;a href="https://bugs.mojang.com/browse/MC-138478" target="_blank" rel="noopener noreferrer"&gt;this bug report&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Custom JFR Events: A Short Introduction</title><link>https://foojay.io/today/custom-jfr-events-a-short-introduction/</link><pubDate>Sun, 26 Nov 2023 21:08:03 +0000</pubDate><guid>https://foojay.io/today/custom-jfr-events-a-short-introduction/</guid><description>&lt;p&gt;&lt;strong&gt;JDK Flight Recorder (JFR) is one of the two prominent open-source profilers for the OpenJDK (besides &lt;a href="https://github.com/async-profiler/async-profiler" target="_blank" rel="noopener noreferrer"&gt;async-profiler&lt;/a&gt;).&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;It offers many features (see &lt;a href="https://mostlynerdless.de/profiling-talks/" target="_blank" rel="noopener noreferrer"&gt;Profiling Talks&lt;/a&gt;) and the ability to observe lots of information by recording over one hundred different events.&lt;/p&gt;&#10;&lt;p&gt;If you want to know more about the existing events, visit my &lt;a href="https://sapmachine.io/jfrevents" target="_blank" rel="noopener noreferrer"&gt;JFR Event Collection&lt;/a&gt; website (&lt;a href="https://mostlynerdless.de/blog/2022/12/06/jfr-event-collection/" target="_blank" rel="noopener noreferrer"&gt;related blog post&lt;/a&gt;):&lt;br&gt;&#10;&lt;a href="https://sapmachine.io/jfrevents" target="_blank" rel="noopener noreferrer"&gt;&lt;img src="https://foojay.io/today/custom-jfr-events-a-short-introduction/image-8a79ea31.png" alt="" width="2000" height="1128" loading="lazy" decoding="async"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;Besides these built-in events, JFR allows you to implement your events to record custom information directly in your profiling file.&lt;/p&gt;</description></item><item><title>Loom is just HyperThreading in Java</title><link>https://foojay.io/today/loom-is-just-hyperthreading-in-java/</link><pubDate>Tue, 14 Nov 2023 10:54:06 +0000</pubDate><guid>https://foojay.io/today/loom-is-just-hyperthreading-in-java/</guid><description>&lt;p&gt;While sitting in &lt;a href="https://horstmann.com/unblog/2023-09-19/index.html" target="_blank" rel="noopener noreferrer"&gt;Cay Horstmann&lt;/a&gt;&amp;rsquo;s &lt;a href="https://baselone.ch/speech.html?id=BEB1A232-BA37-4619-A7F9-33802755DFEB" target="_blank" rel="noopener noreferrer"&gt;&amp;ldquo;Looming Changes in Java Concurrency&amp;rdquo; talk at BaselOne&lt;/a&gt;, I had an epiphany: Aren&amp;rsquo;t virtual threads with Loom just a version of HyperThreading on the JVM?&lt;br&gt;&#10;&lt;img src="https://foojay.io/today/loom-is-just-hyperthreading-in-java/ht_vs_vt_pyramid-1-2000x1125-02652af5.jpg" alt="" width="1600" height="900" loading="lazy" decoding="async"&gt;&lt;/p&gt;&#10;&lt;p&gt;Both try to utilize a computation resource fully, be it hardware core or platform thread, by multiplexing multiple tasks onto it, despite many tasks waiting regularly for IO operations to complete:&#10;&lt;img src="https://foojay.io/today/loom-is-just-hyperthreading-in-java/ht_vs_vt_interleaving-2000x560-22833803.jpg" alt="" width="1600" height="448" loading="lazy" decoding="async"&gt;&lt;/p&gt;&#10;&lt;p&gt;When one task waits, another can be scheduled, improving overall throughput. This works especially well when longer IO operations follow short bursts of computation.&lt;/p&gt;</description></item><item><title>Putting JFR into Context</title><link>https://foojay.io/today/putting-jfr-into-context/</link><pubDate>Thu, 02 Nov 2023 14:03:25 +0000</pubDate><guid>https://foojay.io/today/putting-jfr-into-context/</guid><description>&lt;p&gt;&lt;strong&gt;Have you ever wanted to bring your JFR events into context? Adding information on sessions, user IDs, and more can improve your ability to make sense of all the events in your profile.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Currently, we can only add context by creating custom JFR events, as I presented in my &lt;a href="https://mostlynerdless.de/profiling-talks/" target="_blank" rel="noopener noreferrer"&gt;Profiling Talks&lt;/a&gt;:&lt;/p&gt;&#10;&lt;figure class="wp-block-embed is-type-video is-provider-vimeo wp-block-embed-vimeo wp-embed-aspect-16-9 wp-has-aspect-ratio"&gt;&#10; &lt;div class="wp-block-embed__wrapper"&gt;&#10; &lt;iframe title="Unleash the Power of Open Source Java Profilers - Johannes Bechberger" src="https://player.vimeo.com/video/861946709?dnt=1&amp;amp;app_id=122963" width="500" height="281" frameborder="0" allow="autoplay; fullscreen; picture-in-picture; clipboard-write"&gt;&lt;/iframe&gt;&#10; &lt;/div&gt;&#10; &lt;figcaption class="wp-element-caption"&gt;&#10; More here: &lt;a target="_blank" href="https://mostlynerdless.de/profiling-talks/"&gt;https://mostlynerdless.de/profiling-talks/&lt;/a&gt;&#10; &lt;/figcaption&gt;&#10;&lt;/figure&gt;&#10;&lt;p&gt;We can use these custom events to store away the information and later relate them to all the other events by using the event&amp;rsquo;s time, duration, and thread. This works out-of-the-box but has one major problem: Relating events is quite fuzzy, as time stamps are not as accurate (see JFR Timestamps and System.nanoTime), and we do all of this in post-processing.&lt;/p&gt;</description></item><item><title>JDWP, onthrow and a mysterious error</title><link>https://foojay.io/today/jdwp-onthrow-and-a-mysterious-error/</link><pubDate>Thu, 26 Oct 2023 13:44:01 +0000</pubDate><guid>https://foojay.io/today/jdwp-onthrow-and-a-mysterious-error/</guid><description>&lt;p&gt;&lt;strong&gt;In my previous Java-related blog post called &lt;a href="https://foojay.io/today/level-up-your-java-debugging-skills-with-on-demand-debugging/"&gt;Level-up your Java Debugging Skills with on-demand Debugging&lt;/a&gt;, I showed you how to use the &lt;code&gt;onthrow&lt;/code&gt; option of the JDWP agent to start the debugging session on the first throw of a specific exception.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;This gave us a mysterious error in JDB:&#10;&lt;img src="https://foojay.io/today/jdwp-onthrow-and-a-mysterious-error/image-3-1b809dff.jpg" alt="" width="1600" height="435" loading="lazy" decoding="async"&gt;&lt;/p&gt;&#10;&lt;p&gt;And I asked if somebody had any ideas. No one had, but I was at Devoxx Belgium and happened to talk with &lt;a href="https://shipilev.net/" target="_blank" rel="noopener noreferrer"&gt;Aleksey Shipilev&lt;/a&gt; about it at the Corretto booth:&#10;&lt;img src="https://foojay.io/today/jdwp-onthrow-and-a-mysterious-error/F7hNsheWUAA0Y46-2000x1500-25a1d10f.jpg" alt="" width="1600" height="1200" loading="lazy" decoding="async"&gt; Two OpenJDK developers having fun at Devoxx: Investigating a jdb bug with Shipilev&lt;br&gt;&#10;in the Coretto booth (&lt;a href="https://twitter.com/parttimen3rd/status/1709201492115095904" target="_blank" rel="noopener noreferrer"&gt;Tweet&lt;/a&gt;)&lt;/p&gt;</description></item><item><title>Level-up your Java Debugging Skills with on-demand Debugging</title><link>https://foojay.io/today/level-up-your-java-debugging-skills-with-on-demand-debugging/</link><pubDate>Mon, 16 Oct 2023 14:21:24 +0000</pubDate><guid>https://foojay.io/today/level-up-your-java-debugging-skills-with-on-demand-debugging/</guid><description>&lt;p&gt;&lt;strong&gt;Debugging is one of the most common tasks in software development, so one would assume that all features of debuggers have ample coverage in tutorials and guides.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Yet there are three hidden gems of the Java Debugging (JDWP) agent that allow you to delay the start of the debugging session until&amp;hellip;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;you gave orders via &lt;code&gt;jcmd&lt;/code&gt; (&lt;code&gt;onjcmd=y&lt;/code&gt; option)&lt;/li&gt;&#10;&lt;li&gt;the program threw a specific exception (&lt;code&gt;onthrow=&amp;lt;exception&amp;gt;&lt;/code&gt;)&lt;/li&gt;&#10;&lt;li&gt;the program threw an uncaught exception (&lt;code&gt;onuncaught=y&lt;/code&gt;)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Before I tell you more about the specific options, I want to start with the basics of how to apply them.&lt;/p&gt;</description></item><item><title>Report of My Trip to JavaZone and Northern Germany</title><link>https://foojay.io/today/report-of-my-trip-to-javazone-and-northern-germany/</link><pubDate>Mon, 02 Oct 2023 08:44:28 +0000</pubDate><guid>https://foojay.io/today/report-of-my-trip-to-javazone-and-northern-germany/</guid><description>&lt;p&gt;Between 2nd and 17th September, I gave three talks in three different cities:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://2023.javazone.no/" target="_blank" rel="noopener noreferrer"&gt;JavaZone Oslo&lt;/a&gt;, 7th September: Unleash the Power Of Open-Source Profilers (&lt;a href="https://www.infoq.com/articles/open-source-java-profilers/" target="_blank" rel="noopener noreferrer"&gt;InfoQ article&lt;/a&gt;)&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://javaforumnord.de/2023/programm/" target="_blank" rel="noopener noreferrer"&gt;Java Forum Nord&lt;/a&gt; Hannover, 12th September: Unleash the power of Open-Source Java Profilers&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://codetalks.de/program#talk-1748?event=8" target="_blank" rel="noopener noreferrer"&gt;code.talks&lt;/a&gt; Hamburg, 14th September: Writing a Java Profiler in Pure Java (&lt;a href="https://mostlynerdless.de/blog/2023/03/27/writing-a-profiler-in-240-lines-of-pure-java/" target="_blank" rel="noopener noreferrer"&gt;blog post&lt;/a&gt;)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;I traveled from Karlsruhe to Oslo (via Stuttgart Airport) and from Oslo to Hanover via plane, then to Hamburg, Hanover, back to Hamburg, and the end via Bonn back to Karlsruhe via train:&lt;/p&gt;</description></item><item><title>C2 Might Be Slowing Down Your Builds</title><link>https://foojay.io/today/c2-might-be-slowing-down-your-builds/</link><pubDate>Thu, 28 Sep 2023 09:55:13 +0000</pubDate><guid>https://foojay.io/today/c2-might-be-slowing-down-your-builds/</guid><description>&lt;p&gt;&lt;strong&gt;At the JavaForumNord two weeks ago, I had a friendly chat with Karl Heinz Marbaise (Chairman of the Apache Maven Project), where he mentioned that he wanted to start profiling Maven. This sounded interesting, so I started looking into the performance and bottlenecks of Maven. I began by using the Maven build of &lt;a href="https://github.com/apache/maven" target="_blank" rel="noopener noreferrer"&gt;maven&lt;/a&gt; itself as a starting point (excluding the tests). The following is my first observation related to Maven builds in CIs.&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Taming the Bias: Unbiased Safepoint-Based Stack Walking</title><link>https://foojay.io/today/taming-the-bias-unbiased-safepoint-based-stack-walking/</link><pubDate>Thu, 17 Aug 2023 14:00:34 +0000</pubDate><guid>https://foojay.io/today/taming-the-bias-unbiased-safepoint-based-stack-walking/</guid><description>&lt;p&gt;&lt;strong&gt;Walking only at safepoints has advantages. The main one is that you aren&amp;rsquo;t walking the stack in a signal handler but synchronously to the executed program. Therefore you can allocate memory, acquire locks and rematerialize virtual thread / Loom frames. The latter is significant because virtual threads are &lt;em&gt;the&lt;/em&gt; new Java feature that cannot support using signal-handler-based APIs like AsyncGetCallTrace.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;This article is based on the ideas of Erik Österlund, and the second one is related to these new ideas. The first one is &lt;a href="https://mostlynerdless.de/blog/2023/08/07/asyncgetcalltrace-reworked-frame-by-frame-with-an-iterative-touch/" target="_blank" rel="noopener noreferrer"&gt;AsyncGetCallTrace Reworked: Frame by Frame with an Iterative Touch!&lt;/a&gt;, which you should read before continuing with this post. For a refresher on safepoints, please read &lt;a href="https://mostlynerdless.de/blog/2023/07/31/the-inner-workings-of-safepoints/" target="_blank" rel="noopener noreferrer"&gt;The Inner Workings of Safepoints&lt;/a&gt;.&lt;/p&gt;</description></item></channel></rss>