2012-02-06 9 views
10

Я пытался заставить это работать некоторое время, но пока не повезло.Maven - использовать JDK 7 для компиляции для JVM 5

Я хочу работать с JAVA_HOME указывающих на JDK7, но я хочу, чтобы скомпилировать проект для виртуальной машины Java 5. Я прочитал documentation, я нашел similar posts на SO, но ни один из них не похож на работу в моей установке.

я впервые попробовал с установкой только target и source, но я получил ошибку:

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

[ClassName] is not abstract and does not override abstract method getParentLogger() in CommonDataSource

Насколько я понял, что класс был обновлен в JDK 7 и дополнительный метод, который бросает ошибку только что добавлен. Мне нужно использовать среду выполнения JDK 5, которая имеет старую реализацию, и все должно работать нормально. Так что я делаю это:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-compiler-plugin</artifactId> 
    <configuration> 
     <verbose>true</verbose> 
     <source>1.5</source> 
     <target>1.5</target> 
     <compilerArguments> 
      <bootclasspath>${env.JAVA5_HOME}/jre/lib/rt.jar</bootclasspath> 
     </compilerArguments> 
    </configuration> 
</plugin> 

меня JAVA5_HOME правильно установлено на моей системе, я могу видеть его загрузку правильных классов в журнале, но я ударил другую ошибку:

[loading ZipFileIndexFileObject[c:\Program Files\Java\jdk1.5.0_22\jre\lib\rt.jar(*.class)]]
...
...
[ClassName] error: package javax.crypto does not exist

Который является достаточно справедливым , так как я не включил jce.jar (классы криптографии) в bootclasspath. Тем не менее, есть что-то, что меня озадачивает. Несмотря на то, что bootclasspath содержит только среду выполнения Java 5, у меня есть много библиотек из JRE7 в пути к классам. Они нигде не указаны.

[search path for class files: c:\Program Files (x86)\Java\jdk1.5.0_22\jre\lib\rt.jar,c:\Program Files\Java\jdk1.7.0_02\jre\lib\ext\dnsns.jar,c:\Program Files\Java\jdk1.7.0_02\jre\lib\ext\localedata.jar,c:\Program Files\Java\jdk1.7.0_02\jre\lib\ext\sunec.jar,c:\Program Files\Java\jdk1.7.0_02\jre\lib\ext\sunjce_provider.jar,c:\Program Files\Java\jdk1.7.0_02\jre\lib\ext\sunmscapi.jar,c:\Program Files\Java\jdk1.7.0_02\jre\lib\ext\zipfs.jar, ...]

Если я пытаюсь добавить jce.jar (от JRE5), я вернусь к первой ошибке:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-compiler-plugin</artifactId> 
    <configuration> 
     <verbose>true</verbose> 
     <source>1.5</source> 
     <target>1.5</target> 
     <compilerArguments> 
      <bootclasspath>${env.JAVA5_HOME}/jre/lib/rt.jar${path.separator}${env.JAVA5_HOME}/jre/lib/jce.jar</bootclasspath> 
     </compilerArguments> 
    </configuration> 
</plugin> 

The type [ClassName] must implement the inherited abstract method CommonDataSource.getParentLogger()

Я также вижу никаких следов rt.jar не загружается, но я не получите java.lang не найдена ошибка, поэтому есть некоторые классы, которые загружаются в путь к классам.

Я исправлю это временно, выполнив пакетный скрипт, который перезаписывает JAVA_HOME перед его созданием и устанавливает его обратно, но я действительно хочу, чтобы это было сделано правильно. Это не похоже на такой крайний случай использования. :)

Что я здесь делаю неправильно?

ответ

1

Вы можете использовать опцию конфигурации на загрузочного пути к классам Maven-компилятора-плагин, если это необходимо:

<compilerArguments> 
    <bootclasspath>xxxxxxxxx</bootclasspath> 
</compilerArguments> 

Вы можете прочитать больше об этом here. См. Примечание в примере.

+1

Проверьте мои примеры, я использую его таким образом, но он не работает, если я укажу несколько банок. Я что-то упускаю? –

3

Предыдущая версия Java не особенно хороша для поддержки предыдущих версий Java. Для Java 7 это выглядит намного лучше.

Вот программа, которая должна компилироваться под любую версию.

public class Main { 
    public static void main(String[] args) { 
     System.out.println("Hello World!"); 
    } 
} 

