<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Clayton Walker</title>
    <description>The latest articles on Forem by Clayton Walker (@sineaggi).</description>
    <link>https://forem.com/sineaggi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F428951%2F0e9cf62d-0e32-434b-8fcc-7bd9ae78328b.jpeg</url>
      <title>Forem: Clayton Walker</title>
      <link>https://forem.com/sineaggi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sineaggi"/>
    <language>en</language>
    <item>
      <title>Snippet: How to handle non-issue (client) exceptions in spring boot</title>
      <dc:creator>Clayton Walker</dc:creator>
      <pubDate>Fri, 29 Aug 2025 17:59:25 +0000</pubDate>
      <link>https://forem.com/sineaggi/mini-thought-how-to-handle-non-issue-clinet-exceptions-in-spring-boot-5ccb</link>
      <guid>https://forem.com/sineaggi/mini-thought-how-to-handle-non-issue-clinet-exceptions-in-spring-boot-5ccb</guid>
      <description>&lt;p&gt;If you find yourself writing your own exception handlers, you might have also found yourself manually filtering out 'known-good' exceptions, such as exceptions caused by clients disconnection.&lt;/p&gt;

&lt;p&gt;No sense in replicating spring's existing filter, just use &lt;code&gt;DisconnectedClientHelper.isClientDisconnectedException&lt;/code&gt;) in your &lt;code&gt;@ControllerAdvice&lt;/code&gt; or &lt;code&gt;@ExceptionHandler&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ControllerAdvice&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GlobalExceptionHandler&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@ExceptionHandler&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;WebRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DisconnectedClientHelper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isClientDisconnectedException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// handle as usual&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// handle other exceptions&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;INTERNAL_SERVER_ERROR&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>spring</category>
      <category>springboot</category>
    </item>
    <item>
      <title>Bazel issues I'm following</title>
      <dc:creator>Clayton Walker</dc:creator>
      <pubDate>Wed, 13 Aug 2025 17:32:02 +0000</pubDate>
      <link>https://forem.com/sineaggi/bazel-issues-im-following-18k6</link>
      <guid>https://forem.com/sineaggi/bazel-issues-im-following-18k6</guid>
      <description>&lt;p&gt;In rules_kotlin, you can't use&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;kotlin 2.2 (yet) &lt;a href="https://github.com/bazelbuild/rules_kotlin/pull/1341" rel="noopener noreferrer"&gt;https://github.com/bazelbuild/rules_kotlin/pull/1341&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;runfiles (yet) &lt;a href="https://github.com/bazelbuild/rules_kotlin/issues/1095" rel="noopener noreferrer"&gt;https://github.com/bazelbuild/rules_kotlin/issues/1095&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;on windows (yet)&lt;/li&gt;
&lt;li&gt;env support (yet) see &lt;a href="https://bazel.build/reference/be/common-definitions#binary.env" rel="noopener noreferrer"&gt;https://bazel.build/reference/be/common-definitions#binary.env&lt;/a&gt; &lt;a href="https://github.com/bazelbuild/rules_kotlin/issues/1359" rel="noopener noreferrer"&gt;https://github.com/bazelbuild/rules_kotlin/issues/1359&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;test_env support (fixed) &lt;a href="https://github.com/bazelbuild/rules_kotlin/issues/815" rel="noopener noreferrer"&gt;https://github.com/bazelbuild/rules_kotlin/issues/815&lt;/a&gt; but not closed &lt;a href="https://github.com/bazelbuild/rules_kotlin/pull/837" rel="noopener noreferrer"&gt;https://github.com/bazelbuild/rules_kotlin/pull/837&lt;/a&gt; ???&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Twice now I've had no idea as to why it's giving me a random java error.&lt;br&gt;
This is caused by executing a kotlin binary on java 25&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error occurred during initialization of VM
java.lang.Error: A command line option has attempted to allow or enable the Security Manager. Enabling a Security Manager is not supported.
    at java.lang.System.initPhase3(java.base@25/System.java:1969)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>bazel</category>
      <category>kotlin</category>
      <category>bug</category>
    </item>
    <item>
      <title>Running c/c++ on the JVM</title>
      <dc:creator>Clayton Walker</dc:creator>
      <pubDate>Sat, 14 Jun 2025 18:10:18 +0000</pubDate>
      <link>https://forem.com/sineaggi/running-cc-on-the-jvm-33bj</link>
      <guid>https://forem.com/sineaggi/running-cc-on-the-jvm-33bj</guid>
      <description>&lt;p&gt;This isn't so much a deep dive as it is a solution in search of a problem.&lt;/p&gt;

