开发者

Detect use of older Java libraries

Is there a third-party library to detect the use of a Java 1.5 library when compiling with a 1.5 compiler with -source 1.4 and -target 1.4?

I could use a 1.4 rt.jar in the bootclasspath however I hop开发者_Python百科e there is a better way. To be used, for example, to fail the compile/build if a newer library is used.


The curiously named Animal Sniffer is designed for this task. See Kohsuke's blog post Compiling with JDK6 and running on JDK5

It's packaged as a Maven Plugin (an example of usage is given in this answer), but can also be invoked programmatically:

 ~/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 = org.jvnet.animal_sniffer.SignatureChecker@2a65dbe8

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


It is not clear to me what you are trying to achieve. So I'm guessing that you are trying to ensure that your code is 100% Java 1.4 compatible, while also trying and make use of (hypothetical) improvements in the Java 1.5 bytecode compiler. The simple way is to do two builds:

  1. Build using Java 1.4 to check that your code is Java 1.4 library compatible.

  2. Build a second time using Java 1.5 with -source 1.4 and -target 1.4.

The catch is that this only detects static API mismatches, and will miss problems where you are using APIs reflectively or where the incompatibilities are in class behavior rather than signatures.

The other thing to note is that compiling Java on a new platform to run on an old platform is not likely to help ... if that is what you are trying to achieve.

  • The Java bytecode compilers don't do much optimization, and therefore a newer release won't produce significantly faster bytecode.

  • The JIT compilers are likely improve significantly from one release to the next, but the JIT compiler is part of the execution platform.

  • The other place where performance improvements could occur is in the implementation of the Java class libraries, and these are also part of the execution platform.

In short, if you compile code with the JDK 1.5 javac compiler and then run on a Java 1.4 platform, you won't get the benefit of performance improvements in Java 1.5.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