英文:
Handshake failure when loading images from external url on JLink build
问题
# Solved - 请查看我的回答
### 问题
我尝试从外部URL加载图像,并使用JavaFX将它们设置到`ImageView`中。在IDE内运行时总是正常工作,但是当我使用JLink构建项目时,只有从少数几个URL加载的图像能正常显示。
### 错误
```java
javax.net.ssl.SSLHandshakeException: 收到致命警报: 握手失败
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);
//原始代码
//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。
即使更改了代码,错误仍然存在。我尝试搜索,但只找到与数据库相关的答案。
项目
您可以从其存储库克隆项目进行测试。您需要更新此文件中的loadImage
函数(Project.java:99)为上面的示例,因为GitHub上托管的版本是旧版本。
如果您在IDE上使用gradlew run
运行它,它将按预期工作。要检查图像是否正在加载,请转到菜单栏上的Projects > Use Sample Data
。显示样本数据后,双击任何产品,图像应显示在右侧。所有示例产品都有图像;如果不起作用,您将看到标签“此产品没有图像”。
当您从/build/image/bin/StockManager.bat
中的JLink生成的图像运行它时,您将收到handshake_failure
错误。从样本数据中可用的产品中,唯一正常工作的是“Gaming Laptop”。
截至目前,我使用的“变通方法”是将所有图像托管在https://imgur.com,因为在那里托管图像时不会出现此错误。
<details>
<summary>英文:</summary>
# Solved - See my answer
### Problem
I'm trying to load images from external URLs and set them to an `ImageView` using JavaFX. It always works when running inside the IDE, but when I build the project using JLink, only images from a few URLs work.
### Error
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)
### Code
Initially, I thought the problem was that I was not setting a `User-Agent`, so I modified my code to the following:
```java
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();
}
In a few sites, https://imgur.com for instance, it works, even with the older code this.image = new Image(imageURL, true);
. But on the majority of the sites I tried I received the same error: handshake_failure.
Even after changing the code, the error continued. I tried searching but only found answers related to databases.
Project
You may test yourself cloning the project from its repository. You will need to update the loadImage
function on this file (Project.java:99) to the example above since the one hosted on GitHub is the older version.
If you run it on the IDE, using gradlew run
, it will work as expected. To check if the images are loading, go to Projects > Use Sample Data
on the menu bar. Once the sample data is displayed, double-click any of the products, and the image should display on the right side. All the sample products have images; if it's not working you will see a label "This product has no image".
The moment you run it from the JLink generated image at /build/image/bin/StockManager.bat
, you will get the handshake_failure error. From the products available in the sample data, the only one that is working is the "Gaming Laptop".
As of right now, the "workaround" I'm using is to host all images in https://imgur.com since this error doesn't happen when the image is hosted there.
答案1
得分: 5
解决方案
原来我需要在我的 module-info.java
文件中包含 requires jdk.crypto.ec;
。在添加了这一行之后,无论是在集成开发环境(IDE)中还是在 JLink 构建中,都可以正常工作。
这个 问题帮助我找到了这个解决方案。
英文:
Solution
It turns out I needed to include requires jdk.crypto.ec;
on my module-info.java
. After adding it, it worked properly both in the IDE and in the JLink build.
This question helped me to find this solution
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论