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


<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title type="text">Thihup&#39;s blog</title>
    <subtitle type="html">Thihup&#39;s personal blog</subtitle>
    <updated>2026-02-20T18:45:21&#43;00:00</updated>
    <id>https://thihup.dev/</id>
    <link rel="alternate" type="text/html" href="https://thihup.dev/" />
    <link rel="self" type="application/atom&#43;xml" href="https://thihup.dev/atom.xml" />
    <author>
            <name>Thiago Henrique Hüpner</name>
            <uri>https://thihup.dev/</uri>
            
                <email>thihup@gmail.com</email>
            </author>
    <rights>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</rights>
    <generator uri="https://gohugo.io/" version="0.68.3">Hugo</generator>
        <entry>
            <title type="text">Create Your Own Incubating Java Modules</title>
            <link rel="alternate" type="text/html" href="https://thihup.dev/posts/create-your-own-incubating-java-modules/" />
            <id>https://thihup.dev/posts/create-your-own-incubating-java-modules/</id>
            <updated>2026-02-20T18:45:17&#43;00:00</updated>
            <published>2022-05-30T13:14:44&#43;00:00</published>
            <author>
                    <name>Thiago Henrique Hüpner</name>
                    <uri>https://thihup.dev/</uri>
                    <email>thihup@gmail.com</email>
                    </author>
            <rights>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</rights><summary type="html">Java Modules have some secret features, that are mostly used by the JDK itself. One of these features is the incubating modules.
In the JEP 11: Incubator Modules it is described how it should work
If we use the jdk.incubator.concurrent module as an example - from JEP 428: Structured Concurrency (Incubator) - we can observe that:
 This module is listed in the java --list-modules It is not resolved by default It warns in the console of the use of the incubating module  One way of resolving an incubating module is by adding a requires some.</summary>
            
                <content type="html">&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;
</content>
            
            
            
            
            
                
                    
                
                    
                
            
        </entry>
    
</feed>
