Я разрабатываю приложение javaFX 11, которое использует класс javafx.scene.image для загрузки изображения с URL:
Image(String url, boolean backgroundLoading)
где backgroundLoading имеет значение true.
Приложение отлично работает при запуске из моей Eclipse IDE (с использованием Maven). Но когда приложение создается как модульное (JRT) приложение, и я запускаю средство запуска для тестирования сборки, мои объекты Image не загружаются с назначенных им URL-адресов (протокол https) и вместо этого указывают на ошибку. Возвращенное исключение:
java.util.concurrent.ExecutionException: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Я пробовал переключить backgroundLoading на false и пробовал использовать URL-адреса с других сайтов, которые предоставляют доступ к изображениям. Я даже попытался изменить свойство протокола URL-адресов с «https» на «http». Все тот же результат.
У меня есть класс ImageHandler для обработки создания и настройки объектов javafx.scene.image и другой класс, который использует ImageHandler для установки изображения объекта javafx.scene.image.ImageView (с помощью прослушивателя для проверки завершения фоновой загрузки).
Я не могу предоставить полный код для воспроизведения проблемы, но вот несколько фрагментов из вышеупомянутых классов:
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.
Фактический результат: образы приложений создают SSLHandshakeException при запуске из встроенного модуля JRT.