Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-18989

Cannot get Plugin to honor Java Jar added via "Additional groovy classpath"

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Major Major
    • Windows 7, Jenkins 1.523, Groovy Postbuild: 1.8, SQL Server 2008, JDBC 4.0

      Jenkins: 1:523, PostBuild: 1.8

      I have a Groovy script . . . that will eventually be a post build script . . . for now the script runs on its own and connects to a Database, but with this CLASSPATH set:

      SET CLASSPATH=C:\Users\fmerrow\Downloads\Microsoft JDBC Driver 4.0 for SQL Server\sqljdbc_4.0\enu\sqljdbc4.jar

      However, when I try to get the working script to run as a post build . . . I cannot find the class in that file.

      I've tried to specify as Directory using "Additional groovy classpath" and when that didn't work as full path to the Jar file. I also wondered if spaces would be an issue . . . Quoting gave odd results (pretended C:\Program Files(x85)\Jenkins to the path) so I moved it into a directory with no spaces (again tried both file and directory) . . . I cannot seem to get it to find the class in this jar file.

      Works fine "in the clear" with CLASSPATH set, but I cannot get it to work inside the Jenkins JVM.

      Frank

          [JENKINS-18989] Cannot get Plugin to honor Java Jar added via "Additional groovy classpath"

          Frank Merrow added a comment -

          When I actually got around to trying this, I could not make it work.

          While the code worked fine when run as a Groovy script on its own, once it was inside the Jenkins JVM, for some reason "rootLoader" was null. I'm not enough of a Groovy Guru to understand the difference between the two loaders, but I am still stumped and have no workaround.

          Frank Merrow added a comment - When I actually got around to trying this, I could not make it work. While the code worked fine when run as a Groovy script on its own, once it was inside the Jenkins JVM, for some reason "rootLoader" was null. I'm not enough of a Groovy Guru to understand the difference between the two loaders, but I am still stumped and have no workaround.

          Frank Merrow added a comment -

          Cool . . . just made it to my SQL server from inside the plugin with the following change instead of "this":

          manager.hudson.class.classLoader.addURL(new URL("file:///" + filePath))

          Frank Merrow added a comment - Cool . . . just made it to my SQL server from inside the plugin with the following change instead of "this": manager.hudson.class.classLoader.addURL(new URL("file:///" + filePath))

          Viktor Berke added a comment -

          Frank, how did that work? For me that says:

          groovy.lang.MissingPropertyException: No such property: manager for class: Script1

          Viktor Berke added a comment - Frank, how did that work? For me that says: groovy.lang.MissingPropertyException: No such property: manager for class: Script1

          Torben Knerr added a comment -

          fmerrow, bviktor would be higly interested in that, too

          Torben Knerr added a comment - fmerrow , bviktor would be higly interested in that, too

          joel Young added a comment -

          I've been having the same problem. I'm using v2.2 of the plugin. I've tried using the "Additional Classpath" fields, gone into the Jenkins file in /etc/sysconfig and added a "-cp" options to the JENKINS_JAVA_OPTIONS setting, and tried using the classload in the form: manager.hudson.class.classLoader.addURL(new URL("file:///" + filePath))

          None of it seemed to work. In the end I had to create a "Trigger parameterized build on other project" then specify my script in a Build step. The classpath variables appeared to work there.

          joel Young added a comment - I've been having the same problem. I'm using v2.2 of the plugin. I've tried using the "Additional Classpath" fields, gone into the Jenkins file in /etc/sysconfig and added a "-cp" options to the JENKINS_JAVA_OPTIONS setting, and tried using the classload in the form: manager.hudson.class.classLoader.addURL(new URL("file:///" + filePath)) None of it seemed to work. In the end I had to create a "Trigger parameterized build on other project" then specify my script in a Build step. The classpath variables appeared to work there.

          Zach Auclair added a comment - - edited

          I was able to get the following to work

          in my postbuild task

          this.class.classLoader.parseClass("/home/jenkins/GitlabPostbuildReporter.groovy")
          GitlabPostbuildReporter.newInstance(manager).report()
          

          in my file on disk at /home/jenkins/GitlabPostbuildReporter.groovy

          class GitlabPostbuildReporter {
            def manager
            public GitlabPostbuildReporter(manager){
              if(manager == null) {
                throw new RuntimeException("Manager object musn't be null")
              }
              this.manager = manager
            }
            public def report() {
              // do work with manager object
            }
          }
          

          Zach Auclair added a comment - - edited I was able to get the following to work in my postbuild task this . class. classLoader.parseClass( "/home/jenkins/GitlabPostbuildReporter.groovy" ) GitlabPostbuildReporter.newInstance(manager).report() in my file on disk at /home/jenkins/GitlabPostbuildReporter.groovy class GitlabPostbuildReporter { def manager public GitlabPostbuildReporter(manager){ if (manager == null ) { throw new RuntimeException( "Manager object musn't be null " ) } this .manager = manager } public def report() { // do work with manager object } }

          Hi!
          I am doing the same like Zach in the last comment but getting error message
          groovy.lang.MissingPropertyException: No such property: XXX for class: Script1

          does anyone have any idea why it can happen?

          thanks

          Anna Bredikhina added a comment - Hi! I am doing the same like Zach in the last comment but getting error message groovy.lang.MissingPropertyException: No such property: XXX for class: Script1 does anyone have any idea why it can happen? thanks

          Ayrat Natfullin added a comment - - edited

          Also spent hours trying to make it working but got lots various errors.
          Finally could make it working the following way:

          Groovy file:

          class GitlabPostbuildReporter {
            def manager
            
            public GitlabPostbuildReporter(Object manager){
              if(manager == null) {
                throw new RuntimeException("Manager object can't be null")
              }
              this.manager = manager
            }
            
            public def report() {
              // do work with manager object
              manager.addBadge("db_in.gif", "Stored to DB")
            }
          }
          

          On Jenkins side create a groovy script post build action:

          // Ayrat Natfullin: this code passes manager object to external groovy script 
          // so you may operate with current job
          import hudson.model.*
            
          import groovy.lang.GroovyClassLoader;
          import groovy.lang.GroovyObject;
           
          import java.io.File;
          
          // short ref for printing out in Jenkins console
          out = manager.listener.logger.&println
          
          def file = new File("D:/tools/Jenkins/scripts/GitlabPostbuildReporter.groovy")
          // this helps you to make sure script exists and Jenkins has access to it
          out(file.exists())
          
          // Loading script using String parameter doesn't work so switch to using File instead
          Class groovy = this.class.classLoader.parseClass(new File("D:/tools/Jenkins/scripts/GitlabPostbuildReporter.groovy"));
          GroovyObject groovyObj = (GroovyObject) groovy.newInstance(manager);
          // example of how to print out all existing methods
          out(groovyObj.metaClass.methods*.name.sort().unique());
          // call report that will add Badge icon to current build (see script above)
          groovyObj.report();
          

          Ayrat Natfullin added a comment - - edited Also spent hours trying to make it working but got lots various errors. Finally could make it working the following way: Groovy file: class GitlabPostbuildReporter { def manager public GitlabPostbuildReporter( Object manager){ if (manager == null ) { throw new RuntimeException( "Manager object can't be null " ) } this .manager = manager } public def report() { // do work with manager object manager.addBadge( "db_in.gif" , "Stored to DB" ) } } On Jenkins side create a groovy script post build action: // Ayrat Natfullin: this code passes manager object to external groovy script // so you may operate with current job import hudson.model.* import groovy.lang.GroovyClassLoader; import groovy.lang.GroovyObject; import java.io.File; // short ref for printing out in Jenkins console out = manager.listener.logger.&println def file = new File( "D:/tools/Jenkins/scripts/GitlabPostbuildReporter.groovy" ) // this helps you to make sure script exists and Jenkins has access to it out(file.exists()) // Loading script using String parameter doesn't work so switch to using File instead Class groovy = this . class. classLoader.parseClass( new File( "D:/tools/Jenkins/scripts/GitlabPostbuildReporter.groovy" )); GroovyObject groovyObj = (GroovyObject) groovy.newInstance(manager); // example of how to print out all existing methods out(groovyObj.metaClass.methods*.name.sort().unique()); // call report that will add Badge icon to current build (see script above) groovyObj.report();

          Also the original question was about "Additional groovy classpath": in Jenkins ver. 1.619 it works.
          I've moved all logic to java uber jar, added jar to classpath in Groovy Script Post Build action and is able to make http requests from Java.

          Ayrat Natfullin added a comment - Also the original question was about "Additional groovy classpath": in Jenkins ver. 1.619 it works. I've moved all logic to java uber jar, added jar to classpath in Groovy Script Post Build action and is able to make http requests from Java.

          Ayrat, thanks a lot! your solution works for me!

          Anna Bredikhina added a comment - Ayrat, thanks a lot! your solution works for me!

            wolfs Stefan Wolf
            fmerrow Frank Merrow
            Votes:
            3 Vote for this issue
            Watchers:
            10 Start watching this issue

              Created:
              Updated: