Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No suitable ClassLoader found for grab when using @GrabConfig

I'm attempting to write a global function script that uses groovy.sql.SQL.

When adding the annotation @GrabConfig(systemClassLoader=true) I get an exception when using the global function in Jenkinsfile.

Here is the exception:

hudson.remoting.ProxyException: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
General error during conversion: No suitable ClassLoader found for grab

Here is my code:

@GrabResolver(name='nexus',    root='http://internal.repo.com')
@GrabConfig(systemClassLoader=true)
@Grab('com.microsoft.sqlserver:sqljdbc4:4.0')
import groovy.sql.Sql
import com.microsoft.sqlserver.jdbc.SQLServerDriver

def call(name) {
  echo "Hello world, ${name}"

  Sql.newInstance("jdbc:sqlserver://ipaddress/dbname", "username","password", "com.microsoft.sqlserver.jdbc.SQLServerDriver")
  //  sql.execute "select count(*) from TableName"
}
like image 437
BritishKnight Avatar asked Nov 18 '16 15:11

BritishKnight


2 Answers

Ensure that the "Use groovy sandbox" checkbox is unticked (it's below the pipeline script text box).

like image 111
Mark Avatar answered Nov 17 '22 13:11

Mark


As explained here, Pipeline "scripts" are not simple Groovy scripts, they are heavily transformed before running, some parts on master, some parts on slaves, with their state (variable values) serialized and passed to the next step. As such, not every Groovy feature is supported.

I'm not sure about @Grab support. It is discussed in JENKINS-26192 (which is declared as resolved, so maybe it works now).

Extract from a very interesting comment:

If you need to perform some complex or expensive tasks with unrestricted Groovy physically running on a slave, it may be simplest and most effective to simply write that code in a *.groovy file in your workspace (for example, in an SCM checkout) and then use tool and sh/bat to run Groovy as an external process; or even put this stuff into a Gradle script, Groovy Maven plugin execution, etc. The workflow script itself should be limited to simple and extremely lightweight logical operations focused on orchestrating the overall flow of control and interacting with other Jenkins features—slave allocation, user input, and the like.

In short, if you can move that custom part that needs SQL to an external script and execute that in a separate process (called from your Pipeline script), that should work. But doing this in the Pipeline script itself is more complicated.

like image 1
Hugues M. Avatar answered Nov 17 '22 14:11

Hugues M.