Подтвердить что ты не робот

Maven: javac: исходный релиз 1.6 требует целевого релиза 1.6

ПРИМЕЧАНИЕ. Это, по-видимому, предел в программе "javac".

У меня есть код Java 6, который необходимо создать для Java 5 JVM. Моя предыдущая работа с целью javac ant (как с компилятором JDK, так и с ecj) заставила меня поверить, что это просто вопрос настройки источника и цели для javac. Следовательно, этот фрагмент pom.xml:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
        <source>1.6</source>
        <target>1.5</target>
    </configuration>
</plugin>

который работает как ожидается в рамках Eclipse 3.7 с поддержкой Maven. К сожалению, запуск Maven прямо из командной строки дает мне

javac: source release 1.6 requires target release 1.6

который является тем же самым, что и сгенерированный javac -source 1.6 -target 1.5. Чтобы уточнить, это официальный OpenJDK 6 для Ubuntu

[email protected]:~$ javac -version
javac 1.6.0_20
[email protected]:~$ javac -source 1.6 -target 1.5
javac: source release 1.6 requires target release 1.6
[email protected]:~$

Официальный Oracle J7K JDK для Windows демонстрирует то же поведение.

Примечание. Я не хочу создавать библиотеки Java 5 или что-то еще. Просто, что активный javac генерирует совместимый с Java 5 байт-код.

Как мне получить то, что я хочу, сохраняя при этом совместимость с плагином Eclipse Maven?

(EDIT: В дополнение к @Override я также хочу скомпилировать файлы JAX-WS в Java 6 при использовании, но все еще сгенерированный Java-байтовый код - я могу добавить библиотеки JAX-WS намеренно в Интернете контейнер при развертывании на установку Java 5)


EDIT: Оказывается, maven-compiler-plugin может быть сказано использовать другой компилятор, и компилятор Eclipse может сделать это:

        <plugin>
            <!-- Using the eclipse compiler allows for different source and target, 
                which is a good thing (outweighing that this is a rarely used combination, 
                and most people use javac) This should also allow us to run maven builds 
                on a JRE and not a JDK. -->

            <!-- Note that initial experiments with an earlier version of maven-compiler-plugin 
                showed that the eclipse compiler bundled with that gave incorrect lines in 
                the debug information. By using a newer version of the plexus-compiler-eclipse 
                plugin this is hopefully less of an issue. If not we must also bundle a newer 
                version of the eclipse compiler itself. -->

            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.0</version>
            <configuration>
                <source>1.6</source>
                <target>1.5</target>
                <debug>true</debug>
                <optimize>false</optimize>
                <fork>true</fork>
                <compilerId>eclipse</compilerId>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>org.codehaus.plexus</groupId>
                    <artifactId>plexus-compiler-eclipse</artifactId>
                    <version>2.1</version>
                </dependency>
            </dependencies>
        </plugin>

который компилирует класс в байт-код Java 1.5 без жалоб. Это также поддерживается "из коробки" для m2e для Eclipse Java EE 4.2.2.

EDIT: Я нашел, что из всех вещей инструмент javadoc не любит вывод компилятора Eclipse.

EDIT 2015-06-28: Недавно я сделал быстрый тест, и последний ecj (соответствующий Eclipse 4.4) отлично справился с javadoc.

4b9b3361

Ответ 1

Ограничение в javac. Решение состоит в том, чтобы сказать maven использовать другой компилятор. Подробнее см. Вопрос.

Ответ 2

Кажется, что если вы хотите выполнить кросс-компиляцию, вам нужно предоставить несколько дополнительных аргументов -bootclasspath и -extdirs, хотя я считаю, что вам нужно только первое. Для использования Javac и примера можно найти здесь с объяснением дополнительных опций здесь (раздел "Опции перекрестной компиляции" ).

Затем вам нужно будет настроить эти параметры для своего maven-компилятора-плагина. Насколько я понимаю, вам нужно установить плагин в fork, чтобы он использовал аргументы компилятора, а не встроенный компилятор. Вы можете найти список всех опций здесь

 <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.5</target>
                    <fork>true</fork>
                    <compilerArguments>
                        <bootclasspath>${1.5.0jdk}\lib\rt.jar</bootclasspath>
                   </compilerArguments>
               </configuration>
           </plugin>
        ....
       </plugins>
   </build>

Ответ 3

Я считаю, что вам нужно также установить -bootclasspath, чтобы javac скомпилировался против классов начальной загрузки JDK 1.5.

Try:

javac -source 1.6 -target 1.5 -bootclasspath /path/to/jdk1.5/lib/rt.jar -extdirs "" Foo.java

UPDATE:

Попробуйте удалить параметр -source, но сохраните параметр -target.

Я только что протестировал его:

# no source, only target => COMPILES to 1.5
$ javac -target 1.5 Foo.java
$ javap -v  Foo | grep version
  minor version: 0
  major version: 49

# no source, no target => COMPILES to 1.6
$ javac Foo.java
$ javap -v  Foo | grep version
  minor version: 0
  major version: 50

# both source and target => ERROR
$ javac -source 1.6 -target 1.5 Foo.java
javac: source release 1.6 requires target release 1.6

$ javac -version
javac 1.6.0_21

Ответ 4

Какие функции языка Java 6 вы используете, которых нет в Java 5? Насколько я могу судить, единственной "особенностью", которая была добавлена ​​в язык, является использование аннотации @Override в interface s. В противном случае Java 6 и Java 5 совместимы с исходным кодом. Что происходит, когда вы используете:

<source>1.5</source>
<target>1.5</target>

в файле сборки Maven?

Ответ 5

Таким образом, реальный вопрос заключается в использовании @Override в исходных файлах, которые необходимо скомпилировать в файлах классов Java 1.5.

javac -source 1.5 -target 1.5 aFileWithOverride.java

сделает именно это. В jdk 7 это приведет к предупреждению

[options] bootstrap class path not set in conjunction with -source 1.5

которая отсутствует в jdk 6.

Чтобы избавиться от этого предупреждения, можно создать специальный jar класса загрузки, добавив пакет java 6 (или выше) java.lang.annotation в java 5 rt.jar.

Ответ 6

У меня была такая же ошибка, когда я обновил свою IntelliJ IDE, она была исправлена ​​с заменой 1.5 на 1.6, как показано ниже.

       <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>