javax.net.ssl.SSLHandshakeException 在使用自定义 java 运行时图像时发生但并非没有
javax.net.ssl.SSLHandshakeException happening when using custom java runtime image but not without
我有这个 class,它只发送一个 http post 请求:
import java.net.*; import java.io.*;
public class JarRuntimeTest{
public void start() throws Exception{
HttpURLConnection connection = (HttpURLConnection) (new URL("https://google.com").openConnection());
connection.setRequestMethod("POST");
System.out.println(
getResult((connection.getResponseCode() == HttpURLConnection.HTTP_OK)?
connection.getInputStream():connection.getErrorStream()));
}
public String getResult(InputStream in) throws Exception{
StringBuilder builder = new StringBuilder("");
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = null;
while ((line = reader.readLine()) != null) builder.append(line);
reader.close();
return builder.toString();
}
public static void main(String[] args){try{new JarRuntimeTest().start();}catch(Exception e){e.printStackTrace();}}
}
我有这个 .bat
文件,它构建了我的 jar 和 java 运行time 图像,并将这个自定义 运行time 图像用于 运行 我的罐子:
@echo off
javac JarRuntimeTest.java
jar --create --file thisismyjar.jar --main-class JarRuntimeTest JarRuntimeTest.class
jdeps --list-deps thisismyjar.jar
jlink --add-modules java.base --output myruntime
myruntime\bin\java.exe -jar thisismyjar.jar
pause
如果我 运行 使用自定义 jre 的应用程序,我得到一个错误:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
但是,如果我 运行 应用程序以没有自定义 jre 的正常方式运行,我不会收到此错误。这个问题是因为自定义jre没有正确构建,我的自定义jre中是否缺少一些模块?或者这是一个完全不同的问题?如果缺少某些模块,我应该怎么做才能包含它们?哪一个?我怎么知道?我只添加了从 jdeps
输出的模块
这是我得到的整个堆栈跟踪:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:356)
at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:202)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:171)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1498)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1404)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:441)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:412)
at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:574)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:183)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1653)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1577)
at java.base/java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:527)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:308)
at JarRuntimeTest.start(JarRuntimeTest.java:7)
at JarRuntimeTest.main(JarRuntimeTest.java:18)
这是我为 运行time 添加的模块:java.base
,因为这是从 jdeps 输出的内容。
如@dave_thompson_085 所述,必须包含 jdk.crypto.ec
。我不确定为什么 jdeps 没有显示这一点。无论如何,将它包含在我的 jlink 命令中就可以了,而且它起作用了:
jlink --add-modules java.base,jdk.crypto.ec --output myruntime
myruntime\bin\java.exe -jar thisismyjar.jar
我有这个 class,它只发送一个 http post 请求:
import java.net.*; import java.io.*;
public class JarRuntimeTest{
public void start() throws Exception{
HttpURLConnection connection = (HttpURLConnection) (new URL("https://google.com").openConnection());
connection.setRequestMethod("POST");
System.out.println(
getResult((connection.getResponseCode() == HttpURLConnection.HTTP_OK)?
connection.getInputStream():connection.getErrorStream()));
}
public String getResult(InputStream in) throws Exception{
StringBuilder builder = new StringBuilder("");
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = null;
while ((line = reader.readLine()) != null) builder.append(line);
reader.close();
return builder.toString();
}
public static void main(String[] args){try{new JarRuntimeTest().start();}catch(Exception e){e.printStackTrace();}}
}
我有这个 .bat
文件,它构建了我的 jar 和 java 运行time 图像,并将这个自定义 运行time 图像用于 运行 我的罐子:
@echo off
javac JarRuntimeTest.java
jar --create --file thisismyjar.jar --main-class JarRuntimeTest JarRuntimeTest.class
jdeps --list-deps thisismyjar.jar
jlink --add-modules java.base --output myruntime
myruntime\bin\java.exe -jar thisismyjar.jar
pause
如果我 运行 使用自定义 jre 的应用程序,我得到一个错误:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
但是,如果我 运行 应用程序以没有自定义 jre 的正常方式运行,我不会收到此错误。这个问题是因为自定义jre没有正确构建,我的自定义jre中是否缺少一些模块?或者这是一个完全不同的问题?如果缺少某些模块,我应该怎么做才能包含它们?哪一个?我怎么知道?我只添加了从 jdeps
这是我得到的整个堆栈跟踪:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:356)
at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:202)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:171)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1498)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1404)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:441)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:412)
at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:574)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:183)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1653)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1577)
at java.base/java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:527)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:308)
at JarRuntimeTest.start(JarRuntimeTest.java:7)
at JarRuntimeTest.main(JarRuntimeTest.java:18)
这是我为 运行time 添加的模块:java.base
,因为这是从 jdeps 输出的内容。
如@dave_thompson_085 所述,必须包含 jdk.crypto.ec
。我不确定为什么 jdeps 没有显示这一点。无论如何,将它包含在我的 jlink 命令中就可以了,而且它起作用了:
jlink --add-modules java.base,jdk.crypto.ec --output myruntime
myruntime\bin\java.exe -jar thisismyjar.jar