$ javac -target 1.7 -source 1.7 Main.java 
$ javac -target 1.6 -source 1.6 Main.java 
warning: [options] bootstrap class path not set in conjunction with -source 1.6 
1 warning 
$ javac -Xbootclasspath:/usr/java/jdk1.6.0_29/jre/lib/rt.jar -target 1.6 -source 1.6 Main.java 
$ javac -Xbootclasspath:/usr/java/jdk1.5.0_22/jre/lib/rt.jar -target 1.5 -source 1.5 Main.java 
$ javac -Xbootclasspath:/usr/java/jdk1.4.0_30/jre/lib/rt.jar -target 1.4 -source 1.4 Main.java 
$ javac -Xbootclasspath:/usr/java/jdk1.3.1_29/jre/lib/rt.jar -target 1.3 -source 1.3 Main.java 
$ javac -Xbootclasspath:/usr/java/jdk1.2.2_017/jre/lib/rt.jar -target 1.2 -source 1.2 Main.java 
$ javac -Xbootclasspath:/usr/java/jdk1.1.8_16/jre/lib/rt.jar -target 1.1 -source 1.2 Main.java 
$ javac -Xbootclasspath:/usr/java/jdk1.1.8_16/jre/lib/rt.jar -target 1.1 -source 1.1 Main.java 
javac: invalid source release: 1.1 
Usage: javac 
use -help for a list of possible options 
$ javac -Xbootclasspath:/usr/java/jdk1.1.8_16/jre/lib/rt.jar -target 1.0 -source 1.0 Main.java 
javac: invalid target release: 1.0 
Usage: javac 
use -help for a list of possible options 

Если вам нужно собрать для предыдущей версии Java, необходимо обеспечить загрузочный путь к классам, в идеале для версии Java вы хотите скомпилировать для. Java 7, похоже, может полностью поддерживать Java 1.2

+0

Даже если я использую '' и ''? Я понял из документов, что это то, что они должны делать - создать код, совместимый с другими JVM. –

+3

Вы * можете * скомпилировать код для более ранних JVM под последним JDK. Он будет генерировать соответствующий байтовый код и выдавать ошибки, если вы попытаетесь использовать языковые конструкции, недоступные в целевой JVM. Вам просто нужно проявлять особую осторожность, поскольку javac не помешает вам использовать новые методы/классы, которые не находятся в старой стандартной системе JVM ... –

+0

@AlexCiminian. Вы используете правильный вариант, проблема в том, является ли ваш 'javac 'поддерживает эту опцию. Java 5.0 и 6 были очень плохими при компиляции для предыдущих версий, однако Java 7, похоже, вернется к Java 1.2. Если вы используете более раннюю версию 'rt.jar', это должно помешать вам использовать методы/функции, которых нет в вашей целевой версии. –

1

Проблема заключается в совместимости с Java 7 назад.

Существует очень мало классов, которые не сохраняют обратную совместимость из-за невозможности решения проблем различной природы, DataSource является одним из них.

Таким образом, вы адаптируете свой класс к соблюдению новых подписей (даже в режиме обратной совместимости), или вы будете вынуждены использовать другую версию виртуальной машины.

Вы можете прочитать более подробную информацию здесь: http://www.oracle.com/technetwork/java/javase/compatibility-417013.html

1

Чтобы использовать несколько Баночки в параметрах компилятора Maven, используйте $ {path.separator} строку между баночек:

<compilerArguments> 
    <bootclasspath>${env.JAVA5_HOME}/jre/lib/rt.jar${path.separator}${env.JAVA5_HOME}/jre/lib/jce.jar${path.separator}${env.JAVA5_HOME}/jre/lib/jsse.jar</bootclasspath> 
</compilerArguments> 
+1

Если вы посмотрите на мой пример, это то, что я делаю. –

5

Этот ответ направлена ​​на название вопроса, а не на конкретные проблемы вопроса в деталях.

В результате я решил использовать это решение в своем проекте, что позволяет выборочно использовать выборочный путь класса bootstrap, активируя профиль maven. Я настоятельно рекомендую использовать для этого профиль, потому что в противном случае это приведет к сбою сборки для любого, у кого нет установленной переменной окружения (очень плохо, особенно для проекта с открытым исходным кодом). Я активирую этот профиль только в своей IDE для действия «Clean & Build».

<profile> 
     <id>compileWithJava5</id> 
     <!-- 
      NOTE 
      Make sure to set the environment variable JAVA5_HOME 
      to your JDK 1.5 HOME when using this profile. 
     --> 
     <properties> 
      <java.5.home>${env.JAVA5_HOME}</java.5.home> 
      <java.5.libs>${java.5.home}/jre/lib</java.5.libs> 
      <java.5.bootclasspath>${java.5.libs}/rt.jar${path.separator}${java.5.libs}/jce.jar</java.5.bootclasspath> 
     </properties> 
     <build> 
      <plugins> 
       <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-compiler-plugin</artifactId> 
        <configuration> 
         <source>1.5</source> 
         <target>1.5</target> 
         <compilerArguments> 
          <bootclasspath>${java.5.bootclasspath}</bootclasspath> 
         </compilerArguments> 
        </configuration> 
       </plugin> 
      </plugins> 
     </build> 
    </profile>