commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dan Fabulich <...@fabulich.com>
Subject Re: [dbutils] binary compatibility
Date Tue, 03 Nov 2009 20:03:16 GMT
Jörg Schaible wrote:

> Is it binary backward compatible?

I think it is, but I'm not 100% certain; it's confusing.

I ran clirr on dbutils-1.2 and my locally built 1.3-SNAPSHOT; it found one 
clear compatibility error which I just fixed (DBUTILS-61).  This is what 
it says as of r832529:

INFO: 7011: org.apache.commons.dbutils.ProxyFactory: Method 'public java.lang.Object newProxyInstance(java.lang.Class,
java.lang.reflect.InvocationHandler)' has been added
INFO: 7011: org.apache.commons.dbutils.ResultSetIterator: Method 'public java.lang.Iterable
iterable(java.sql.ResultSet)' has been added
ERROR: 7006: org.apache.commons.dbutils.ResultSetIterator: Return type of method 'public java.lang.Object
next()' has been changed to java.lang.Object[]
INFO: 7011: org.apache.commons.dbutils.ResultSetIterator: Method 'public java.lang.Object
next()' has been added
INFO: 8000: org.apache.commons.dbutils.handlers.AbstractKeyedHandler: Class org.apache.commons.dbutils.handlers.AbstractKeyedHandler
added
ERROR: 7006: org.apache.commons.dbutils.handlers.AbstractListHandler: Return type of method
'public java.lang.Object handle(java.sql.ResultSet)' has been changed to java.util.List
INFO: 7011: org.apache.commons.dbutils.handlers.AbstractListHandler: Method 'public java.lang.Object
handle(java.sql.ResultSet)' has been added
ERROR: 7006: org.apache.commons.dbutils.handlers.ArrayHandler: Return type of method 'public
java.lang.Object handle(java.sql.ResultSet)' has been changed to java.lang.Object[]
INFO: 7011: org.apache.commons.dbutils.handlers.ArrayHandler: Method 'public java.lang.Object
handle(java.sql.ResultSet)' has been added
ERROR: 7006: org.apache.commons.dbutils.handlers.ArrayListHandler: Return type of method 'protected
java.lang.Object handleRow(java.sql.ResultSet)' has been changed to java.lang.Object[]
INFO: 7011: org.apache.commons.dbutils.handlers.ArrayListHandler: Method 'protected java.lang.Object
handleRow(java.sql.ResultSet)' has been added
ERROR: 7006: org.apache.commons.dbutils.handlers.BeanListHandler: Return type of method 'public
java.lang.Object handle(java.sql.ResultSet)' has been changed to java.util.List
INFO: 7011: org.apache.commons.dbutils.handlers.BeanListHandler: Method 'public java.lang.Object
handle(java.sql.ResultSet)' has been added
INFO: 5000: org.apache.commons.dbutils.handlers.KeyedHandler: Added org.apache.commons.dbutils.handlers.AbstractKeyedHandler
to the list of superclasses
INFO: 7000: org.apache.commons.dbutils.handlers.KeyedHandler: Method 'protected java.util.Map
createMap()' is now implemented in superclass org.apache.commons.dbutils.handlers.AbstractKeyedHandler
ERROR: 7006: org.apache.commons.dbutils.handlers.KeyedHandler: Return type of method 'protected
java.lang.Object createRow(java.sql.ResultSet)' has been changed to java.util.Map
INFO: 7011: org.apache.commons.dbutils.handlers.KeyedHandler: Method 'protected java.lang.Object
createRow(java.sql.ResultSet)' has been added
INFO: 7003: org.apache.commons.dbutils.handlers.KeyedHandler: Method 'public java.lang.Object
handle(java.sql.ResultSet)' has been removed, but an inherited definition exists.
ERROR: 7006: org.apache.commons.dbutils.handlers.MapHandler: Return type of method 'public
java.lang.Object handle(java.sql.ResultSet)' has been changed to java.util.Map
INFO: 7011: org.apache.commons.dbutils.handlers.MapHandler: Method 'public java.lang.Object
handle(java.sql.ResultSet)' has been added
ERROR: 7006: org.apache.commons.dbutils.handlers.MapListHandler: Return type of method 'protected
java.lang.Object handleRow(java.sql.ResultSet)' has been changed to java.util.Map
INFO: 7011: org.apache.commons.dbutils.handlers.MapListHandler: Method 'protected java.lang.Object
handleRow(java.sql.ResultSet)' has been added

All of the errors are complaints about covariant return types. In each 
case, something that used to return an Object now returns a more specific 
type (e.g. List or Object[]).

But it's confusing, because Java handles covariant return types by 
generating replacement methods in the bytecode.  So there IS still a 
method that returns Object in the bytecode.

For example, according to Jad, BeanListHandler.class decompiles like this:

   public List handle(ResultSet rs) throws SQLException {
     return convert.toBeanList(rs, type);
   }

   public volatile Object handle(ResultSet resultset) throws SQLException {
     return handle(resultset);
   }

Strangely, Clirr is reporting this as an ERROR that the method has 
changed, followed by an INFO remark that a new method was added that just 
happens to be exactly like the old method!  (I guess the new signature 
isn't exactly the same, since it is marked "volatile" ...?)

I believe none of these errors are really errors.  I tested this by 
creating a subclass of KeyedHandler like this:

   public class MyKeyedHandler extends KeyedHandler {
     public boolean hit = false;
     @Override
     protected Object createRow(ResultSet rs) throws SQLException {
       hit = true;
       return super.createRow(rs);
     }
   }

I used that to create a jar called "backcompat.jar"

I then copied KeyedHandlerTest from 1.2 and changed it to refer to 
MyKeyedHandler.  I also added assertions that "hit" turned to true when it 
was invoked.  I ran the test against 1.2 and backcompat.jar and it passed; 
then I replaced the 1.2 jar with the 1.3 jar and it again passed, with no 
changes to backcompat.jar.

So it seems to me that all of these errors aren't really errors, but 
rather bugs in clirr.

-Dan


Mime
View raw message