Ошибка JAVA 8u77 classLoader - ищем обходной путь
JAVA 8u77 был выпущен на прошлой неделе (23 марта 2016 г.)
Привет, опубликовал месяц назад связанный вопрос (касательно JAVA 8u74). Сейчас я публикую новый вопрос, поскольку у нас есть более точная информация, и мой вопрос немного отличается.
С моим приложением веб-запуска, если клиент установил обновление, он получит ошибки во время работы:
java.security.cert.CertificateException:
Could not verify signing in resource: https://www.example.com:443/app/myFile.jar
at com.sun.deploy.security.TrustDecider.ensureAllJarEntriesSigned(Unknown Source)
….
Погружаясь в код, я заметил, что ошибка выдается для следующей строки:
ClassLoader classLoader = this.getClass().getClassLoader();
classLoader.getResource("").getPath();
вторая строка возвращает NULL.
Этот код работает с JAVA 8u73 и более ранними версиями. Oracle подтвердил, что это ошибка - https://bugs.openjdk.java.net/browse/JDK-8152827
Тем не менее, я не уверен, что могу дождаться исправления ошибки... Мы пытаемся найти обходной путь...
Это то, что я нашел -
Файлы JAR, к которым мы пытаемся получить доступ с помощью загрузчика классов, не являются частью пути к классу приложения. Они содержат файлы, которые не являются частью кода JAVA.
Мы заметили, что если добавить файл класса в JAR и затем установить JAR как часть проекта и classpath, ошибка не воспроизводится.
Но наша проблема в том, что у нас длинный динамический список файлов JAR (мы регулярно создаем новые JAR-файлы). Каждый раз, когда приложение загружается (используя файл JNLP) - мы динамически добавляем необходимые JAR-файлы в список файлов JNLP. Мы не сможем сделать новое развертывание приложения для каждого нового JAR, который мы создаем. (как уже упоминалось - у этих JAR нет кода JAVA.)
Конечно, все банки подписаны одним и тем же доверенным сертификатом. И - опять же - без проблем работал на 8у73.
У кого-нибудь есть идеи для обхода?
Спасибо
7 ответов
Oracle имеет информацию об этой ошибке здесь, https://bugs.openjdk.java.net/browse/JDK-8151624, но широкая публика не имеет доступа для чтения к этому URL. (Я тоже не знаю, но ошибка, которую вы связали, помечена как дубликат скрытой ошибки.)
Таким образом, мы ничего не можем сделать, об этом не сообщается от Oracle, и обходной путь должен использовать 8u73.
Вам придется удалить предыдущую JRE вручную ( http://java.com/newerversionexists перенаправит вас на инструкции, основанные на операционной системе вашего браузера), а затем загрузить 8u73 здесь: http://www.oracle.com/technetwork/java/javase/downloads/java-archive-javase8-2177648.html
Но: вам нужно будет зарегистрировать учетную запись Oracle и дать им свой адрес электронной почты, номер телефона и т. Д., Чтобы ссылка для скачивания работала.
Отличная работа, Oracle.
Я видел эту проблему при вызове ClassLoader.getResource / getResourceAsStream, но не при вызове getResources. Таким образом, возможный обходной путь может заключаться в использовании:
Thread.currentThread (). GetContextClassLoader(). GetResources("некоторые / путь").
Путь должен быть абсолютным, но не начинаться с '/'. Тип возвращаемого значения - перечисление URL.
Мы обнаружили, что это исключение в JRE 8u74-77 вызвано загрузкой ресурсов из другого JAR. Так this.getClass()
не достаточно хорош Другой пример, призыв к ResourceBundle.getBundle()
должен иметь третий параметр - загрузчик для класса из JAR, где расположены ресурсы. Существует также возможность перетасовывать файлы ресурсов между файлами JAR. Еще больше проблем с библиотеками сторонних производителей, такими как SwingX.
Странно, что выброшенное исключение CertificateException
когда более подходящим будет "Ресурс не найден".
Только что протестировал 1.8u91, и проблема не была исправлена, как было указано в предыдущем комментарии.
У меня есть приложение с точно такой же проблемой (трассировка стека, как в вопросе). Все работает с 8u73
,
С 8u74
ошибка воспроизводима каждый раз, когда Java Control Panel
- Настройки временных файлов - "Хранить временные файлы на моем компьютере". Если флажок не установлен, ошибка не воспроизводится.
То же самое относится и к 8u77
, Единственное различие, которое я обнаружил до сих пор: если сначала "Не сохранять временные файлы на моем компьютере", а затем проверять снова, ошибка не будет воспроизводиться каждый раз. Причина этого неизвестна.
Пожалуйста, имейте в виду, что снятие отметки с этой опции в Java Control Panel
может снизить производительность вашего приложения. Тем не менее, в зависимости от ваших клиентов и приложения это может быть лучшим решением, чем просто не обновлять.
Обходным решением для меня было объявление зависимостей в архиве jnlp без использования тега "версия".
Так, например, этот способ отлично работает:
<jar href="spring-aop-u15-2.5.5.jar"/>
Это решение имеет следующий побочный эффект:
- Протокол загрузки версии не вступает в силу, поэтому каждый раз, когда пользователь выполняет приложение, jws будет запрашивать у сервера каждый jar-файл, содержащийся в приложении. JAR-файл не будет обновлен, потому что, вероятно, сервер ответит 304 с указанием того, что оно уже обновлено, но если ваше приложение содержит много библиотек, у вас будет некоторая задержка при запуске приложения, так как для каждой библиотеки будет один http-запрос.
Темный ход кажется. Очевидно, что клиенты на Java SE Advanced могли бы сразу воспользоваться исправлением ошибки, но неоплачиваемые клиенты все еще ждут первого выпуска GA, содержащего исправление ошибки. Плюс вся эта проблема публичных JBS, помеченных как дубликаты частных проблем, статус которых не виден.