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






<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title>Thihup&#39;s blog</title>
        <link>https://thihup.dev/</link>
        <description>Thihup&#39;s personal blog</description>
        <generator>Hugo 0.68.3 https://gohugo.io/</generator>
        
            <language>en</language>
        
        
            <managingEditor>thihup@gmail.com (Thiago Henrique Hüpner)</managingEditor>
        
        
            <webMaster>thihup@gmail.com (Thiago Henrique Hüpner)</webMaster>
        
        
            <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
        
        <lastBuildDate>Fri, 20 Feb 2026 18:45:21 &#43;0000</lastBuildDate>
        
            <atom:link rel="self" type="application/rss&#43;xml" href="https://thihup.dev/rss.xml" />
        
        
            <item>
                <title>Create Your Own Incubating Java Modules</title>
                <link>https://thihup.dev/posts/create-your-own-incubating-java-modules/</link>
                <guid isPermaLink="true">https://thihup.dev/posts/create-your-own-incubating-java-modules/</guid>
                <pubDate>Mon, 30 May 2022 13:14:44 &#43;0000</pubDate>
                
                    <author>thihup@gmail.com (Thiago Henrique Hüpner)</author>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                    <description>&lt;p&gt;Java Modules have some secret features, that are mostly used by the JDK itself.
