Reputation:
I'm testing a runtime change in the groovy.sql.Sql MetaClass, modifying the createConnection method. My aim is to allways call a process when some connection is requested.
Is there a restriction for changing protected methods? I can see that my change don't have effect, and if I log the invokeMethod()
, only public methods are printed.
Maybe I'm incorrect in my approach? Here's my script:
@Grapes([
@Grab(group='com.h2database', module='h2', version='1.3.160'),
@GrabConfig(systemClassLoader = true)
])
import com.h2database.*
import groovy.sql.*
import java.sql.*
def originalMethod = Sql.metaClass.&createConnection
Connection.metaClass.createConnection = {
println "Called $name"
originalMethod.invoke(this)
}
def db = Sql.newInstance('jdbc:h2:mem:', 'sa', '', 'org.h2.Driver')
// Setup database.
db.execute '''
create table if not exists languages(
id int primary key,
name varchar(20) not null
)
'''
Upvotes: 3
Views: 307
Reputation: 27200
The problem here isn't related to protected methods. The issue is that you are using Groovy's runtime metapgrogramming to replace an existing method and then expecting that meta programming to be in play when the method in question is called from Java. This style of metaprogramming doesn't apply to method calls made directly from Java. The groovy.sql.Sql class is written in Java and as such when the code inside of groovy.sql.Sql invokes the createConnection method, the real method is used, not the one that was metaprogrammed.
Upvotes: 4