&lt;p&gt;How to compile to llvm bitcode (or webasm)&lt;/p&gt;

&lt;p&gt;Notes: Graalvm supports llvm-bitcode and wasm (&lt;a href="https://github.com/oracle/graal/blob/master/wasm/README.md" rel="noopener noreferrer"&gt;https://github.com/oracle/graal/blob/master/wasm/README.md&lt;/a&gt;)&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>jvm</category>
      <category>webassembly</category>
      <category>oracle</category>
    </item>
    <item>
      <title>How to exclude classes from jacoco in Gradle</title>
      <dc:creator>Clayton Walker</dc:creator>
      <pubDate>Thu, 17 Apr 2025 03:26:46 +0000</pubDate>
      <link>https://forem.com/sineaggi/how-to-exclude-classes-from-jacoco-in-gradle-2go9</link>
      <guid>https://forem.com/sineaggi/how-to-exclude-classes-from-jacoco-in-gradle-2go9</guid>
      <description>&lt;p&gt;Basically the only way to re-route is to re-build the &lt;code&gt;JacocoReportBase.classDirectories&lt;/code&gt; object from scratch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;withType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;JacocoReportBase&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;configureEach&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;classDirectories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sourceSets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;asFileTree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matching&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"**/build/**"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;reporting&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;reports&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;withType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;JacocoCoverageReport&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;configureEach&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;reportTask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;classDirectories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sourceSets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;asFileTree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matching&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="nf"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"**/build/**"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;when using the reporting extension.&lt;/p&gt;

&lt;p&gt;Follow &lt;a href="https://github.com/gradle/gradle/issues/14760" rel="noopener noreferrer"&gt;https://github.com/gradle/gradle/issues/14760&lt;/a&gt; for future updates.&lt;/p&gt;

</description>
      <category>gradle</category>
      <category>java</category>
      <category>programming</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Managing Java installations on macOS</title>
      <dc:creator>Clayton Walker</dc:creator>
      <pubDate>Wed, 12 Feb 2025 17:31:10 +0000</pubDate>
      <link>https://forem.com/sineaggi/managing-java-installations-on-macos-5gi2</link>
      <guid>https://forem.com/sineaggi/managing-java-installations-on-macos-5gi2</guid>
      <description>&lt;p&gt;By default, macOS ships with a tool to resolve Java installations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/usr/libexec/java_home
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It searches in the following directories:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/Library/Java/JavaVirtualMachines/
~/Library/Java/JavaVirtualMachines/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Intellij will install downloaded jvms into the user's home directory, meaning we can use Intellij to manage and update our java installations. &lt;a href="https://www.jetbrains.com/guide/java/tips/download-jdk/" rel="noopener noreferrer"&gt;https://www.jetbrains.com/guide/java/tips/download-jdk/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By setting either &lt;code&gt;JAVA_VERSION&lt;/code&gt; or &lt;code&gt;JAVA_HOME&lt;/code&gt;, calling &lt;code&gt;java&lt;/code&gt; will point to the particular java version selected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cwalker ~ % export JAVA_VERSION=21
cwalker ~ % java --version
openjdk 21.0.6 2025-01-21 LTS
OpenJDK Runtime Environment Corretto-21.0.6.7.1 (build 21.0.6+7-LTS)
OpenJDK 64-Bit Server VM Corretto-21.0.6.7.1 (build 21.0.6+7-LTS, mixed mode, sharing)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a faster way of switching in a shell, see this answer on stack overflow. &lt;a href="https://stackoverflow.com/a/40754792" rel="noopener noreferrer"&gt;https://stackoverflow.com/a/40754792&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Fix dynamic agent loading warning in Gradle</title>
      <dc:creator>Clayton Walker</dc:creator>
      <pubDate>Sat, 13 Jan 2024 00:32:22 +0000</pubDate>
      <link>https://forem.com/sineaggi/fix-dynamic-agent-loading-warning-in-gradle-5748</link>
      <guid>https://forem.com/sineaggi/fix-dynamic-agent-loading-warning-in-gradle-5748</guid>
      <description>&lt;p&gt;In newer versions java, dynamically loaded agents will be disallowed. Warnings like the following would be logged by your test runner.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WARNING: A Java agent has been loaded dynamically (/Users/cwalker/.gradle/caches/modules-2/files-2.1/net.bytebuddy/byte-buddy-agent/1.14.6/46e2545d7a97b6ccb195621650c5957279eb4812/byte-buddy-agent-1.14.6.jar)
WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning
WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information
WARNING: Dynamic loading of agents will be disallowed by default in a future release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To fix this, we can get add a new agent configuration and map dependencies from that configuration to the &lt;code&gt;-javaagent&lt;/code&gt; flag.&lt;/p&gt;

&lt;p&gt;Using the new test-suites plugin, that would look like the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;testAgent&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;configurations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;creating&lt;/span&gt;

&lt;span class="nf"&gt;dependencies&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;testAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"net.bytebuddy:byte-buddy-agent:1.14.6"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// if configuring test task directly&lt;/span&gt;
&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;jvmArgumentProviders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;newInstance&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;JavaAgentArgumentProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;classpath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testAgent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// if using test suites&lt;/span&gt;
&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;suites&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;test&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nf"&gt;existing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JvmTestSuite&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configureEach&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;testTask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;jvmArgumentProviders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;newInstance&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;JavaAgentArgumentProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;classpath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testAgent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JavaAgentArgumentProvider&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;CommandLineArgumentProvider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nc"&gt;Classpath&lt;/span&gt;
    &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;classpath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ConfigurableFileCollection&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;asArguments&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;classpath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"-javaagent:${it.absolutePath}"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the &lt;a href="https://github.com/gradle/gradle/issues/27714" rel="noopener noreferrer"&gt;upstream issue&lt;/a&gt; for updates.&lt;/p&gt;

&lt;p&gt;For simplicity, it may be easier to depend on a third-party dependency (such as &lt;a href="https://github.com/ryandens/javaagent-gradle-plugin" rel="noopener noreferrer"&gt;javaagent-gradle-plugin&lt;/a&gt;) to handle agents.&lt;/p&gt;

&lt;p&gt;EDIT 3/2/2025:&lt;br&gt;
Added test.task option&lt;br&gt;
Replaced direct jvmArgs with jvmArgumentProviders to avoid configuration errors on older versions of Gradle 8&lt;br&gt;
EDIT 6/14/2025:&lt;br&gt;
Added support for task relocatability by using a command-line configurator like in this comment &lt;a href="https://github.com/mockito/mockito/issues/3037#issuecomment-2724136224" rel="noopener noreferrer"&gt;https://github.com/mockito/mockito/issues/3037#issuecomment-2724136224&lt;/a&gt; or this plugin &lt;a href="https://github.com/bakdata/gradle-plugins/pull/63/files" rel="noopener noreferrer"&gt;https://github.com/bakdata/gradle-plugins/pull/63/files&lt;/a&gt;&lt;br&gt;
Added link to &lt;a href="https://github.com/ryandens" rel="noopener noreferrer"&gt;ryandens&lt;/a&gt;' &lt;a href="https://github.com/ryandens/javaagent-gradle-plugin" rel="noopener noreferrer"&gt;javaagent-gradle-plugin&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Python and distroless: A simplified guide</title>
      <dc:creator>Clayton Walker</dc:creator>
      <pubDate>Thu, 12 Oct 2023 01:07:32 +0000</pubDate>
      <link>https://forem.com/sineaggi/python-and-distroless-a-simplified-guide-13je</link>
      <guid>https://forem.com/sineaggi/python-and-distroless-a-simplified-guide-13je</guid>
      <description>&lt;p&gt;While this guide's focus is on python, the general advice here applies to anyone trying to build docker images on top of &lt;a href="https://github.com/GoogleContainerTools/distroless" rel="noopener noreferrer"&gt;distroless&lt;/a&gt; base images.&lt;/p&gt;

&lt;h2&gt;
  
  
  No dependencies
&lt;/h2&gt;

&lt;p&gt;If you have a simple python script with no dependencies, you can follow &lt;a href="https://github.com/GoogleContainerTools/distroless/tree/main/examples/python3" rel="noopener noreferrer"&gt;this&lt;/a&gt; guide, whose Dockerfile is reproduced below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;python:3-slim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build-env&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . /app&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; gcr.io/distroless/python3&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build-env /app /app&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["hello.py", "/etc"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pure-python dependencies
&lt;/h2&gt;

&lt;p&gt;If you have a &lt;code&gt;requirements.txt&lt;/code&gt; but no additional native dependencies you can follow &lt;a href="https://github.com/GoogleContainerTools/distroless/tree/main/examples/python3-requirements" rel="noopener noreferrer"&gt;this&lt;/a&gt; guide&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Build a virtualenv using the appropriate Debian release&lt;/span&gt;
&lt;span class="c"&gt;# * Install python3-venv for the built-in Python3 venv module (not installed by default)&lt;/span&gt;
&lt;span class="c"&gt;# * Install gcc libpython3-dev to compile C Python modules&lt;/span&gt;
&lt;span class="c"&gt;# * In the virtualenv: Update pip setuputils and wheel to support building new packages&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;debian:11-slim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-install-suggests&lt;/span&gt; &lt;span class="nt"&gt;--no-install-recommends&lt;/span&gt; &lt;span class="nt"&gt;--yes&lt;/span&gt; python3-venv gcc libpython3-dev &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv /venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    /venv/bin/pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; pip setuptools wheel

&lt;span class="c"&gt;# Build the virtualenv as a separate step: Only re-execute this step when requirements.txt changes&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build-venv&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt /requirements.txt&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;/venv/bin/pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--disable-pip-version-check&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; /requirements.txt

&lt;span class="c"&gt;# Copy the virtualenv into a distroless image&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; gcr.io/distroless/python3-debian11&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build-venv /venv /venv&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . /app&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["/venv/bin/python3", "psutil_example.py"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Native dependencies
&lt;/h2&gt;

&lt;p&gt;Finally if we have native dependencies, we can download them from a debian-based build stage, extract their contents to a temp directory (i.e. &lt;code&gt;/dpkg&lt;/code&gt;), then copy those into the root distroless image during the final stage.&lt;/p&gt;

&lt;p&gt;One way to generate a list of dependencies needed is to call &lt;code&gt;apt-cache depends &amp;lt;your-lib-here&amp;gt;&lt;/code&gt;.&lt;br&gt;
In our case we want to install the &lt;a href="https://pypi.org/project/psycopg2/" rel="noopener noreferrer"&gt;psycopg2&lt;/a&gt; library, that has a native dependency on libpq. To find the package (and its dependencies) in debian, we'll first need the name of the package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ apt-get update
&amp;lt;snip&amp;gt;
Reading package lists... Done
$ apt-cache search libpq
&amp;lt;snip&amp;gt;
libpq5 - PostgreSQL C client library
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have the name of the package (&lt;code&gt;libpq5&lt;/code&gt;) we can see what dependencies it has.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ apt-cache depends --recurse libpq5
libpq5
  Depends: libc6
  Depends: libgssapi-krb5-2
  Depends: libldap-2.4-2
  Depends: libssl1.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see the pre-installed distroless dependencies listed in the &lt;a href="https://github.com/GoogleContainerTools/distroless/blob/main/experimental/python3/BUILD#L22" rel="noopener noreferrer"&gt;python&lt;/a&gt; build file, the &lt;a href="https://github.com/GoogleContainerTools/distroless/blob/main/cc/BUILD#L11" rel="noopener noreferrer"&gt;cc&lt;/a&gt; build file and the &lt;a href="https://github.com/GoogleContainerTools/distroless/blob/main/base/BUILD" rel="noopener noreferrer"&gt;base&lt;/a&gt; build file. Looks like we'll need to add these dependencies.&lt;br&gt;
NOTE: Dependencies might have dependencies, you can use the script &lt;a href="https://gist.github.com/tuananh/1e8e0f921410a830a7cd1161ff8bb189" rel="noopener noreferrer"&gt;here&lt;/a&gt; (written by &lt;a href="https://gist.github.com/tuananh" rel="noopener noreferrer"&gt;@tuananh&lt;/a&gt;) to get all dependencies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final &lt;code&gt;Dockerfile&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Build a virtualenv using the appropriate Debian release&lt;/span&gt;
&lt;span class="c"&gt;# * Install python3-venv for the built-in Python3 venv module (not installed by default)&lt;/span&gt;
&lt;span class="c"&gt;# * Install gcc libpython3-dev to compile C Python modules&lt;/span&gt;
&lt;span class="c"&gt;# * In the virtualenv: Update pip setuputils and wheel to support building new packages&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;debian:11-slim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-install-suggests&lt;/span&gt; &lt;span class="nt"&gt;--no-install-recommends&lt;/span&gt; &lt;span class="nt"&gt;--yes&lt;/span&gt; python3-venv gcc libpython3-dev &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv /venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    /venv/bin/pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; pip setuptools wheel
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /tmp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nt"&gt;--no-install-recommends&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;        &lt;span class="c"&gt;# install only deps&lt;/span&gt;
        curl \
        ca-certificates \
        openssl \
        &amp;amp;&amp;amp; \
    apt-get download \
        # ca-certificates \
        \
        # additional python dependencies
        libpq5 \
        &amp;amp;&amp;amp; \
    mkdir -p /dpkg/var/lib/dpkg/status.d/ &amp;amp;&amp;amp; \
    for deb in *.deb; do \
        package_name=$(dpkg-deb -I ${deb} | awk '/^ Package: .*$/ {print $2}'); \ 
        echo "Process: ${package_name}"; \
        dpkg --ctrl-tarfile $deb | tar -Oxf - ./control &amp;gt; /dpkg/var/lib/dpkg/status.d/${package_name}; \
        dpkg --extract $deb /dpkg || exit 10; \
    done

&lt;span class="c"&gt;# Build the virtualenv as a separate step: Only re-execute this step when requirements.txt changes&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build-venv&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt /requirements.txt&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;/venv/bin/pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--disable-pip-version-check&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; /requirements.txt

&lt;span class="c"&gt;# Copy the virtualenv into a distroless image&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; gcr.io/distroless/python3-debian11&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build-venv /venv /venv&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build/dpkg /&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . /app&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["/venv/bin/python3", "psutil_example.py"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>moderation</category>
    </item>
    <item>
      <title>Building multi-release jars (easily) with Gradle and Maven</title>
      <dc:creator>Clayton Walker</dc:creator>
      <pubDate>Sun, 04 Dec 2022 05:41:51 +0000</pubDate>
      <link>https://forem.com/sineaggi/building-multi-release-jars-easily-with-gradle-and-maven-49hd</link>
      <guid>https://forem.com/sineaggi/building-multi-release-jars-easily-with-gradle-and-maven-49hd</guid>
      <description>&lt;h1&gt;
  
  
  Gradle
&lt;/h1&gt;

&lt;p&gt;Use Cédric Champeau's &lt;a href="https://github.com/melix/mrjar-gradle-plugin" rel="noopener noreferrer"&gt;mrjar plugin&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;plugins&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"me.champeau.mrjar"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="s"&gt;"0.1.1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;multiRelease&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;targetVersions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See &lt;a href="https://melix.github.io/mrjar-gradle-plugin/0.1/index.html" rel="noopener noreferrer"&gt;https://melix.github.io/mrjar-gradle-plugin/0.1/index.html&lt;/a&gt; for more details.&lt;/p&gt;

&lt;h1&gt;
  
  
  Maven
&lt;/h1&gt;

&lt;p&gt;Use at least maven-compiler-plugin 3.7.1 which adds &lt;a href="https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#multiReleaseOutput" rel="noopener noreferrer"&gt;multiReleaseOutput&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;release&amp;gt;&lt;/span&gt;9&lt;span class="nt"&gt;&amp;lt;/release&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;compileSourceRoots&amp;gt;&lt;/span&gt; 
        &lt;span class="nt"&gt;&amp;lt;compileSourceRoot&amp;gt;&lt;/span&gt;${project.basedir}/src/main/java9&lt;span class="nt"&gt;&amp;lt;/compileSourceRoot&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;/compileSourceRoots&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;multiReleaseOutput&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/multiReleaseOutput&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then set &lt;code&gt;Multi-Release: true&lt;/code&gt; in the maven-jar-plugin&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;archive&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;manifestEntries&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;Multi-Release&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/Multi-Release&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/manifestEntries&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/archive&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  How to add a &lt;code&gt;module-info.java&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;todo&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>Stop using sourceCompatibility and targetCompatibility</title>
      <dc:creator>Clayton Walker</dc:creator>
      <pubDate>Fri, 07 Jan 2022 00:20:22 +0000</pubDate>
      <link>https://forem.com/sineaggi/stop-using-source-and-target-2n2k</link>
      <guid>https://forem.com/sineaggi/stop-using-source-and-target-2n2k</guid>
      <description>&lt;p&gt;And start using &lt;code&gt;--release&lt;/code&gt;. As of &lt;a href="https://openjdk.java.net/jeps/247" rel="noopener noreferrer"&gt;JEP-247&lt;/a&gt; released in java 9, the flag will allow you to compile for older releases of java without &lt;a href="https://www.morling.dev/blog/bytebuffer-and-the-dreaded-nosuchmethoderror/" rel="noopener noreferrer"&gt;worrying about the dreaded NoSuchMethodError&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop talking and show me the code!
&lt;/h2&gt;

&lt;p&gt;Gradle&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JavaCompile&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;configureEach&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;release&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gradle (kts)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;withType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;JavaCompile&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;configureEach&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;release&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maven (xml) compiler plugin configuration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;release&amp;gt;&lt;/span&gt;9&lt;span class="nt"&gt;&amp;lt;/release&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or via properties&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;maven.compiler.release&amp;gt;&lt;/span&gt;9&lt;span class="nt"&gt;&amp;lt;/maven.compiler.release&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>gradle</category>
      <category>java</category>
      <category>maven</category>
    </item>
    <item>
      <title>Verify an application has picked up a java property</title>
      <dc:creator>Clayton Walker</dc:creator>
      <pubDate>Thu, 16 Dec 2021 01:45:45 +0000</pubDate>
      <link>https://forem.com/sineaggi/verify-an-application-has-picked-up-a-java-property-5bc1</link>
      <guid>https://forem.com/sineaggi/verify-an-application-has-picked-up-a-java-property-5bc1</guid>
      <description>&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; This was written in response to the log4shell vulnerability CVE-2021-44228. &lt;code&gt;-Dlog4j2.noFormatMsgLookup=true&lt;/code&gt; is not effective  at mitigating the second of the two log4j vulnerabilities, CVE-2021-45046.&lt;/p&gt;

&lt;p&gt;I've noticed these past few days people have been asking how to validate if a system property has been set.&lt;/p&gt;

&lt;h1&gt;
  
  
  Simple method (no code change)
&lt;/h1&gt;

&lt;p&gt;The simplest method would be to add &lt;code&gt;-Dlog4j2.noFormatMsgLookup=true&lt;/code&gt; to your &lt;code&gt;JAVA_TOOL_OPTIONS&lt;/code&gt; environment variable, then verify that on startup you see the line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Picked up JAVA_TOOL_OPTIONS: -Dlog4j2.formatMsgNoLookups=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;printed to the console.&lt;/p&gt;

&lt;h1&gt;
  
  
  Code change method
&lt;/h1&gt;

&lt;p&gt;The second way would be to check the system property itself, and print it out on startup. One example would be&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"log4j2.formatMsgNoLookups="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"log4j2.formatMsgNoLookups"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then validating&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;log4j2.formatMsgNoLookups=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
 is printed to the console.&lt;/p&gt;

</description>
      <category>log4shell</category>
      <category>java</category>
      <category>log4j</category>
      <category>log4j2</category>
    </item>
  </channel>
</rss>
