views:

44

answers:

5

I have a scenario where I have code written against version 1 of a library but I want to ship version 2 of the library instead. The code has shipped and is therefore not changeable. I'm concerned that it might try to access classes or members of the library that existed in v1 but have been removed in v2.

I figured it would be possible to write a tool to do a simple check to see if the code will link against the newer version of the library. I appreciate that the code may still be very broken even if the code links. I am thinking about this from the other side - if the code won't link then I can be sure there is a problem.

As far as I can see, I need to run through the bytecode checking for references, method calls and field accesses to library classes then use reflection to check whether the class/member exists.

I have three-fold question:

(1) Does such a tool exist already?

(2) I have a niggling feeling it is much more complicated that I imagine and that I have missed something major - is that the case?

(3) Do you know of a handy library that would allow me to inspect the bytecode such that I can find the method calls, references etc.?

Thanks!

+2  A: 

Changing the library in your IDE will result in all possible compile-time errors.

You don't need anything else, unless your code uses another library, which in turn uses the updated library.

Bozho
+1  A: 

Be especially wary of Spring configuration files. Class names are configured as text and don't show up as missing until runtime.

extraneon
A: 

If you have access to the source code, you could just compile source against the new library. If it doesn't compile, you have definitely a problem. If it compiles you may still have a problem if the program uses reflection, some kind of IoC stuff like Spring etc.

If you have unit tests, then you may have a better change catch any linking errors.

If you have only have a .class file of the program, then I don't know any tools that would help besides decomplining class file to source and compiling source again against the new library, but that doesn't sound too healthy.

Juha Syrjälä
+2  A: 

I think that Clirr - a binary compatibility checker - can help here:

Clirr is a tool that checks Java libraries for binary and source compatibility with older releases. Basically you give it two sets of jar files and Clirr dumps out a list of changes in the public api. The Clirr Ant task can be configured to break the build if it detects incompatible api changes. In a continuous integration process Clirr can automatically prevent accidental introduction of binary or source compatibility problems.

Pascal Thivent
Thanks - looks interesting.
monorailkitty
@monorailkitty you could upvote an answer, in addition to accepting it ;)
Bozho
A: 

The checks you mentioned are done by the JVM/Java class loader, see e.g. Linking of Classes and Interfaces.

So "attempting to link" can be simply achieved by trying to run the application. Of course you could hoist the checks to run them yourself on your collection of .class/.jar files. I guess a bunch of 3rd party byte code manipulators like BCEL will also do similar checks for you.

I notice that you mention reflection in the tags. If you load classes/invoke methods through reflection, there's no way to analyse this in general.

Good luck!

ShiDoiSi