poi-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Josh Micich <josh.mic...@gmail.com>
Subject Re: Problem due to making DocumentInputStream final in POI 3.5 beta
Date Thu, 12 Feb 2009 23:11:07 GMT
Hello Kumar,

Thanks for pointing out this incompatibility between the latest versions of
poi and mpxj.
I have posted a proposed patch to mpxj-developers@lists.sourceforge.net .
Jon Iles has already put it into CVS and replied here:


To get your application running you have three choices:
  - Get the latest mpxj code from cvs ( see
http://sourceforge.net/cvs/?group_id=70649 )
  - Wait for the next release of mpxj
  - Patch your local poi-3.5-beta4 to make DocumentInputStream non-final


The NoSuchMethodError you mention is totally independent DocumentInputStream
being final.
> java.lang.NoSuchMethodError:

In April 2008, POIFSFileSystem.getRoot() was changed to return DirectoryNode
instead of DirectoryEntry (
http://svn.apache.org/viewvc?view=rev&revision=646870 ).  This change is a
source compatible but binary incompatible change, and it's the origin of the
NoSuchMethodError you describe.  Change r646870 occurred between POI
versions 3.0.2 and 3.1.  So to observe the error in practice you would need
to run a version of MPXJ which was compiled against POI 3.0.2 or *earlier*
against POI 3.1 or later.  However, it seems very clear to me that MPXJ
version 3.0.0 was compiled against POI 3.2.

I just disassembled line 61 of net/sf/mpxj/mpp/MPPReader.class in version
(For reference, the mpxj.jar I used had an md5sum of
940f1186c0658c3c33dfd4eccd2bdb23 )

// line 61
  17  aload_3
  18  invokevirtual  Lorg/apache/poi/poifs/filesystem/DirectoryNode;
  21  astore  4

That line of code is clearly compiled against POI post r646870 .  I am
pretty sure that MPXJ version 3.0.0 cannot produce the NoSuchMethodError you
describe. Maybe you have a different version of MPXJ on your classpath.

Having said all that, binary incompatibility changes are a general problem.
There could be other changes (since POI 3.2) that cause similar linkage
errors.  These are not easy to preemptively detect.  It's straightforward to
confirm source compatibility (just compile the mpxj source against the
specific poi.jar).  However, this does not guarantee binary compatibility
(which is generally more restrictive) between (a previously compiled)
mpxj.jar and poi.jar.
When the JVM finds a violation of binary compatibility it throws a subclass
of LinkageError.  However, all possible checks are not applied in a single
sweep across a whole jar, class or even method.  In some cases (like this
one) only when the invoke instruction is executed for the first time is the
method linked.  A linkage error may lay dormant just because a certain piece
of code hasn't executed yet.

I don't know of any tool which verifies complete binary compatibility
between two pre-compiled jars.  Such a tool would be very handy.

Hope this helps,

  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message