Java UnsupportedClassVersionError (51), но только при выполнении команды с удаленного компьютера

У меня есть простая установка TestNG, где я вызываю основной класс из командной строки. Тесты проходят отлично.

Я запускаю их из командной строки, потому что мне нужно запустить выполнение из HP Quality Center. Это также работает, если QC-клиент, запускающий командную строку, работает в том же месте, что и скомпилированные тестовые классы.

Однако, если я пытаюсь вызвать командную строку с удаленного хоста, я получаю небольшую главную ошибку 51. Я знаю, что это означает, что классы были скомпилированы с использованием Java 1.7, и попробуйте запустить с использованием более низкого уровня Java. Что я не понимаю, так это как и почему он использует более низкую версию Java. командная строка java -version показывает, что на исполняющей ВМ работает Java 1.8_91. Раньше был 1.6_19, но я его обновил. Я также изменил системные переменные для path и JAVA_HOME и просмотрел другие системные переменные, не найдя ничего выдающегося.

Как это возможно, что командная строка запускает две разные версии Java времени выполнения при исполнении с локального и удаленного хоста? Как я могу это исправить, чтобы они использовали 1.8 в обоих случаях?

PS, понижение скомпилированных классов до 1.6 - не вариант, так как TestNG зависит от версии 1.7

Вот исключение:

Error Number: 8
Source: executeCommand
Description: java.lang.UnsupportedClassVersionError: org/testng/TestNG : Unsupported major.minor version 51.0
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(Unknown Source)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at java.security.SecureClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.access$000(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: org.testng.TestNG.  Program will exit.
Exception in thread "main" While executing command: java -cp c:\test\Execution\lib\*;c:\test\Execution\bin org.testng.TestNG c:\test\Execution\testng.xml

и сама команда:

C:\Users\myUser>java -cp C:\test\Execution\lib\*;C:\test\Execution\bin org.testng.TestNG C:\test\Execution\testng.xml

lib включает в себя несколько jar-файлов, таких как Selenium и TestNG. testng.xml может содержать конфигурации для точного определения, какие тесты должны выполняться внутри класса, но в этом случае он пуст. Папка bin содержит сам скомпилированный тестовый сценарий java и некоторые файлы данных, используемые для параметров.

ОБНОВЛЕНИЕ: я должен был, конечно, запустить простой java -version, с самого начала, но теперь у меня есть, и вот результаты:

При запуске непосредственно из командной строки внутри виртуальной машины:

java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)

При выполнении из Quality Center Script, из браузера внутри виртуальной машины (здесь мне нужно сохранить в файл, чтобы увидеть фактический результат, и это, кажется, работает только при использовании java -verbose -version):

[Opened D:\java\JDK 1.8.0_91\lib\rt.jar]
[Loaded java.lang.Object from D:\java\JDK 1.8.0_91\lib\rt.jar]
[Loaded java.io.Serializable from D:\java\JDK 1.8.0_91\lib\rt.jar]
... etc

При выполнении из Quality Center Script из браузера вне виртуальной машины (также java -verbose -version):

[Loaded java.lang.Object from shared objects file]
[Loaded java.io.Serializable from shared objects file]
[Loaded java.lang.Comparable from shared objects file]
....
[Opened C:\Program Files (x86)\Java\jre6\lib\rt.jar]
....

После удаления вышеупомянутой папки Java и всего ее содержимого вывод команды был полностью пустым в моем текстовом файле.

этот вопрос, что такое файл общих объектов?, дает мне небольшое представление о том, что происходит, но я до сих пор не понимаю, почему одно конкретное исполнение выбирает другой JRE, чем другие, или как это исправить...

2 ответа

Решение

Выполните его с параметром -verbose. Это покажет вам, какие файлы Java действительно используются.

java -verbose -cp C:\test\Execution\lib\*;C:\test\Execution\bin org.testng.TestNG C:\test\Execution\testng.xml

Если по какой-либо причине в вашей среде QC используется другая версия Java, используйте полный путь для выполнения Java 8.

%java_home%/bin/java -cp C:\test\Execution\lib\*;C:\test\Execution\bin org.testng.TestNG C:\test\Execution\testng.xml

Из вашего вопроса, кажется, что версия JDK на вашем удаленном хосте - 1.8_91, тогда как версия на вашем локальном хосте - 1.7. Поправьте меня если я ошибаюсь.

Вы должны использовать одну и ту же версию JDK во всех местах, где вы запускаете этот код. Кроме того, используя плагин компилятора maven, вы можете убедиться, что код компилируется в вашей предполагаемой версии:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.5.1</version>
    <inherited>true</inherited>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
    </configuration>
</plugin>
Другие вопросы по тегам