从 URL 构建的 JavaFX 11 javafx.scene.image 在应用程序 运行 来自构建的 JRT 模块时抛出 SSLHandshakeException
JavaFX 11 javafx.scene.image constructed from URL is throwing SSLHandshakeException when application is run from built JRT module
我正在开发一个 javaFX 11 应用程序,它使用 javafx.scene.image class 从 URL 加载图像:
Image(String url, boolean backgroundLoading)
其中 backgroundLoading 设置为 true。
当 运行 从我的 Eclipse IDE(使用 Maven)时,应用程序工作正常。但是当应用程序构建为模块化 (JRT) 应用程序并且我 运行 启动程序来测试构建时,我的图像对象不会从它们分配的 URLs(https 协议)加载,而是指示一个错误。返回的异常是:
java.util.concurrent.ExecutionException: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
我已经尝试将 backgroundLoading 切换为 false 并尝试从其他提供图像访问的站点 URLs。我什至尝试将 URL 的协议 属性 从 "https" 更改为 "http"。还是一样的结果。
我有一个 ImageHandler class 用于处理 javafx.scene.image 对象的构造和设置以及另一个 class 使用 ImageHandler 设置 javafx.scene.image.ImageView 对象的图像(通过使用侦听器检查何时后台加载已完成。
我无法提供重现问题的完整代码,但这里有一些来自上述 classes 的片段:
ImageHandler - getImage():
public Image getImage() {
if (this.image == null || this.imageHadErrorLoading()) {
this.imageUrl = String.format(Settings.GATHERER_URL + ImageHandler.QUERY_DATA, this.multiverseId);
LoggerUtil.logger(this).log(Level.INFO, String.format("URL for image: %s", this.imageUrl));
try {
this.image = new Image(this.imageUrl, this.backgroundLoading);
this.setImageError(false);
} catch (Exception e) {
LoggerUtil.logger(this).log(Level.SEVERE, String.format("Exception creating new Image: %s", e.toString()));
}
}
return this.image;
}
ViewController - setCurrentImage():
private void setCurrentImage(int multiverseId) {
ImageHandler imageHandler;
imageHandler = new ImageHandler(multiverseId, true);
Image cardImage = imageHandler.getImage();
// If the image was previously loaded (successfully), just set the image.
// Otherwise, use a listener to monitor the loading of the image which
// eventually sets the image once it has successfully loaded.
if (imageHandler.imageHasLoaded()) {
this.cardImageView.setImage(cardImage);
LoggerUtil.logger(this).log(Level.INFO, String.format("Multiverse ID %d: Image cached....getting image....", multiverseId));
} else {
// This listener on the image's progress is used to set the Image View when the image has finally loaded. In the meantime,
// the Image View will continue to display the "placeholder" image.
cardImage.progressProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
double cardProgress = (double) newValue;
if (cardProgress == 1.0) {
if (cardImage.isError()) {
cardImageView.setImage(imageHandler.getErrorImage());
LoggerUtil.logger(this).log(Level.SEVERE, String.format("Multiverse ID %d: Error loading image.", multiverseId));
LoggerUtil.logger(this).log(Level.SEVERE, String.format("Image exception was: %s", cardImage.getException().getMessage()));
LoggerUtil.logger(this).log(Level.SEVERE, String.format("Image exception was: %s", cardImage.getException()));
} else {
cardImageView.setImage(cardImage);
imageHandler.setImageLoaded(true);
LoggerUtil.logger(this).log(Level.INFO, String.format("Multiverse ID %d: Image loaded successfully! Image URL: %s", multiverseId, cardImage.getUrl()));
}
}
}
});
}
预期结果:
当 运行 来自构建的 JRT 模块时,应用程序显示图像并且具有与来自 Eclipse IDE.
的 运行 相同的行为
实际结果:
当 运行 来自构建的 JRT 模块
时,应用程序映像产生 SSLHandshakeException
感谢@jewelsea,我发现在使用 javafx-maven-plugin. See this answer 构建应用程序时,我需要添加 jdk.crypto.ec 作为模块选项以获取详细信息.
在 Eclipse 中使用 OpenJDK 11 并从源代码中使用 运行 时它工作正常,但某些模块(例如 jdk.crypto.ec 在构建时必须默认省略通过 jlink 的 JRT 图像,除非特别添加。
这是我在 Maven POM 中更新的 javafx-maven-plugin 定义:
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.2</version>
<configuration>
<release>11</release>
<jlinkImageName>thecollector</jlinkImageName>
<launcher>launcher</launcher>
<mainClass>thecollector/com.cladge.thecollector.MainApp</mainClass>
<options>
<option>--add-modules</option>
<option>jdk.crypto.ec</option>
</options>
</configuration>
</plugin>
我正在开发一个 javaFX 11 应用程序,它使用 javafx.scene.image class 从 URL 加载图像:
Image(String url, boolean backgroundLoading)
其中 backgroundLoading 设置为 true。
当 运行 从我的 Eclipse IDE(使用 Maven)时,应用程序工作正常。但是当应用程序构建为模块化 (JRT) 应用程序并且我 运行 启动程序来测试构建时,我的图像对象不会从它们分配的 URLs(https 协议)加载,而是指示一个错误。返回的异常是:
java.util.concurrent.ExecutionException: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
我已经尝试将 backgroundLoading 切换为 false 并尝试从其他提供图像访问的站点 URLs。我什至尝试将 URL 的协议 属性 从 "https" 更改为 "http"。还是一样的结果。
我有一个 ImageHandler class 用于处理 javafx.scene.image 对象的构造和设置以及另一个 class 使用 ImageHandler 设置 javafx.scene.image.ImageView 对象的图像(通过使用侦听器检查何时后台加载已完成。
我无法提供重现问题的完整代码,但这里有一些来自上述 classes 的片段:
ImageHandler - getImage():
public Image getImage() {
if (this.image == null || this.imageHadErrorLoading()) {
this.imageUrl = String.format(Settings.GATHERER_URL + ImageHandler.QUERY_DATA, this.multiverseId);
LoggerUtil.logger(this).log(Level.INFO, String.format("URL for image: %s", this.imageUrl));
try {
this.image = new Image(this.imageUrl, this.backgroundLoading);
this.setImageError(false);
} catch (Exception e) {
LoggerUtil.logger(this).log(Level.SEVERE, String.format("Exception creating new Image: %s", e.toString()));
}
}
return this.image;
}
ViewController - setCurrentImage():
private void setCurrentImage(int multiverseId) {
ImageHandler imageHandler;
imageHandler = new ImageHandler(multiverseId, true);
Image cardImage = imageHandler.getImage();
// If the image was previously loaded (successfully), just set the image.
// Otherwise, use a listener to monitor the loading of the image which
// eventually sets the image once it has successfully loaded.
if (imageHandler.imageHasLoaded()) {
this.cardImageView.setImage(cardImage);
LoggerUtil.logger(this).log(Level.INFO, String.format("Multiverse ID %d: Image cached....getting image....", multiverseId));
} else {
// This listener on the image's progress is used to set the Image View when the image has finally loaded. In the meantime,
// the Image View will continue to display the "placeholder" image.
cardImage.progressProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
double cardProgress = (double) newValue;
if (cardProgress == 1.0) {
if (cardImage.isError()) {
cardImageView.setImage(imageHandler.getErrorImage());
LoggerUtil.logger(this).log(Level.SEVERE, String.format("Multiverse ID %d: Error loading image.", multiverseId));
LoggerUtil.logger(this).log(Level.SEVERE, String.format("Image exception was: %s", cardImage.getException().getMessage()));
LoggerUtil.logger(this).log(Level.SEVERE, String.format("Image exception was: %s", cardImage.getException()));
} else {
cardImageView.setImage(cardImage);
imageHandler.setImageLoaded(true);
LoggerUtil.logger(this).log(Level.INFO, String.format("Multiverse ID %d: Image loaded successfully! Image URL: %s", multiverseId, cardImage.getUrl()));
}
}
}
});
}
预期结果: 当 运行 来自构建的 JRT 模块时,应用程序显示图像并且具有与来自 Eclipse IDE.
的 运行 相同的行为实际结果: 当 运行 来自构建的 JRT 模块
时,应用程序映像产生 SSLHandshakeException感谢@jewelsea,我发现在使用 javafx-maven-plugin. See this answer 构建应用程序时,我需要添加 jdk.crypto.ec 作为模块选项以获取详细信息.
在 Eclipse 中使用 OpenJDK 11 并从源代码中使用 运行 时它工作正常,但某些模块(例如 jdk.crypto.ec 在构建时必须默认省略通过 jlink 的 JRT 图像,除非特别添加。
这是我在 Maven POM 中更新的 javafx-maven-plugin 定义:
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.2</version>
<configuration>
<release>11</release>
<jlinkImageName>thecollector</jlinkImageName>
<launcher>launcher</launcher>
<mainClass>thecollector/com.cladge.thecollector.MainApp</mainClass>
<options>
<option>--add-modules</option>
<option>jdk.crypto.ec</option>
</options>
</configuration>
</plugin>