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

Classpath exception in Email Extension Plugin preSend script.

    • Icon: Bug Bug
    • Resolution: Not A Defect
    • Icon: Major Major
    • None
    • Jenkins 2.89.1
      Email Extension Plugin 2.61
      Script Security Plugin 1.38
      Groovy Plugin 2.0

      I had defined a working email extension in one of my templates that fired off emails in certain cases.  This extension defined the following groovy pre-send script:

      def getReplacementIndicatorFile(subproject) {
           if (subproject == null) {
                build.getWorkspace().child('build').child('replaceInfo.txt')
           } else {
                build.getWorkspace().child(subproject).child('build').child('replaceInfo.txt')

                }
      }
      if (this.hasProperty("RAWSUB")) {
          def replaceInfoFile = getReplacementIndicatorFile("${RAWSUB}")  
          logger.println("replaceInfoFile=${replaceInfoFile}")
          if (replaceInfoFile.exists()) {
              msg.text = replaceInfoFile.readToString()
          } else {
              cancel = true

              }
      } else {
         cancel = true
      }

       

      This script now fails with the following error:

       

      Pre-send script tried to access secured objects: classpath entry file:/ is a class directory, which are not allowed.
      ERROR: Could not send email as a part of the post-build publishers.
      org.jenkinsci.plugins.scriptsecurity.scripts.UnapprovedClasspathException: classpath entry file:/ is a class directory, which are not allowed.
              at org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval.using(ScriptApproval.java:570)
              at hudson.plugins.emailext.ExtendedEmailPublisher.expandClasspath(ExtendedEmailPublisher.java:678)
              at hudson.plugins.emailext.ExtendedEmailPublisher.executeScript(ExtendedEmailPublisher.java:620)
              at hudson.plugins.emailext.ExtendedEmailPublisher.executePresendScript(ExtendedEmailPublisher.java:573)
              at hudson.plugins.emailext.ExtendedEmailPublisher.sendMail(ExtendedEmailPublisher.java:456)
              at hudson.plugins.emailext.ExtendedEmailPublisher._perform(ExtendedEmailPublisher.java:441)
              at hudson.plugins.emailext.ExtendedEmailPublisher.perform(ExtendedEmailPublisher.java:349)
              at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
              at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:744)
              at hudson.model.AbstractBuild$AbstractBuildExecution.performAllBuildSteps(AbstractBuild.java:690)
              at hudson.model.Build$BuildExecution.cleanUp(Build.java:196)
              at hudson.model.Run.execute(Run.java:1771)
              at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
              at hudson.model.ResourceController.execute(ResourceController.java:97)
              at hudson.model.Executor.run(Executor.java:421)
      Finished: SUCCESS

       

      Since my script says nothing about the classpath, I wonder what I would need to do to set up a classpath for my script that does not produce this error.  Why is file:/ the default classpath?

      Also, nothing is available in the script approval page that I can approve to get around this.

      This issue was not present prior to the upgrade to the above versions.

       

          [JENKINS-48522] Classpath exception in Email Extension Plugin preSend script.

          I just attempted to reproduce and was unable to 

          David van Laatum added a comment - I just attempted to reproduce and was unable to 

          Steve Cohen added a comment -

          My Jenkins instance is launched with this command on Red Hat Enterprise Linux Server release 6.9 (Santiago)

          java -DHUDSON_HOME=/vtone/3rd-party/jenkins/jenkins/data -jar /vtone/3rd-party/jenkins/jenkins/bin/jenkins.war --logfile=/vtone/3rd-party/jenkins/jenkins/logs/jenkins.log --httpPort=14354 --prefix=/jenkins --handlerCountMax=500 --handlerCountMaxIdle=100

          The significant bits as far as this issue is concerned are that it was launched with a java -jar command with the jar being jenkins.war.  Jenkins.war is a symbolic link pointing a specific version of Jenkins.war:

          $ ll /vtone/3rd-party/jenkins/jenkins/bin/jenkins.war
          lrwxrwxrwx 1 jenkins jenkins 18 Dec 12 11:27 /vtone/3rd-party/jenkins/jenkins/bin/jenkins.war -> jenkins-2.89.1.war

          java is

          $ java -version
          java version "1.8.0_131"
          Java(TM) SE Runtime Environment (build 1.8.0_131-b33)
          Java HotSpot(TM) 64-Bit Server VM (build 25.131-b33, mixed mode)

          Perhaps you can find some differences with your setup that might explain your inability to replicate?

           

          Steve Cohen added a comment - My Jenkins instance is launched with this command on Red Hat Enterprise Linux Server release 6.9 (Santiago) java -DHUDSON_HOME=/vtone/3rd-party/jenkins/jenkins/data -jar /vtone/3rd-party/jenkins/jenkins/bin/jenkins.war --logfile=/vtone/3rd-party/jenkins/jenkins/logs/jenkins.log --httpPort=14354 --prefix=/jenkins --handlerCountMax=500 --handlerCountMaxIdle=100 The significant bits as far as this issue is concerned are that it was launched with a java -jar command with the jar being jenkins.war.  Jenkins.war is a symbolic link pointing a specific version of Jenkins.war: $ ll /vtone/3rd-party/jenkins/jenkins/bin/jenkins.war lrwxrwxrwx 1 jenkins jenkins 18 Dec 12 11:27 /vtone/3rd-party/jenkins/jenkins/bin/jenkins.war -> jenkins-2.89.1.war java is $ java -version java version "1.8.0_131" Java(TM) SE Runtime Environment (build 1.8.0_131-b33) Java HotSpot(TM) 64-Bit Server VM (build 25.131-b33, mixed mode) Perhaps you can find some differences with your setup that might explain your inability to replicate?  

          Steve Cohen added a comment -

          My log is littered with entries like this.  They seem to occur whenever I modify the template that holds the script that is failing, which thereby causes Jenkins to rewrite all the job configs that use the template:

          Dec 14, 2017 9:06:41 PM org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval configuring
          WARNING: Classpath file:/ is a class directory, which are not allowed. Ignored in configuration, use will be rejected

           

          Steve Cohen added a comment - My log is littered with entries like this.  They seem to occur whenever I modify the template that holds the script that is failing, which thereby causes Jenkins to rewrite all the job configs that use the template: Dec 14, 2017 9:06:41 PM org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval configuring WARNING: Classpath file:/ is a class directory, which are not allowed. Ignored in configuration, use will be rejected  

          Steve Cohen added a comment -

          At the point of actually running the job that produces the error, the log has:

          Dec 14, 2017 8:58:13 PM hudson.model.Run execute
          INFO: Platdev/Projects/jenkinsutil #722 main build action completed: SUCCESS
          Dec 14, 2017 8:58:14 PM org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval using
          WARNING: Classpath file:/ (550a0a3d3d812f9cf4cbf15b4a8afd4d9a56b0bd) is a class directory, which are not allowed.
          Dec 14, 2017 8:58:14 PM hudson.plugins.emailext.ExtendedEmailPublisher sendMail
          WARNING: Could not send email.

          followed by the stack trace shown above.

          Clearly something is munging the classpath from its legitimate value
          /vtone/3rd-party/jenkins/jenkins/bin/jenkins.war
          to

          file:/

          probably in the URL conversion process but I can't quite see where.

          I can't help but think that the fact that this file is actually a symbolic link might somehow be involved.

           

           

          Steve Cohen added a comment - At the point of actually running the job that produces the error, the log has: Dec 14, 2017 8:58:13 PM hudson.model.Run execute INFO: Platdev/Projects/jenkinsutil #722 main build action completed: SUCCESS Dec 14, 2017 8:58:14 PM org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval using WARNING: Classpath file:/ (550a0a3d3d812f9cf4cbf15b4a8afd4d9a56b0bd) is a class directory, which are not allowed. Dec 14, 2017 8:58:14 PM hudson.plugins.emailext.ExtendedEmailPublisher sendMail WARNING: Could not send email. followed by the stack trace shown above. Clearly something is munging the classpath from its legitimate value /vtone/3rd-party/jenkins/jenkins/bin/jenkins.war to file:/ probably in the URL conversion process but I can't quite see where. I can't help but think that the fact that this file is actually a symbolic link might somehow be involved.    

          Daniel Beck added a comment -

          Please provide the global Jenkins config.xml directly in JENKINS_HOME (after purging secrets), and the job's config.xml.

          Daniel Beck added a comment - Please provide the global Jenkins config.xml directly in JENKINS_HOME (after purging secrets), and the job's config.xml.

          Steve Cohen added a comment -

          There's no config.xml in JENKINS_HOME. I presume you mean the top level one in JENKINS_HOME/data. I am sending that along with the one that contains the email-ext stuff. This is a template used by many jobs.

          Steve Cohen added a comment - There's no config.xml in JENKINS_HOME. I presume you mean the top level one in JENKINS_HOME/data. I am sending that along with the one that contains the email-ext stuff. This is a template used by many jobs.

          Daniel Beck added a comment -

          As the screen shot shows, you configure one 'additional class path' entry, and it's the empty string.

          Don't do that.

          Click the red 'X' to remove it.

          Daniel Beck added a comment - As the screen shot shows, you configure one 'additional class path' entry, and it's the empty string. Don't do that. Click the red 'X' to remove it.

          Daniel Beck added a comment -

          User error

          Daniel Beck added a comment - User error

          Steve Cohen added a comment -

          Thank you, Daniel!
          Your find was the answer.
          That is not particularly obvious from the screen shot. It looks as though there are no entries in the additional classpath, rather than one empty entry. I suppose it would be an improvement to the plugin to treat an empty entry not as something to be added to the classpath. I might never have clicked the add button, had the question mark link been working, which I mentioned above. Looking at github it looks like that issue is a link looking for the helpfile in the wrong location.

          Anyway, thank you for your help.

          Steve Cohen added a comment - Thank you, Daniel! Your find was the answer. That is not particularly obvious from the screen shot. It looks as though there are no entries in the additional classpath, rather than one empty entry. I suppose it would be an improvement to the plugin to treat an empty entry not as something to be added to the classpath. I might never have clicked the add button, had the question mark link been working, which I mentioned above. Looking at github it looks like that issue is a link looking for the helpfile in the wrong location. Anyway, thank you for your help.

          Steve Cohen added a comment - - edited

          While it's true that adding a blank entry is a "User Error", it's also true that an empty string is not a valid file system path.  It would be better to refuse such entries than to convert them to "file:/" since the error message in no way points to the root cause.  If the current working directory is wanted on the classpath (don't see why it ever would be wanted in Jenkins), this should be indicated by

          '.'.

          Suggested improvement:
          ExtendedEmailPublisher.transformToClasspathEntries()

              private void transformToClasspathEntries(List<GroovyScriptPath> input, ExtendedEmailPublisherContext context, List<ClasspathEntry> output) {
                  for (GroovyScriptPath path : input) {
                      if (path.getPath().trim().isEmpty() {
                          continue;
                      } 
                      ...
                  }
              }
          

          An alternative improvement would be for the UI to simply not save empty classpath entries.

          Steve Cohen added a comment - - edited While it's true that adding a blank entry is a "User Error", it's also true that an empty string is not a valid file system path.  It would be better to refuse such entries than to convert them to "file:/" since the error message in no way points to the root cause.  If the current working directory is wanted on the classpath (don't see why it ever would be wanted in Jenkins), this should be indicated by '.'. Suggested improvement: ExtendedEmailPublisher.transformToClasspathEntries() private void transformToClasspathEntries(List<GroovyScriptPath> input, ExtendedEmailPublisherContext context, List<ClasspathEntry> output) { for (GroovyScriptPath path : input) { if (path.getPath().trim().isEmpty() { continue; } ... } } An alternative improvement would be for the UI to simply not save empty classpath entries.

            davidvanlaatum David van Laatum
            sc1478 Steve Cohen
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: