9

Question

How can I make the classes from the module jdk.incubator.httpclient visible at runtime?

What I'm Using

Java 9 + Maven + HttpClient jdk.incubator.http.HttpClient

Problems

=> Maven build failing when using jdk.incubator.HttpClient. Fixed with this question thanks to @nullpointer

=> Runtime stacktrace :

java.lang.NoClassDefFoundError: jdk/incubator/http/HttpClient
at com.foo.Bar.Bar.<clinit>(Bar.java:56) ~[?:?]
at java.lang.Class.forName0(java.base@9-Ubuntu/Native Method) ~[?:?]
at java.lang.Class.forName(java.base@9-Ubuntu/Class.java:374) ~[?:?]
Caused by: java.lang.ClassNotFoundException: jdk.incubator.http.HttpClient
at java.net.URLClassLoader.findClass(java.base@9-Ubuntu/URLClassLoader.java:388) ~[?:?]
at java.lang.ClassLoader.loadClass(java.base@9-Ubuntu/ClassLoader.java:486) ~[?:?]
at java.lang.ClassLoader.loadClass(java.base@9-Ubuntu/ClassLoader.java:419) ~[?:?]
at com.foo.Bar.Bar.<clinit>(Bar.java:56) ~[?:?]
at java.lang.Class.forName0(java.base@9-Ubuntu/Native Method) ~[?:?]
at java.lang.Class.forName(java.base@9-Ubuntu/Class.java:374) ~[?:?]

Build Section of Pom

<build>
    <finalName>${project.artifactId}</finalName>
    <sourceDirectory>${project.basedir}/src</sourceDirectory>

    <resources>
        <resource>
            <targetPath>.</targetPath>
            <filtering>true</filtering>
            <directory>${project.basedir}/resources</directory>

            <includes>
                <include>plugin.yml</include>
            </includes>
        </resource>
    </resources>

    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-clean-plugin</artifactId>
            <version>3.0.0</version>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.7.0</version>

            <configuration>
                <source>9</source>
                <target>9</target>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.1.0</version>

            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <minimizeJar>true</minimizeJar>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

As you can see, I am using the maven-shade-plugin for my dependencies, but since jdk.incubator.http.HttpClient is part of the JDK it is not included in my jar.

Trying to execute as:

 java -jar --add-modules jdk.incubator.httpclient uhc-staging.jar

results into the following exception:

Error occurred during initialization of VM 
java.lang.module.ResolutionException: Module jdk.incubator.httpclient not found 
at java.lang.module.Resolver.fail(java.base@9-Ubuntu/Resolver.java:790) 
at java.lang.module.Resolver.resolveRequires(java.base@9-Ubuntu/Resolver.java:94)
at java.lang.module.Configuration.resolveRequiresAndUses(java.base@9-Ubuntu/Configuration.java:370)
at java.lang.module.ModuleDescriptor$1.resolveRequiresAndUses(java.base@9-Ubuntu/ModuleDescriptor.java:1986)
at jdk.internal.module.ModuleBootstrap.boot(java.base@9-Ubuntu/ModuleBootstrap.java:263)
at java.lang.System.initPhase2(java.base@9-Ubuntu/System.java:1927)
Naman
  • 27,789
  • 26
  • 218
  • 353
Caleb Bassham
  • 1,874
  • 2
  • 16
  • 33
  • @nullpointer The jar is used as an addon. There is a method `enable()` that is called when the main process enables it. To main process is just another jar file started with `java -jar server.jar` – Caleb Bassham Nov 23 '17 at 03:59
  • @nullpointer Sorry for being too brief. My jar is used as a plugin to an api Bukkit. When the Bukkit server starts, it loads all of the plugins, including mine, and calls the `enable()` method. In my enable method I start by calling to my api with the HttpClient to load some information on user permissions. – Caleb Bassham Nov 23 '17 at 04:04
  • Ideally you should update the question with the integration part of the current jar with Bukkit and the code used in there. [Though, honestly I am not much aware of how Bukkit works.] – Naman Nov 23 '17 at 04:33
  • @nullpointer I have found another question that seems to have a similar issue. [here](https://stackoverflow.com/questions/45129397/noclassdeffounderror-while-trying-to-use-jdk-incubator-http-httpclient-in-java-i). They use `--add-modules jdk.incubator.httpclient` but I am not sure where I would put this with maven. If you know, that would be awesome. I will continue searching as well. Thanks for all the help! – Caleb Bassham Nov 23 '17 at 04:40
  • 1
    Something fishy here, is there any chance that you are running a really old early access build of JDK 9? What does `java -version` print? – Alan Bateman Nov 23 '17 at 07:31
  • 1
    @AlanBateman In a [discussion](https://chat.stackoverflow.com/rooms/159630/discussion-between-nullpointer-and-caleb-bassham) with OP. Figured out that the `java --list-modules` for the installed JDK doesn't include `jdk.incubator.httpclient`. Suggested to install the latest JDK for Ubuntu. Maybe you can guide better in terms of where to download from or further. – Naman Nov 23 '17 at 09:22
  • 2
    Thanks for a link to the discussion. He seems to be running with a build of jdk-9+134 so it's an ancient EA build from 2016 and before the incubating feature settled down. Once it install a GA release (9 or the latest 9.0.01) then it will be a lot easier to help him. – Alan Bateman Nov 23 '17 at 14:21

1 Answers1

3

In the discussion, the detail brought out was that executing:-

java --list-modules

doesn't include jdk.incubator.httpclient as a module which is the reason why the j.l.m.ResolutionException is thrown. Hence, the solution to this shall be upgrading the JDK version installed to the latest release(which should include the incubator module) and then trying to run the application using the same command as suggested:-

java -jar --add-modules jdk.incubator.httpclient uhc-staging.jar
Naman
  • 27,789
  • 26
  • 218
  • 353
  • To expand on this, I had the `openjdk-9-jdk` package on Ubuntu 16.10, which is no longer a supported version of Ubuntu. Upgrading to 17.04 allowed me to install the `oracle-java9-installer` package which had failed to install with 16.10. Since the `openjdk-9-jdk` package does not come with the incubator module, using the `--add-modules jdk.incubator.httpclient` would not work. Using `oracle-java9-installer` and running the jar with `--add-modules jdk.incubator.httpclient` fixed the problem – Caleb Bassham Nov 24 '17 at 17:59
  • Also, to avoid using the `--add-modules` on the command line. One has to [execute using the modulepath as detailed out in another answer](https://stackoverflow.com/a/47468106/1746118). – Naman Nov 24 '17 at 18:34