在 JLink 构建中从外部 url 加载图像时握手失败
Handshake failure when loading images from external url on JLink build
已解决 - 请参阅我的回答
问题
我正在尝试从外部 URL 加载图像并使用 JavaFX 将它们设置为 ImageView
。当 运行 在 IDE 中时,它总是有效,但是当我使用 JLink 构建项目时,只有来自几个 URL 的图像有效。
错误
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:313)
at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:186)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1144)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1055)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:395)
at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1587)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1515)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:250)
代码
最初,我认为问题是我没有设置User-Agent
,所以我修改了我的代码如下:
public boolean loadImage() {
if (!imageURL.isBlank() && image == null) {
try {
URLConnection conn = new URL(imageURL).openConnection();
conn.setRequestProperty("User-Agent", "Wget/1.13.4 (linux-gnu)");
InputStream stream = conn.getInputStream();
this.image = new Image(stream);
//original code
//this.image = new Image(imageURL, true);
} catch (Exception e) {
e.printStackTrace();
}
}
return image != null && image.isError();
}
在一些站点中,例如 https://imgur.com,它可以工作,即使使用较旧的代码 this.image = new Image(imageURL, true);
。但是在我尝试过的大多数网站上,我都收到了同样的错误:handshake_failure.
即使更改了代码,错误仍然存在。我尝试搜索但只找到与数据库相关的答案。
项目
您可以测试自己将项目 from its repository. You will need to update the loadImage
function on this file (Project.java:99) 克隆到上面的示例,因为 GitHub 上托管的是旧版本。
如果您 运行 在 IDE 上使用 gradlew run
,它将按预期工作。要检查图像是否正在加载,请转到菜单栏上的 Projects > Use Sample Data
。显示示例数据后,双击任何产品,图像应显示在右侧。所有样品产品都有图片;如果它不起作用,您会看到一个标签“该产品没有图像”。
当您从 JLink 在 /build/image/bin/StockManager.bat
生成的图像中 运行 时,您将收到 handshake_failure 错误。从样本数据中可用的产品来看,唯一可用的是“游戏笔记本电脑”。
截至目前,我使用的“解决方法”是在 https://imgur.com 中托管所有图像,因为当图像托管在那里时不会发生此错误。
解决方案
原来我需要在我的 module-info.java
中包含 requires jdk.crypto.ec;
。添加后,它在 IDE 和 JLink 构建中都能正常工作。
This 问题帮助我找到了这个解决方案
已解决 - 请参阅我的回答
问题
我正在尝试从外部 URL 加载图像并使用 JavaFX 将它们设置为 ImageView
。当 运行 在 IDE 中时,它总是有效,但是当我使用 JLink 构建项目时,只有来自几个 URL 的图像有效。
错误
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:313)
at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:186)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1144)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1055)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:395)
at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1587)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1515)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:250)
代码
最初,我认为问题是我没有设置User-Agent
,所以我修改了我的代码如下:
public boolean loadImage() {
if (!imageURL.isBlank() && image == null) {
try {
URLConnection conn = new URL(imageURL).openConnection();
conn.setRequestProperty("User-Agent", "Wget/1.13.4 (linux-gnu)");
InputStream stream = conn.getInputStream();
this.image = new Image(stream);
//original code
//this.image = new Image(imageURL, true);
} catch (Exception e) {
e.printStackTrace();
}
}
return image != null && image.isError();
}
在一些站点中,例如 https://imgur.com,它可以工作,即使使用较旧的代码 this.image = new Image(imageURL, true);
。但是在我尝试过的大多数网站上,我都收到了同样的错误:handshake_failure.
即使更改了代码,错误仍然存在。我尝试搜索但只找到与数据库相关的答案。
项目
您可以测试自己将项目 from its repository. You will need to update the loadImage
function on this file (Project.java:99) 克隆到上面的示例,因为 GitHub 上托管的是旧版本。
如果您 运行 在 IDE 上使用 gradlew run
,它将按预期工作。要检查图像是否正在加载,请转到菜单栏上的 Projects > Use Sample Data
。显示示例数据后,双击任何产品,图像应显示在右侧。所有样品产品都有图片;如果它不起作用,您会看到一个标签“该产品没有图像”。
当您从 JLink 在 /build/image/bin/StockManager.bat
生成的图像中 运行 时,您将收到 handshake_failure 错误。从样本数据中可用的产品来看,唯一可用的是“游戏笔记本电脑”。
截至目前,我使用的“解决方法”是在 https://imgur.com 中托管所有图像,因为当图像托管在那里时不会发生此错误。
解决方案
原来我需要在我的 module-info.java
中包含 requires jdk.crypto.ec;
。添加后,它在 IDE 和 JLink 构建中都能正常工作。
This 问题帮助我找到了这个解决方案