One of these features is the incubating modules.&lt;/p&gt;
&lt;p&gt;In the &lt;a href=&#34;https://openjdk.java.net/jeps/11&#34;&gt;JEP 11: Incubator Modules&lt;/a&gt; it is described how
it should work&lt;/p&gt;
&lt;p&gt;If we use the &lt;code&gt;jdk.incubator.concurrent&lt;/code&gt; module as an example -
from &lt;a href=&#34;https://openjdk.java.net/jeps/428&#34;&gt;JEP 428: Structured Concurrency (Incubator)&lt;/a&gt; -
we can observe that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This module is listed in the &lt;code&gt;java --list-modules&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;It is not resolved by default&lt;/li&gt;
&lt;li&gt;It warns in the console of the use of the incubating module&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One way of resolving an incubating module is by adding a &lt;code&gt;requires some.incubator.module&lt;/code&gt; in a &lt;code&gt;module-info.java&lt;/code&gt;
or by including the &lt;code&gt;--add-modules=some.incubator.module&lt;/code&gt; to the JVM command-line flag.&lt;/p&gt;
&lt;p&gt;However, &lt;a href=&#34;https://openjdk.java.net/jeps/11&#34;&gt;JEP 11&lt;/a&gt; only defines how it should work with JMod files.
While JMods are great for use with JLink, it is not the current deploy format for
Maven Central.&lt;/p&gt;
&lt;p&gt;Looking through the JDK source-code, though, I have found out that not only &lt;code&gt;JMod&lt;/code&gt; tool
supports the creation of incubating modules, but also the &lt;code&gt;Jar&lt;/code&gt; tool.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;WARNING&lt;/strong&gt; These command-line flags and the class file attribute are not in the specification.
They may be changed or removed without any notice!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There are two main flags:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/openjdk/jdk/blob/master/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java#L170&#34;&gt;&amp;ndash;do-not-resolve-by-default&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/openjdk/jdk/blob/master/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java#L177&#34;&gt;&amp;ndash;warn-if-resolved=value&lt;/a&gt;
(where &lt;code&gt;value&lt;/code&gt; can be one of):
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/openjdk/jdk/blob/master/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java#L187&#34;&gt;incubating&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/openjdk/jdk/blob/master/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java#L185&#34;&gt;deprecated-for-removal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/openjdk/jdk/blob/master/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java#L183&#34;&gt;deprecated&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Using the &lt;code&gt;Javap&lt;/code&gt; tool, it is possible to see that the &lt;code&gt;module-info.class&lt;/code&gt; is
changed to include a (unspecified) attribute: &lt;code&gt;ModuleResolution&lt;/code&gt; that has a few valid values:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;nl&#34;&gt;ModuleResolution:&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;1&lt;/span&gt;     &lt;span class=&#34;c1&#34;&gt;//  DO_NOT_RESOLVE_BY_DEFAULT
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;ModuleResolution:&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;2&lt;/span&gt;     &lt;span class=&#34;c1&#34;&gt;//  WARN_DEPRECATED
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;ModuleResolution:&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;4&lt;/span&gt;     &lt;span class=&#34;c1&#34;&gt;//  WARN_DEPRECATED_FOR_REMOVAL
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;ModuleResolution:&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;8&lt;/span&gt;     &lt;span class=&#34;c1&#34;&gt;//  WARN_INCUBATING
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Only the first option (&lt;code&gt;DO_NOT_RESOLVE_BY_DEFAULT&lt;/code&gt;) can be combined with any of ther other options.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note&lt;/em&gt; Due a bug, it is needed to specify the
&lt;code&gt;--warn-if-resolved&lt;/code&gt; flag before &lt;code&gt;--do-not-resolve-by-default&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In Maven, you can achive this by updating the jar after it has been already created,
like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.github.wiverson&lt;span class=&#34;nt&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;jtoolprovider-plugin&lt;span class=&#34;nt&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.34&lt;span class=&#34;nt&#34;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
            &lt;span class=&#34;nt&#34;&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;phase&amp;gt;&lt;/span&gt;package&lt;span class=&#34;nt&#34;&gt;&amp;lt;/phase&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;nt&#34;&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;java-tool&lt;span class=&#34;nt&#34;&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;nt&#34;&gt;&amp;lt;toolName&amp;gt;&lt;/span&gt;jar&lt;span class=&#34;nt&#34;&gt;&amp;lt;/toolName&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;nt&#34;&gt;&amp;lt;writeOutputToLog&amp;gt;&lt;/span&gt;true&lt;span class=&#34;nt&#34;&gt;&amp;lt;/writeOutputToLog&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;nt&#34;&gt;&amp;lt;writeErrorsToLog&amp;gt;&lt;/span&gt;true&lt;span class=&#34;nt&#34;&gt;&amp;lt;/writeErrorsToLog&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;nt&#34;&gt;&amp;lt;failOnError&amp;gt;&lt;/span&gt;true&lt;span class=&#34;nt&#34;&gt;&amp;lt;/failOnError&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;nt&#34;&gt;&amp;lt;args&amp;gt;&lt;/span&gt;
                        &lt;span class=&#34;nt&#34;&gt;&amp;lt;arg&amp;gt;&lt;/span&gt;--update&lt;span class=&#34;nt&#34;&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;
                        &lt;span class=&#34;nt&#34;&gt;&amp;lt;arg&amp;gt;&lt;/span&gt;--warn-if-resolved=incubating&lt;span class=&#34;nt&#34;&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;                        
                        &lt;span class=&#34;nt&#34;&gt;&amp;lt;arg&amp;gt;&lt;/span&gt;--do-not-resolve-by-default&lt;span class=&#34;nt&#34;&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;
                        &lt;span class=&#34;nt&#34;&gt;&amp;lt;arg&amp;gt;&lt;/span&gt;--file&lt;span class=&#34;nt&#34;&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;
                        &lt;span class=&#34;nt&#34;&gt;&amp;lt;arg&amp;gt;&lt;/span&gt;${project.build.directory}/${project.build.finalName}.jar&lt;span class=&#34;nt&#34;&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;
                        &lt;span class=&#34;c&#34;&gt;&amp;lt;!-- It seems to be needed to include twice --&amp;gt;&lt;/span&gt;
                        &lt;span class=&#34;nt&#34;&gt;&amp;lt;arg&amp;gt;&lt;/span&gt;${project.build.directory}/${project.build.finalName}.jar&lt;span class=&#34;nt&#34;&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;nt&#34;&gt;&amp;lt;/args&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
            &lt;span class=&#34;nt&#34;&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;You can checkout a full example here: &lt;a href=&#34;https://github.com/Thihup/incubator-module-example&#34;&gt;https://github.com/Thihup/incubator-module-example&lt;/a&gt;&lt;/p&gt;
</description>
                
                
                
                
                
                    
                        
                    
                        
                    
                
            </item>
        
    </channel>
</rss>
