我正在尝试在Java 9 maven项目中使用孵化器中的HttpClient。我没有得到任何编译问题。该项目成功建立。但是当我尝试运行Main类时,它给出了以下异常:
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)....
我的代码只是一个模块信息文件和一个只调用google.com并试图读取响应的Main类:
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>
我错过了什么?我找到了关于这个的各种文章,但他们都是这样做的。
任何帮助都是适用的。谢谢!
使用--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
何时不使用--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
答案 0 :(得分:8)
执行期间的差异是使用类路径与模块路径。要注意的 JEP11#Incubator Modules 中的陈述是
...对于应用程序,默认情况下不会解析孵化器模块 班级路径。
所以为了使用classpath执行代码
类路径上的应用程序必须使用
--add-modules
命令行选项,用于请求解析孵化器模块。
如果要在不使用--add-modules
选项的情况下执行,在创建新module
并尝试执行Main
类时,请确保使用模块路径执行java命令参数:
-p or --module-path <module path>
从以分号分隔的(;)目录列表中搜索目录。每个目录都是模块目录。
-m or --module <module>/<mainclass
指定要解析的初始模块的名称,如果模块未指定,则指定要执行的主类的名称。
完整的命令将是(例如)像:
.../jdk-9.0.1.jdk/Contents/Home/bin/java
-p .../jdk9-httpincubate-maven/target/classes
-m jdk.httpincubate.maven/http2.Main
<强> 注意 强>:
在我创建的示例项目on GitHub中遵循上述目录结构以复制相同的目录结构。
只是为了添加它而没有任何公开化我使用2017年的IntelliJ EAP,它让我 运行 Main类没有VM参数(使用包含上面共享的参数的命令。)
答案 1 :(得分:0)
如果接受的答案仍然不适合你那么..
缺少的秘密还包括具有相同编译器arg的maven-surefire-plugin
。
<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>