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

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org

Reply via email to