2010-06-09 10 views
5

¿Existe una biblioteca de terceros que detecte el uso de una biblioteca Java 1.5 al compilar con un compilador 1.5 con -ource 1.4 y -target 1.4?Detectar el uso de bibliotecas Java más antiguas

Podría usar un 1.4 rt.jar en el bootclasspath, pero espero que haya una mejor manera. Para ser utilizado, por ejemplo, para fallar la compilación/compilación si se utiliza una biblioteca más nueva.

Respuesta

3

El curiosamente llamado Animal Sniffer está diseñado para esta tarea. Ver el blog de Kohsuke enviar Compiling with JDK6 and running on JDK5

Se envasa como un plugin de Maven (un ejemplo de uso se da en este answer), pero también puede ser invocado mediante programación:

~/code/scratch/sniff: curl http://maven.dyndns.org/2/org/jvnet/animal-sniffer/1.2/animal-sniffer-1.2.jar > animal-sniffer.jar 
~/code/scratch/sniff: curl http://repo1.maven.org/maven2/asm/asm-all/3.1/asm-all-3.1.jar > asm-all.jar 
~/code/scratch/sniff: curl http://maven.dyndns.org/2/org/jvnet/animal-sniffer/java1.5/1.0/java1.5-1.0.sig > java1.5-1.0.sig 

~/code/scratch/sniff: mkdir -p target/classes 
~/code/scratch/sniff: cd !$ 
cd target/classes 
~/code/scratch/sniff/target/classes: jar xf /Users/jason/usr/scala-2.8.0.RC2/lib/scala-library.jar 
~/code/scratch/sniff/target/classes: jar xf /Users/jason/usr/scala-2.8.0.RC2/lib/scala-compiler.jar 
~/code/scratch/sniff/target/classes: cd - 
/Users/jason/code/scratch/sniff 
~/code/scratch/sniff: scala -classpath animal-sniffer.jar:asm-all.jar 
Welcome to Scala version 2.8.0.RC2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_17). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> import org.jvnet.animal_sniffer._ 
import org.jvnet.animal_sniffer._ 

scala> import collection.JavaConversions._ 
import collection.JavaConversions._ 

scala> val ignored = collection.mutable.Set("scala/*", "ch/*", "jline/*", "org/apache/*") 
ignored: scala.collection.mutable.Set[java.lang.String] = Set(org/apache/*, jline/*, scala/*, ch/*) 

scala> val sc = new SignatureChecker(new java.io.FileInputStream("java1.5-1.0.sig"), ignored) 
sc: org.jvnet.animal_sniffer.SignatureChecker = [email protected] 

scala> sc.process(new java.io.File("target/classes")) 
Undefined reference: java/util/concurrent/locks/LockSupport.park(Ljava/lang/Object;)V in target/classes/scala/concurrent/forkjoin/ForkJoinPool$WaitQueueNode.class 
Undefined reference: sun/misc/Unsafe.putOrderedObject(Ljava/lang/Object;JLjava/lang/Object;)V in target/classes/scala/concurrent/forkjoin/ForkJoinWorkerThread.class 
Undefined reference: sun/misc/Unsafe.putOrderedInt(Ljava/lang/Object;JI)V in target/classes/scala/concurrent/forkjoin/ForkJoinWorkerThread.class 
Undefined reference: java/util/concurrent/atomic/AtomicReferenceFieldUpdater.lazySet(Ljava/lang/Object;Ljava/lang/Object;)V in target/classes/scala/concurrent/forkjoin/LinkedTransferQueue$QNode.class 
Undefined reference: java/util/concurrent/locks/LockSupport.park(Ljava/lang/Object;)V in target/classes/scala/concurrent/forkjoin/LinkedTransferQueue.class 
Undefined reference: java/util/concurrent/locks/LockSupport.parkNanos(Ljava/lang/Object;J)V in target/classes/scala/concurrent/forkjoin/LinkedTransferQueue.class 
2

No está claro para mí lo que está tratando de lograr. Así que supongo que está tratando de asegurarse de que su código sea 100% compatible con Java 1.4, mientras que también intenta y hace uso de las mejoras (hipotéticas) en el compilador de códigos de bytes de Java 1.5. La manera simple es hacer dos compilaciones:

  1. Compila con Java 1.4 para verificar que tu código sea compatible con la biblioteca Java 1.4.

  2. Compila una segunda vez usando Java 1.5 con -source 1.4 y -target 1.4.

El problema es que esto sólo se detecta desajustes API estáticas, y se perderá los problemas de las que se utilizan las API de forma reflexiva o cuando las incompatibilidades están en comportamiento de la clase en lugar de firmas.

La otra cosa a tener en cuenta es que compilar Java en una plataforma nueva para ejecutar en una plataforma anterior no es probable que ayude ... si eso es lo que está tratando de lograr.

  • Los compiladores de código de bytes de Java no hacen mucho optimización, y por lo tanto una nueva versión de código de bytes no producirán mucho más rápido.

  • Es probable que los compiladores JIT mejoren significativamente de una publicación a otra, pero el compilador JIT es parte de la plataforma de ejecución.

  • El otro lugar donde las mejoras de rendimiento podrían ocurrir es en la implementación de las bibliotecas de clases Java, y estas también son parte de la plataforma de ejecución.

En resumen, si se compila el código con el compilador JDK 1.5 javac y luego se ejecuta en una plataforma Java 1.4, no obtendrá el beneficio de mejoras en el rendimiento en Java 1.5.

Cuestiones relacionadas