Could not find ClassNode for MetaClass

Can anyone tell me why the snippet in the end gives me the following messages?

{<DB data here}
groovy.sql.DataSet@c75d20
  FAILURE: Build failed with an exception.
  * Where:
Script '...\db-tasks.gradle' line: 440
  * What went wrong:
Execution failed for task 'dbtest'.
> Could not find the ClassNode for MetaClass: org.codehaus.groovy.runtime.metaclass.ClosureMetaClass@20b2e046[class db_tasks_4qn62qasr0ln4j3vbt93u2pe09$_run_closure14_closure20]
def sql = Sql.newInstance("jdbc:oracle:thin:@$dbHost:$dbPort:$dbName", dbUser, dbPassword)
   def coreLogging = sql.dataSet('CORE_LOGGING')
   println coreLogging.firstRow()
   def temp = coreLogging.findAll { it.SOURCE_DATE != null }
   println temp
   println temp.firstRow()
   sql.close()

Can you post the full stack trace (’-s’) and tell us which line of the script is failing? Which Gradle version are you using (‘gradle -v’)? As far as I know, some features of the ‘Sql’ class don’t work in all environments, and apparently ‘findAll’ is one of them. If you need the details, the Groovy folks may be better able to help.

Sure, you can find the stack trace at Gist #3838320 The failing line is “println temp.firstRow()” (you can also see the output of the other two println statements) Gradle version is 1.0 currently, but I just tried with 1.2 and it’s the same.

You may be right, GROOVY-2450 could be the issue. So I guess until GROOVY-4618 is fixed and the Groovy version with the fix shipped with Gradle I cannot use findAll in a Gradle script? Is there any workaround? Can I somehow disable build script pre-compilation - at least for testing purpose -?

From the stack trace, I would have expected that ‘findAll’ is failing, not ‘firstRow’. In any case, the best (and possibly only) solution is not to use ‘Sql.dataSet’ but the more traditional ‘Sql.rows’ etc. I wouldn’t bet on ‘Sql.dataSet’ being fixed anytime soon. And even if it was, Gradle won’t be able to upgrade to a new major Groovy version for quite a while (for backwards compatibility reasons).

What shows evidence that findAll is failing in the stack trace?

I only see that it says the closure is failing, and the line it says is the second firstRow line. Also you see in the output that the first and second println statements execute just fine.

Yes I guess not using DataSet is the only option currently, thanks.

How about my question for disabling pre-compilation?

I’d at least like to verify that this would fix the problem.

What shows evidence that findAll is failing in the stack trace?

It’s complaining about a closure, and that closure is likely the one passed to ‘findAll’. I had missed that there is another ‘firstRow’ after the ‘findAll’. It’s plausible that the second ‘firstRow’ is failing.

How about my question for disabling pre-compilation?

Not sure what exactly you mean by that, as Groovy code always gets compiled before execution. In any case, there is no way to control how and when Gradle compiles build scripts.

It’s complaining about a closure, and that closure is likely the one passed to findAll. I had missed that there is another firstRow after the findAll. It’s plausible that the second firstRow is failing.

The closure that the stack trace is mentioning is indeed the findAll closure, I’ve had a look inside the mentioned .class file. But nevertheless it is executed fine for the second println statement but fails when doing an additional firstRow() call. Sometimes dynamic language are not too nice. g

Not sure what exactly you mean by that, as Groovy code always gets compiled before execution.

Compiled yes, pre-compiled no. You can either pre-compile a .groovy file to a .class file with groovyc and then use that .class file like Gradle is doing as far as I interpret what I see in the cache directory and hear from you. The other option is to directly run a .groovy file in “interpreted” mode by passing it to “groovy”. According to the Groovy bugs I mentioned above this problem happens when the .groovy Script is not in the classpath which is the case e. g. when you pre-compile the .groovy script to a .class file like Gradle does. Maybe it would help to add the script to the classpath somehow despite the fact that it is pre-compiled to a .class file, but I guess not.

In short, the current implementation of ‘findAll’ is a hack, and I wouldn’t try to compensate for this with hacks on the Gradle side.

Yeah, you are probably right if that’s the case, thanks for your explanations. :slight_smile:

Can I somehow set this to “Answered” or is that only possible by moderators?

Unfortunately, only moderators can hit the “Answered” button, but I’m more than happy to do it for you. :slight_smile:

great, thanks :slight_smile: