--- SPOILER ALERT ---
Краткий ответ: для того, чтобы скомпилировать исходный код в более старую версию, вам необходимо указать и параметр -source
.как -bootclasspath
.См. эту статью .И если вы хотите скомпилировать исходный код в более новую версию, вам нужно установить <source>
, <target>
, <compilerVersion>
, <fork>
и <executable>
в плагине компилятора, и set <jvm>
на плагине surefire ...
А теперь для истории ...
Я столкнулся с той же проблемой.Оказывается, компиляция предыдущей версии может быть не такой простой, как установка <source>
и <target>
.Мой конкретный случай - у меня Java 1.7 JDK, и у моего класса несовместимость с 1.7 (они добавили новый метод в интерфейс, который я реализую) .Когда я пытался скомпилировать его, компилятор выдал мне сообщение об ошибке, в котором говорилось, что я не реализовал метод интерфейса.В любом случае, я попытался установить плагин компилятора:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
, но когда я запустил сборку, я получил ту же ошибку.Поэтому я запустил maven в режиме отладки и увидел следующее:
[INFO] [DEBUG] Command line options:
[INFO] [DEBUG] -d C:\... -nowarn -target 1.6 -source 1.6 -encoding UTF-8
Обратите внимание, что ... для краткости вместо фактических аргументов ставится ... 1034 *
inвыход.Сообщение, начинающееся с -d
, является фактическим полным списком аргументов компиляции.Таким образом, если вы уберете флаг -nowarn
и вставите остальное после javac
в командной строке, вы сможете увидеть фактический вывод компилятора:
javac -d C:\... -target 1.6 -source 1.6 -encoding UTF-8
warning: [options] bootstrap class path not set in conjunction with -source 1.6
Это выводит на экран предупреждение об удобстве Путь к классу начальной загрузки не задан в сочетании с -source 1.6 .Немного прибегая к помощи, которая обнаруживает эту статью , в которой говорится:
Чтобы использовать javac из JDK N для кросс-компиляции на более старую версию платформы, правильная практика заключается в следующем:
- Используйте более старую настройку -source.
- Установите bootclasspath для компиляции с rt.jar (или эквивалентным) для более старой платформы.
Есливторой шаг не сделан, javac будет должным образом использовать старые языковые правила в сочетании с новыми библиотеками, что может привести к тому, что файлы классов не будут работать на более старой платформе, поскольку могут быть включены ссылки на несуществующие методы.
Теперь ссылаясь на , документация maven для плагина компилятора дает:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<compilerArguments>
<verbose />
<bootclasspath>${java.home}\lib\rt.jar</bootclasspath>
</compilerArguments>
</configuration>
</plugin>
, которую затем можно объединить с более ранней конфигурацией, чтобы получить:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>UTF-8</encoding>
<bootclasspath>${java.home}\lib\rt.jar</bootclasspath>
</configuration>
</plugin>
А теперь вам просто нужно сделать переменную ${java.home}
доступной для вашего mvn (через системные свойства -D, или через простые старые переменные окружения, или вы можете получить действительно модные вещи и прочее)это в профиле java 6 в ваших пользовательских настройках).
Теперь просто запустите сборку и возьмите холодное пиво, пока оно выпрыгивает ...
---- EDIT ----
И еще одна вещь ... Включение rt.jar в путь начальной загрузки всегда требуется, однако я обнаружил, что в каждом конкретном случае может потребоваться больше.Мне пришлось включить jce.jar (в тот же каталог, что и rt.jar), потому что мое приложение выполняло криптографическую работу.
---- EDIT 2 ----
Для ухмылок,Я попробовал это в другом направлении.Вместо запуска maven с компиляцией java 7 для java 6, я запустил maven с компиляцией java 6 для java 7. Первая попытка довольно проста:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<fork>true</fork>
<verbose>true</verbose>
<compilerVersion>1.7</compilerVersion>
<executable>${JAVA_7_HOME}/bin/javac</executable>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
По сути, я установил <source>
и <target>
до 1,7, но этого явно недостаточно, потому что 6 не могут скомпилировать 7 кодов.Итак, вернемся к плагину компилятора, на самом деле пример страницы , описывающей, что нужно сделать.А именно, вам нужно <fork>
отключить новый процесс с использованием Java 7 <executable>
.Так что теперь я думаю, что все готово.Время запустить сборку ...
C:\Projects\my-project>mvn package
...
Caused by: java.lang.UnsupportedClassVersionError: mypackage.StupidTest : Unsup
ported major.minor version 51.0
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
Какого черта UnsupportedClassVersionError?Более внимательный взгляд говорит нам о том, что это maven-surefire-plugin, который не работает.Поэтому я пробую просто mvn compile
и, конечно же, получаю успех, так как плагин surefire никогда не запускается.Итак, я запускаю mvn -X package
и замечаю этот драгоценный камень:
Forking command line: cmd.exe /X /C ""C:\Program Files\Java\jdk1.6.0_29\jre\bin\
java" -jar C:\Projects\my-project\target\surefire\surefirebooter2373372991878002
398.jar C:\Projects\my-project\target\surefire\surefire1861974777102399530tmp C:
\Projects\my-project\target\surefire\surefire4120025668267754796tmp"
Хорошо, так что работает Java 6. Почему?Документация для безошибочного дает это:
jvm:
Option to specify the jvm (or path to the java executable) to use with the forking
options. For the default, the jvm will be a new instance of the same VM as the one
used to run Maven. JVM settings are not inherited from MAVEN_OPTS.
Поскольку мы запустили mvn с виртуальной машиной Java 6, она создала виртуальную машину Java 6 для своих модульных тестов. Поэтому, установив эту опцию соответствующим образом:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<jvm>${JAVA_7_HOME}/bin/java</jvm>
</configuration>
</plugin>
И запустить сборку ...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------