proyecto - javac cmd
Opciones de origen y destino de javac (4)
He visto las opciones de compilación, como se explica en ¿Qué distribuciones de JDK pueden ejecutar `javac -source 1.6 -target 1.5`? . Entiendo las opciones individuales de origen y destino. No entiendo por qué la versión de origen es más alta que la versión de destino. Compilar el código para objetivos más antiguos tiene sentido. Pero en ese caso, ¿por qué no simplemente usamos -source del objetivo más antiguo en el que queremos poder ejecutar?
JDK1.8 ya no admitirá -source y -target menos de 1.6
"c:/Program Files/Java/jdk1.8.0_121/bin/javac.exe" -source 1.3 HelloWorld.java
warning: [options] bootstrap class path not set in conjunction with -source 1.3
warning: [options] source value 1.3 is obsolete and will be removed in a future release
warning: [options] target value 1.4 is obsolete and will be removed in a future release
warning: [options] To suppress warnings about obsolete options, use -Xlint:-options.
4 warnings
Java es compatible con versiones anteriores. Utiliza la opción -source para especificar la versión java utilizada para la compilación y usa la opción -target para especificar la versión java más baja para admitir. p.ej. Si especifico un objetivo de 1.4, mi programa no podrá ejecutarse en java 1.3 o inferior. Consulte la siguiente documentation javac para obtener más información. especialmente la sección de opciones de compilación cruzada
Peter Tseng menciona muchos puntos clave para recordar durante la compilación. De hecho, incluso me enfrenté a un problema similar en algún momento y quiero compartir las causas de muchos problemas.
Tenía un código fuente que tenía que compilar y hacerlo compatible (-source & -target) Java ''1.8'' . El código en sí tenía
- Gran cantidad de símbolos de marcas comerciales, por lo que terminé en caracteres no reconocidos (tuve que modificar la configuración de codificación de la IntelliJ Idea)
- Muchos cambios en el paquete
java.sql.*
- Uso del lote de bibliotecas de terceros. Ahórreme el horror de explicar la dificultad de depurar allí y bla, bla, bla.
Después de ciertos cambios, terminé con un código que tenía la misma cantidad de casos de prueba de JUnit para ejecutar. Finalmente me encontré con un java.lang.VerifyError
. Me sorprendí cuando comprendí que tal error ocurre cuando compilo y ejecuto el código en las diferentes bibliotecas / entorno (lo cual no fue el caso).
Lo que casi me perdí fue que, para honrar el hecho de que las pruebas tenían que ejecutarse en un entorno aislado, Junit y sus casos de prueba se ejecutaban en una máquina virtual separada.
<target name="runJunit">
<junit printonsummary="on"
haltonfailure="off"
fork="true"
forkmode="once">
<formatter />
<batchtest />
<classpath />
</junit>
</target>
Esto obviamente se extenderá como un proceso separado y actuará como una aplicación independiente en ejecución. Aunque el IDE abarca ambos procesos de forma síncrona, las JVM están bastante aisladas.
Después de Java 1.7, Oracle ha introducido una verificación más estricta y ha cambiado un poco el formato de la clase, para que contenga un mapa de pila, que se utiliza para verificar que el código es correcto . La excepción que había visto era porque algún método no tiene un mapa de pila válido. Finalmente traté de incluir muchas opciones de JVM para modificar la configuración, pero fue en vano.
<jvmarg value="bootclasspath:{env.JAVA_HOME}/jre/bin/rt.jar" prefix="-X"/>
nada funcionó. El único trabajo alrededor era incluir
<jvmarg value=":UseSplitVerifier" prefix="-XX"/>
En Java 1.7 para permitir solo la verificación del código de byte nominal. Ya que esto se quitó en Java 1.8, la única opción era usar
<jvmarg value="-noverify"/>
- fuente: la versión que su código fuente requiere para compilar.
- target: la versión más antigua de JRE que quieres soportar.
Asegúrese de configurar también bootclasspath para asegurarse de que su programa funcione en máquinas virtuales más antiguas.
De la documentation javac
:
Ejemplo de compilación cruzada
El siguiente ejemplo utiliza javac para compilar el código que se ejecutará en una máquina virtual 1.6.
C/:>javac -source 1.6 -target 1.6 -bootclasspath C:/jdk1.6.0/lib/rt.jar -extdirs "" OldCode.java
La opción
-source 1.6
especifica que la versión 1.6 (o 6) del lenguaje de programación Java se use para compilarOldCode.java
. La opción-target 1.6
opción asegura que los archivos de clase generados sean compatibles con 1.6 VM. Tenga en cuenta que en la mayoría de los casos, el valor de la opción-target
es el valor de la opción-source
; en este ejemplo, puede omitir la opción-target
.Debe especificar la opción
-bootclasspath
para especificar la versión correcta de las clases dert.jar
(la bibliotecart.jar
). Si no, el compilador genera la siguiente advertencia:
C:/>javac -source 1.6 OldCode.java warning: [options] bootstrap class path not set in conjunction with -source 1.6
Si no especifica la versión correcta de las clases de arranque, el compilador usará las reglas del idioma antiguo (en este ejemplo, usará la versión 1.6 del lenguaje de programación Java) combinada con las nuevas clases de arranque, lo que puede resultar en archivos de clase que No trabaje en la plataforma anterior (en este caso, Java SE 6) porque puede incluirse la referencia a métodos no existentes.