Type not declared by trigger method
sannegrinovero Mar 10, 2011 8:30 PMHello, I'm attempting to use Byteman to have all implementors of the java.sql.DatabaseMetaData interface throw a new java.sql.SQLException everytime the getDatabaseMajorVersion() method is invoked.
context: some JDBC driver versions are broken and don't implement this method throwing a SQLException when invoked. Not only old weird drivers, but even some recent versions of Oracle and PostgreSQL drivers; Hibernate invokes this method only to log some information about the database it's connecting to, so not critically important, but currently fails to boot when this exception is thrown.
It could easily log a warning instead and just, but I need an automated test to make the fix future-re-factoring proof.
There are some subtle differences in which this code is handled according to the database being used; continuous integration runs all functional tests on all supported databases so I would like to have this fault injection to be enabled on all JDBC implementations. (example: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5642 - there are many more reports on other databases)
So my rule is:
RULE DatabaseMetaData fails getDatabaseMajorVersion()
INTERFACE ^java.sql.DatabaseMetaData
METHOD getDatabaseMajorVersion
IF TRUE
DO throw new java.sql.SQLException("Byteman injected fault");
ENDRULE
but this throws:
org.jboss.byteman.agent.Transformer : possible trigger for rule ConcurrentMergeErrorHandledTest in class org.h2.jdbc.JdbcDatabaseMetaData RuleTriggerMethodAdapter.injectTriggerPoint : inserting trigger into org.h2.jdbc.JdbcDatabaseMetaData.getDatabaseMajorVersion() int for rule ConcurrentMergeErrorHandledTest org.jboss.byteman.agent.Transformer : inserted trigger for ConcurrentMergeErrorHandledTest in class org.h2.jdbc.JdbcDatabaseMetaData Rule.execute called for ConcurrentMergeErrorHandledTest_0 Rule.ensureTypeCheckedCompiled : error type checking rule ConcurrentMergeErrorHandledTest org.jboss.byteman.rule.exception.TypeException: ThrowExpression.typeCheck : exception type not declared by trigger method java.sql.SQLException file /home/sanne/workspaces/hibernate/hibernate-core-parent/testsuite/src/test/resources/bytemanrules.txt line 42
The problem being that the method signature in the interface declares that it could throw a SQLException, but the actual implementation of H2's JDBC driver does not declare the same exception.
So I guess it's not possible to break this typesafety, but could I take advantage of it?
I think I could assume that all drivers not declaring it can't possibly ever throw it, so I would like to skip the rule if it's not possible to apply it, without failing the test. Ideally I'd love it to invoke a custome helper method, that would be useful to report in some way which tests where skipped.