Программа работает в Eclipse, но не как jar

Мой компилятор настроен на совместимость с Java 1.8. Когда я запускаю свой код, он работает и никаких предупреждений нет.

Когда я экспортирую все в виде работоспособного jar-файла и выполняю его, выдается эта ошибка:

Exception in thread "main" java.lang.NoSuchMethodError: java.net.URLEncoder.encode(Ljava/lang/String;Ljava/nio/charset/Charset;)Ljava/lang/String;
        at ...

Моему коду необходимо преобразовать некоторую строку пользовательского ввода для выполнения API-вызова, для чего он должен быть совместимым с URL-адресом, например заменив пробелы на «%20». Для этого я использую java.net.URLEncoder.encode.

В моей системе установлена ​​версия jre 1.8.0_411, так что этого не должно происходить, верно?

Да, так и должно быть. Этот метод появился в Java 10. Вы можете сделать второй параметр a String Когда я запускаю свой код, он работает и никаких предупреждений не появляется. Потому что он запускается и компилируется с >= 10

g00se 28.05.2024 18:33

опубликованный метод доступен начиная с Java 10 – возможная ошибка, код был написан и скомпилирован с использованием более новой версии – проверьте свойства проекта (в основном путь сборки Java – библиотеки – системная библиотека JRE) и используйте другой метод, который требует двух струны

user85421 28.05.2024 18:37

(простого соответствия версии 1.8 недостаточно; вы должны проявлять особую осторожность, чтобы не использовать методы, недоступные в версии 1.8, при использовании другой библиотеки JRE - настоятельно рекомендуется использовать правильную версию библиотеки JRE)

user85421 28.05.2024 18:44
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
3
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Есть 3 едва связанных между собой аспекта, которые все объединяются в «.. будет работать на Java 1.8»:

  • Любые обновления самой спецификации языка. Например, концепция «var» была введена в Java 10. В Java 9 ее не было. Это не библиотечная функция; вам не нужно ничего импортировать, чтобы использовать var в Java. Его просто… вообще нельзя использовать в Java9 и более ранних версиях, и он появляется только начиная с Java 10. Вот для чего предназначена опция --source.

  • Спецификация файла класса — это отдельная вещь, но на практике она обновляется для каждого выпуска Java, и всегда несовместимым образом. Создание файла класса, который java.exe из Java 1.8 не может запустить, означает, что он не будет работать в Java 1.8. Как правило, любые новые функции исходного кода требуют формата файла класса, который соответствует этой версии Java. Это то, для чего нужен --target.

  • Java поставляется с обширной стандартной библиотекой, которая обновляется с каждым выпуском Java. Использование чего-либо, что было добавлено, скажем, в Java 1.9 (т.е. не было в Java 1.8), приведет именно к этой ошибке.

Вы не можете просто сказать eclipse: «Эй, пожалуйста, только вещи 1.8» и ожидать, что последний пункт «просто сработает» - знать, что доступно, а что нет в Java 1.8, сложно, потому что стандартная библиотека на самом деле не поставляется. с информацией «это было здесь с версии X», поэтому eclipse не может работать: О, эй, подожди секунду, ты используешь что-то, чего не было в Java 1.8. Кажется, что он есть (теги javadoc @since), но это не гарантируется спецификацией Java.

Следовательно, чтобы знать, eclipse необходима фактическая установка Java 1.8. Вы говорите, что он у вас есть – окей, отлично! Расскажите об этом Eclipse, и тогда он сможет вам помочь.

Процедура следующая:

  • В настройках eclipse используйте поле фильтра для поиска «JRE» и добавьте свой путь к Java 1.8. Eclipse должен автоматически сообщить вам: «А, это Java версии 1.8». Обратите внимание, что JRE здесь бесполезна. Получите JDK. Обратите внимание, что JRE как концепция умерла более 10 лет назад и больше не существует. Получите JDK v1.8 и сообщите об этом eclipse.
  • Затем в настройках вашего проекта установите для всего Java 1.8: совместимость с языком, вывод классов и JDK, который будет использоваться для компиляции - для которого вы можете установить значение 1.8, если вы выполнили предыдущий шаг.

Или... перейдите в командную строку и используйте базовый инструмент сборки, который вы установили в Eclipse. Вы используете один, верно? Установите JAVA_HOME (временно) для установки JDK 8, а затем выполните maven clean compile exec:java (или эквивалент Gradle). Тогда не будет никаких сомнений в используемой версии. И я рекомендую сделать это, даже если вы не измените версию, вы не останетесь без Eclipse.

g00se 28.05.2024 18:45

Другие вопросы по теме