问题
I am trying to use the HttpClient from incubator in Java 9 maven project. I am not getting any Compilation issue. The project builds successfully. But when I try to run the Main class, it gives me the following exception:
Exception in thread "main" java.lang.NoClassDefFoundError: jdk/incubator/http/HttpClient
at java9.http_client.Main.main(Main.java:18)
Caused by: java.lang.ClassNotFoundException: jdk.incubator.http.HttpClient
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)....
My code is just a module-info file and a Main class that just calls google.com and tries to read the response:
module-info.java
module java9.http_client {
requires jdk.incubator.httpclient;
}
Main.java
public final class Main {
public static void main(String[] args) {
try {
HttpClient client = HttpClient.newHttpClient();
URI httpURI = new URI("http://www.google.com/");
HttpRequest request = HttpRequest.newBuilder(httpURI).GET().build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandler.asString());
String responseBody = response.body();
int responseStatusCode = response.statusCode();
System.out.println(responseBody + "\n" + responseStatusCode);
} catch (URISyntaxException | IOException | InterruptedException e) {
throw new RuntimeException("Unable to run Java 9 Http Client examples", e);
}
}
}
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.javacodegeeks.java9</groupId>
<artifactId>http_client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Java9HttpClient</name>
<description>Java Http Client example</description>
<properties>
<java-version>1.9</java-version>
<maven-compiler-plugin-version>3.6.1</maven-compiler-plugin-version>
<maven-shade-plugin-version>3.0.0</maven-shade-plugin-version>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin-version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven-shade-plugin-version}</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java-version}</source>
<target>${java-version}</target>
<verbose>true</verbose>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.javacodegeeks.java9.http_client.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
What am I missing? I found various articles about this but they are all doing it in this way.
Any help is appreicated. Thanks!
Command executed when using --add-modules
cd /home/mansi/NetBeansProjects/java9-http-client; JAVA_HOME=/home/mansi/jdk-9 /home/mansi/netbeans-dev-201709070001/java/maven/bin/mvn "-Dexec.args=--add-modules=jdk.incubator.httpclient -classpath %classpath java9.http_client.Main" -Dexec.executable=/home/mansi/jdk-9/bin/java -Dexec.classpathScope=runtime org.codehaus.mojo:exec-maven-plugin:1.5.0:exec
When not using --add-modules
cd /home/mansi/NetBeansProjects/java9-http-client; JAVA_HOME=/home/mansi/jdk-9 /home/mansi/netbeans-dev-201709070001/java/maven/bin/mvn "-Dexec.args=-classpath %classpath java9.http_client.Main" -Dexec.executable=/home/mansi/jdk-9/bin/java -Dexec.classpathScope=runtime org.codehaus.mojo:exec-maven-plugin:1.5.0:exec
回答1:
The difference during the execution is using the classpath vs the modulepath. The statement in the JEP11#Incubator Modules to notice is as
... incubator modules are not resolved by default for applications on the class path.
so in order to execute the code using the classpath
Applications on the class path must use the
--add-modules
command-line option to request that an incubator module be resolved.
If you want to execute without using the --add-modules
option, while creating a new module
and trying to execute the Main
class make sure the java command executed using the module path using the arguments :
-p or --module-path <module path>
Searches for directories from a semicolon-separated (;) list of directories. Each directory is a directory of modules.
-m or --module <module>/<mainclass
Specifies the name of the initial module to resolve and, if it isn’t specified by the module, then specifies the name of the mainclass to execute.
The complete command would be something (e.g.) like :
.../jdk-9.0.1.jdk/Contents/Home/bin/java
-p .../jdk9-httpincubate-maven/target/classes
-m jdk.httpincubate.maven/http2.Main
Note:
The above directory structure is followed in the sample project that I have created on GitHub to replicate the same as well.
Just to add to it and without any publicisizing I am using 2017.3 EAP of intelliJ and it lets me Run the Main class without the VM arguments as well (using the command including the arguments as shared above.)
回答2:
If the accepted answer still did not work for you then..
The missing secret is to also include the maven-surefire-plugin
with the same compiler arg.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>10</source>
<target>10</target>
<compilerArgument>--add-modules=jdk.incubator.httpclient</compilerArgument>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.21.0</version>
<configuration>
<argLine>--add-modules=jdk.incubator.httpclient</argLine>
</configuration>
</plugin>
</plugins>
</build>
来源:https://stackoverflow.com/questions/47467663/java-9-httpclient-java-lang-noclassdeffounderror-jdk-incubator-http-httpclient