2015-01-09 2 views
2

Я настроил непрерывной интеграции инструмент (Travis CI) для запуска на каждой фиксации я делаю, он строит свой проект Java 6 на следующих JDK-х:Имеет ли значение, если артефакт Java 6 скомпилирован с Java 6, 7 или 8?

  • Oracle JDK 8
  • Oracle JDK 7
  • Open JDK 7
  • Open JDK 6

Теперь Travis CI нет (пока) изначально поддерживает задачу, которая загружает созданный артефакт после выполнения всех задач, которые были закончены, так что я с помощью его к этому.

Мой вопрос заключается в том, что обходной путь попытается загрузить в репозиторий моментального снимка Sonatype артефакт, который был создан как , последний.

Это означает, что один раз он будет загрузить снимок, который был скомпилирован с помощью Open JDK 6, в другой раз с помощью Open JDK 7, и т.д., и т.д.

ли этот вопрос? Может ли клиент Java 6 использовать код Java 6, который компилируется с помощью Java 6+ JDK? Мы уже знаем, что код (по-видимому) делает то, что он должен делать, поскольку он скомпилирован и тесты прошли в этот момент.

Предполагается, что код Java 6 можно запускать на любой совместимой с Java 6 JRE и на Android.

+1

У вас не должно быть проблем с кодом Java 6, скомпилированным под JDK 8 (например), но вы могли бы повеселиться, пытаясь скомпилировать JDK 7 или 8 код в JDK6. Например, операторы switch работают отлично в 7+, но будут бросать ошибки компиляции в 6. – Dave

+0

@Dave Это все код Java 6, который я компилирую здесь, в любом из этих JDK. Я не пытаюсь скомпилировать (скажем) код Java 8 для Java 6. – skiwi

+0

Тогда у вас не должно быть проблем. Но однажды вам будут предъявлены требования для записи в JDK7, в конечном итоге используйте функции, не поддерживаемые в 6, и потратьте полдня на то, чтобы узнать, почему Travis не будет компилироваться для вас. :-) – Dave

ответ

5

No. - но вы должны указать -target

Когда Java компилирует классы, компилирует его для цели Java JRE. Для Другой крупный, см javac option for javac 1.7for Java8 here)

-target version 
    Generate class files that target a specified version of the VM. 
    Class files will run on the specified target and on later versions, 
    but not on earlier versions of the VM. 
    Valid targets are 1.1, 1.2, 1.3, 1.4, 1.5 (also 5), 1.6 (also 6), and 1.7 (also 7). 

The default for -target depends on the value of -source: 

    If -source is not specified, the value of -target is 1.7 
    If -source is 1.2, the value of -target is 1.4 
    If -source is 1.3, the value of -target is 1.4 
    If -source is 1.5, the value of -target is 1.7 
    If -source is 1.6, the value of -target is 1.7 
    For all other values of -source, the value of -target is the value of -source. 

Таким образом, код скомпилирован с Java8 JAVAC с -target 1.7, будет работоспособной на Java7 JRE только если код не использует функции, доступные в Java8 или новее.

Итак, в вашем случае код, скомпилированный с вашим Java8 JDK, если у него нет аргумента -target для команды javac, не будет даже загружаться на Java6. Ошибка будет: UnsupportedClassVersionError

2

Если вы успешно создали свой код на Java 6 и Java 8 (определяя целевую версию), вы можете передать свой код другому человеку и только им нужно иметь Java 6+ (также устанавливая целевую версию), и он будет работайте на любой Java 6 или выше.

Для этого вам необходимо установить -target 1.6 -source 1.6 или указать версию в maven-compiler-plugin. (Я настоятельно рекомендую вам использовать инструмент сборки)

В мавена вы установили бы

<project> 
    [...] 
    <build> 
    [...] 
    <plugins> 
     <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-compiler-plugin</artifactId> 
     <version>3.2</version> 
     <configuration> 
      <source>1.6</source> 
      <target>1.6</target> 
     </configuration> 
     </plugin> 
    </plugins> 
    [...] 
    </build> 
    [...] 
</project> 

И тот, кто использует свой билд будет создавать JAR с байт-код исполняемую на Java 6+


Когда вы компилируете байт-код для Java 6 в Java 8, его будет хорошо использовать на Java 6+

Где вы обнаружили, проблема в том, что Java 8 имеет больше классов и методов в JDK по сравнению с Java 6 Это означает, что компилятор Java 8 с радостью компилирует Java 6, который использует класс, методы или поле, которые доступны в Java 8, но недоступны в Java 6.

Возможно, компилятор Java 8 может использовать Java 6 библиотеки при компиляции кода, но гораздо более простым решением является использование компилятора Java 6, или вы можете предположить, что этого не произойдет или у вас есть еще одно средство для обнаружения того, что код Java 6 использует только библиотеки, доступные для Java 6.

Возможно, у вас была такая же проблема с сторонними библиотеками.Вы можете компилировать версию версии сторонней библиотеки, которая работает в Java 8, но для Java 6 вам нужно использовать более старую версию библиотек (или, возможно, ее не существует)

Еще одна проблема, с которой вы столкнетесь, - это то, что Java 8 исправлены некоторые ошибки в компиляторе, которые позволяет Java 6. Эти исправления довольно экзотичны, и у вас должен быть написан нестандартный Java-код (который Java 6 разрешен из-за ошибок в компиляторе)

Javadoc по умолчанию будет жаловаться на нестандартный Javadoc и даже не сможет построить, когда Java 6 javadoc пройдет.

+0

К сожалению, я не могу заставить точно, какой Java-компилятор я буду использовать, все, что я знаю, это компилятор Java 6+. Есть ли гарантия, что каждый компилятор генерирует один и тот же байт-код или является единственной гарантией того, что он показывает одно и то же поведение? – skiwi

+0

@skiwi Если у вас есть код, который построен на Java 6 и 8, вы можете дать его пользователю Java 6+ для компиляции, и он может передать его другому пользователю Java 6+. –

+0

@ Vogel612 Да, я забыл, что некоторые люди не используют встроенные инструменты или знают, что вам нужно это установить. –

Смежные вопросы