2012-02-06 28 views
10

He intentado hacer que esto funcione por un tiempo, pero todavía no tengo suerte.Maven - Use JDK 7 para compilar para JVM 5

Quiero correr con JAVA_HOME apuntando a JDK7 pero quiero compilar un proyecto para la JVM 5. He leído a través documentation, he encontrado similar posts en SO, pero ninguno de ellos parece funcionar en mi configuración.

intentó por primera vez con el entorno rural a sólo target y source pero me da un error:

<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

Por lo que he entendido que la clase se actualizó en JDK 7 y el método extra que está lanzando el error fue Recien agregado. Necesito usar el tiempo de ejecución de JDK 5 que tiene la implementación anterior y todo debería funcionar bien. Así que hacer esto:

<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> 

tengo JAVA5_HOME ajustado correctamente en mi sistema, puedo ver que la carga de las clases correctas en el registro, pero golpear a otro error:

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

que es justo , ya que no incluí jce.jar (clases de criptografía) en el bootclasspath. Sin embargo, hay algo que me desconcierta. Aunque el bootclasspath contiene solo el tiempo de ejecución de Java 5, tengo muchas bibliotecas de JRE7 en el classpath. No están especificados en ninguna parte.

[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, ...]

Si trato y añadir jce.jar (de JRE5), regrese al primer error:

<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()

También veo ningún rastro de rt.jar está cargando, pero no obtienes un error de java.lang no encontrado, por lo que hay algunas clases cargadas en el classpath.

Lo arreglaré temporalmente haciendo un script por lotes que sobrescriba JAVA_HOME antes de compilarlo y lo vuelva a configurar posteriormente, pero realmente quiero que se haga de la manera correcta. Esto no parece un caso de uso tan extremo. :)

¿Qué estoy haciendo mal aquí?

Respuesta

1

Puede utilizar la opción de configuración bootclasspath en el experto compilador-plugin si es necesario:

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

Puede leer mas sobre esto here. Ver la nota debajo del ejemplo.

+1

Eche un vistazo a mis ejemplos, lo estoy usando de esa manera, pero no funciona si especifico varios contenedores. ¿Me estoy perdiendo de algo? –

3

La versión anterior de Java no es especialmente buena para soportar versiones anteriores de Java. Para Java 7 parece ser mucho mejor.

Aquí hay un programa que debe compilar en cualquier versión.

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 

Si necesita compilar para una versión anterior de Java, es necesario proporcionar una bootclasspath, idealmente para la versión de Java que desea compilar para. Java 7 parece ser capaz de soportar todo el camino de regreso a Java 1.2

+0

Incluso si uso '' y ''? Entendí por los documentos que esto es lo que se supone que deben hacer: producir código compatible con otras JVM. –

+3

Usted * puede * compilar el código para JVM anteriores bajo el último JDK. Producirá el código de bytes apropiado y lanzará errores si intenta utilizar construcciones de lenguaje no disponibles en la JVM de destino. Solo necesita tener mucha precaución ya que javac no le impedirá usar nuevos métodos/clases que no están en el antiguo sistema estándar de JVM ... –

+0

@AlexCiminian Está utilizando la opción correcta, el problema es si su 'javac 'admite esta opción. Java 5.0 y 6 fueron muy pobres en la compilación de versiones anteriores, sin embargo, Java 7 parece cubrir Java 1.2. Si utiliza una versión anterior de 'rt.jar', debería evitar el uso de métodos/funcionalidad que no existe en su versión objetivo –

1

El problema es con la compatibilidad con versiones anteriores de Java 7.

Hay muy pocas clases que no conservan la compatibilidad hacia atrás debido a problemas imposibles de resolver de naturaleza diferente, DataSource pasa a ser uno de ellos.

Por lo tanto, adaptas tu clase para respetar las nuevas firmas (incluso en modo de compatibilidad con versiones anteriores), o te verás obligado a utilizar una versión diferente de la máquina virtual.

Usted puede leer más información aquí: http://www.oracle.com/technetwork/java/javase/compatibility-417013.html

1

para usar varios frascos en las opciones del compilador Maven, utilizar la cadena $ {} path.separator entre los tarros:

<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

Si miras mi ejemplo, esto es lo que estaba haciendo. –

5

Esta respuesta está dirigido al título de la pregunta, no a los problemas específicos de la pregunta en detalle.

Terminé usando esta solución en mi proyecto, lo que me permite usar la ruta de acceso de arranque personalizada selectivamente, activando un perfil de experto. Recomiendo usar un perfil para esto, porque de lo contrario hace que la compilación falle para cualquiera que no tenga la variable de entorno establecida (muy mala, especialmente para un proyecto de código abierto). Solo activo este perfil en mi IDE para la acción "Limpiar & 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> 
Cuestiones relacionadas