检测旧Java库的使用

时间:2010-06-09 05:29:43

标签: java bytecode

使用带有-source 1.4和-target 1.4的1.5编译器进行编译时是否有第三方库来检测Java 1.5库的使用?

我可以在bootclasspath中使用1.4 rt.jar但是我希望有更好的方法。例如,如果使用更新的库,则用于编译/构建失败。

2 个答案:

答案 0 :(得分:3)

奇怪的名字Animal Sniffer是专为此任务而设计的。请参阅Kohsuke的博客文章Compiling with JDK6 and running on JDK5

它打包为Maven插件(此answer中提供了一个使用示例),但也可以通过编程方式调用:

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

答案 1 :(得分:2)

我不清楚你想要达到的目标。所以我猜你正在努力确保你的代码是100%兼容Java 1.4,同时也尝试并利用Java 1.5字节码编译器中的(假设的)改进。简单的方法是做两个构建:

  1. 使用Java 1.4构建以检查您的代码是否与Java 1.4库兼容。

  2. 使用带有-source 1.4和-target 1.4的Java 1.5再次构建。

  3. 问题在于,它只检测静态API不匹配,并且会错过您反复使用API​​或不兼容性在类行为而不是签名中的问题。

    另外需要注意的是,在新平台上编译Java以在旧平台上运行不太可能有帮助......如果这是您想要实现的目标。

    • Java字节码编译器没有做太多优化,因此较新的版本不会产生明显更快的字节码。

    • 从一个版本到下一个版本,JIT编译器可能会有很大的改进,但JIT编译器是执行平台的一部分。

    • 可能发生性能改进的另一个地方是Java类库的实现,这些也是执行平台的一部分。

    简而言之,如果您使用JDK 1.5 javac编译器编译代码然后在Java 1.4平台上运行,那么您将无法从Java 1.5中获得性能改进的好处。