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

declarative-linter don't work with shared library

      I have a jenkinsfile which call shared library at the beginning

      @Library('gconftools')
      import forjenkins.GetNodes
      

      this jenkinsfile work correctly, but when I want to test with declarative-linter, there is an error.

      java -jar /var/lib/jenkins/home/war/WEB-INF/jenkins-cli.jar -s http://serveur.domainperso:8082 declarative-linter --username=user --password mdp <script.groovy
      
      Errors encountered validating Jenkinsfile:
      WorkflowScript: 7: unable to resolve class forjenkins.GetNodes
       @ line 7, column 1.
         @Library('gconftools')
         ^
      
      WorkflowScript: 26: unable to resolve class forjenkins.GetNodes 
       @ line 26, column 7.
                      z = new forjenkins.GetNodes()
               ^
      

          [JENKINS-42730] declarative-linter don't work with shared library

          hi,

          I have found the doc (https://jenkins.io/doc/book/pipeline/shared-libraries/#loading-libraries-dynamically ), and resolved my problem . So you can close this bug.

           

          Boudoux Etienne added a comment - hi, I have found the doc ( https://jenkins.io/doc/book/pipeline/shared-libraries/#loading-libraries-dynamically ), and resolved my problem . So you can close this bug.  

          Reinhold Füreder added a comment - - edited

          I stumbled over this issue as well (when using global vars from "vars/" and using classes from the "src/"), but was not able to resolve the problem to my satisfation:

          • either the linter complains about the import (initial/old approach via @Library and import), while the pipeline works
          • or the pipeline fails

           

          I tried many unsuccessful approaches, here are some of them:

          1. Using library directive on top (before pipeline) and a second library for dynamic class usage
            --- old/Jenkinsfile
            +++ new/Jenkinsfile
             
            -@Library('acme-shared-library') _
            -import com.acme.Constants
            +library('acme-shared-library')
             
             pipeline {
            ...
                   steps {
                     script {
                       acme.setBuildDisplayName()
            +          
            +          def lib = library('acme-shared-library').com.acme // preselect the package
            +          echo lib.Constants.DEVOPS_EMAIL
                     }
                   }
                 }
            
            • Interesting log output:
              Only using first definition of library acme-shared-library
              
            • Failure:
              java.lang.IllegalAccessException: com.acme.Constants was defined in file:///var/lib/jenkins/jobs/***/builds/42/libs/acme-shared-library/vars/acme.groovy which was not inside file:///var/lib/jenkins/jobs/***/builds/42/libs/acme-shared-library/src/
              	at org.jenkinsci.plugins.workflow.libs.LibraryStep$LoadedClasses.loadClass(LibraryStep.java:287)
              	at org.jenkinsci.plugins.workflow.libs.LibraryStep$LoadedClasses.getProperty(LibraryStep.java:240)
              	at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:174)
              	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:456)
              	at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:243)
              	at org.kohsuke.groovy.sandbox.GroovyInterceptor.onGetProperty(GroovyInterceptor.java:52)
              	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:308)
              	at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:241)
              	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:238)
              	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:28)
              	at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
              	at WorkflowScript.run(WorkflowScript:28)
              	at ___cps.transform___(Native Method)
                ...
              
          2. Using library directive on top (before pipeline) (without a second library for dynamic class usage) and direct FQ access to class
            --- old/Jenkinsfile
            +++ new/Jenkinsfile
             
            -@Library('acme-shared-library') _
            -import com.acme.Constants
            +library('acme-shared-library')
             
             pipeline {
            ...
                   steps {
                     script {
                       acme.setBuildDisplayName()
            +          
            +          echo "devops email: ${com.acme.Constants.DEVOPS_EMAIL}"
                     }
                   }
                 }
            
            • No interesting log output anymore (cf. "Only using first definition of library acme-shared-library")
            • Failure:
              groovy.lang.MissingPropertyException: No such property: com for class: groovy.lang.Binding
              	at groovy.lang.Binding.getVariable(Binding.java:63)
              	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:224)
              	at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:241)
              	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:238)
              	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221)
              	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221)
              	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221)
              	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221)
              	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221)
              	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:28)
              	at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
              	at WorkflowScript.run(WorkflowScript:27)
              	at ___cps.transform___(Native Method)
                ...
              
          3. Using library directive in pipeline before first global var usage
            --- old/Jenkinsfile
            +++ new/Jenkinsfile
             
            -@Library('acme-shared-library') _
            -import com.acme.Constants
             
             pipeline {
            ...
                   steps {
                     script {
            +          def lib = library('acme-shared-library').com.acme // preselect the package
                       acme.setBuildDisplayName()
            +          echo "devops email: ${lib.Constants.DEVOPS_EMAIL}"         }
                   }
                 }
            
            • Failure:
              java.lang.IllegalAccessException: com.acme.Constants was defined in file:///var/lib/jenkins/jobs/***/builds/45/libs/acme-shared-library/vars/acme.groovy which was not inside file:///var/lib/jenkins/jobs/***/builds/45/libs/acme-shared-library/src/
              	at org.jenkinsci.plugins.workflow.libs.LibraryStep$LoadedClasses.loadClass(LibraryStep.java:287)
              	at org.jenkinsci.plugins.workflow.libs.LibraryStep$LoadedClasses.getProperty(LibraryStep.java:240)
              	at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:174)
              	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:456)
              	at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:243)
              	at org.kohsuke.groovy.sandbox.GroovyInterceptor.onGetProperty(GroovyInterceptor.java:52)
              	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:308)
              	at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:241)
              	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:238)
              	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:28)
              	at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
              	at WorkflowScript.run(WorkflowScript:25)
              	at ___cps.transform___(Native Method)
                ...
              
          4. Same for using library directive in pipeline before first global var usage and FQ access to class instead of preselect package
            --- old/Jenkinsfile
            +++ new/Jenkinsfile
             
            -@Library('acme-shared-library') _
            -import com.acme.Constants
             
             pipeline {
            ...
                   steps {
                     script {
            +          def lib = library('acme-shared-library')
                       acme.setBuildDisplayName()
            +          echo "devops email: ${lib.com.acme.Constants.DEVOPS_EMAIL}"
                   }
                 }
            
          5. Using new libraries section in pipeline
            --- old/Jenkinsfile
            +++ new/Jenkinsfile
             
            -@Library('acme-shared-library') _
            -import com.acme.Constants
             
             pipeline {
            ...
            +  libraries {
            +    lib('acme-shared-library')
            +  }
            +
                   steps {
                     script {
                       acme.setBuildDisplayName()
            +          echo "devops email: ${com.acme.Constants.DEVOPS_EMAIL}"
                   }
                 }
            
            • Failure:
              groovy.lang.MissingPropertyException: No such property: com for class: groovy.lang.Binding
              	at groovy.lang.Binding.getVariable(Binding.java:63)
              	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:224)
              	at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:241)
              	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:238)
              	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221)
              	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221)
              	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221)
              	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221)
              	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221)
              	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:28)
              	at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
              	at WorkflowScript.run(WorkflowScript:29)
              	at ___cps.transform___(Native Method)
                ...
              

          Oh! The following approach seems to work (linter is happy and pipeline works), but is a rather inconvenient/surprising workaround; thus, this is rather interesting for the bug fix, but not a real workaround, let alone a solution, I claim:

          • not using libraries block in pipeline block, but using library including suffix for class in "src/" (as seen above it does not work, if the first library statement is without class usage suffix!)
          --- old/Jenkinsfile
          +++ new/Jenkinsfile
           
          -@Library('acme-shared-library') _
          -import com.acme.Constants
           
           pipeline {
          ...
                 steps {
                   script {
          +          echo "devops email: ${library('acme-shared-library').com.acme.Constants.DEVOPS_EMAIL}"
                     acme.setBuildDisplayName()
          +          
                 }
               }
          

          IMHO this is very confusing and should be addressed in another issue, but presumably not in the linter (unless the initial/old approach via @Library and import will be re-recommended, and the linter accepts it).

          Reinhold Füreder added a comment - - edited I stumbled over this issue as well (when using global vars from "vars/" and using classes from the "src/"), but was not able to resolve the problem to my satisfation: either the linter complains about the import (initial/old approach via @Library and import ), while the pipeline works or the pipeline fails   I tried many unsuccessful approaches, here are some of them: Using library directive on top (before pipeline ) and a second library for dynamic class usage --- old/Jenkinsfile +++ new /Jenkinsfile -@Library( 'acme-shared-library' ) _ - import com.acme.Constants +library( 'acme-shared-library' ) pipeline { ... steps { script { acme.setBuildDisplayName() + + def lib = library( 'acme-shared-library' ).com.acme // preselect the package + echo lib.Constants.DEVOPS_EMAIL } } } Interesting log output: Only using first definition of library acme-shared-library Failure: java.lang.IllegalAccessException: com.acme.Constants was defined in file:///var/lib/jenkins/jobs/***/builds/42/libs/acme-shared-library/vars/acme.groovy which was not inside file:///var/lib/jenkins/jobs/***/builds/42/libs/acme-shared-library/src/ at org.jenkinsci.plugins.workflow.libs.LibraryStep$LoadedClasses.loadClass(LibraryStep.java:287) at org.jenkinsci.plugins.workflow.libs.LibraryStep$LoadedClasses.getProperty(LibraryStep.java:240) at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:174) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:456) at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:243) at org.kohsuke.groovy.sandbox.GroovyInterceptor.onGetProperty(GroovyInterceptor.java:52) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:308) at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:241) at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:238) at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:28) at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20) at WorkflowScript.run(WorkflowScript:28) at ___cps.transform___(Native Method) ... Using library directive on top (before pipeline ) (without a second library for dynamic class usage) and direct FQ access to class --- old/Jenkinsfile +++ new /Jenkinsfile -@Library( 'acme-shared-library' ) _ - import com.acme.Constants +library( 'acme-shared-library' ) pipeline { ... steps { script { acme.setBuildDisplayName() + + echo "devops email: ${com.acme.Constants.DEVOPS_EMAIL}" } } } No interesting log output anymore (cf. "Only using first definition of library acme-shared-library") Failure: groovy.lang.MissingPropertyException: No such property: com for class: groovy.lang.Binding at groovy.lang.Binding.getVariable(Binding.java:63) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:224) at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:241) at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:238) at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221) at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221) at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221) at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221) at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221) at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:28) at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20) at WorkflowScript.run(WorkflowScript:27) at ___cps.transform___(Native Method) ... Using library directive in pipeline before first global var usage --- old/Jenkinsfile +++ new /Jenkinsfile -@Library( 'acme-shared-library' ) _ - import com.acme.Constants pipeline { ... steps { script { + def lib = library( 'acme-shared-library' ).com.acme // preselect the package acme.setBuildDisplayName() + echo "devops email: ${lib.Constants.DEVOPS_EMAIL}" } } } Failure: java.lang.IllegalAccessException: com.acme.Constants was defined in file:///var/lib/jenkins/jobs/***/builds/45/libs/acme-shared-library/vars/acme.groovy which was not inside file:///var/lib/jenkins/jobs/***/builds/45/libs/acme-shared-library/src/ at org.jenkinsci.plugins.workflow.libs.LibraryStep$LoadedClasses.loadClass(LibraryStep.java:287) at org.jenkinsci.plugins.workflow.libs.LibraryStep$LoadedClasses.getProperty(LibraryStep.java:240) at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:174) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:456) at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:243) at org.kohsuke.groovy.sandbox.GroovyInterceptor.onGetProperty(GroovyInterceptor.java:52) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:308) at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:241) at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:238) at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:28) at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20) at WorkflowScript.run(WorkflowScript:25) at ___cps.transform___(Native Method) ... Same for using library directive in pipeline before first global var usage and FQ access to class instead of preselect package --- old/Jenkinsfile +++ new /Jenkinsfile -@Library( 'acme-shared-library' ) _ - import com.acme.Constants pipeline { ... steps { script { + def lib = library( 'acme-shared-library' ) acme.setBuildDisplayName() + echo "devops email: ${lib.com.acme.Constants.DEVOPS_EMAIL}" } } Using new libraries section in pipeline --- old/Jenkinsfile +++ new /Jenkinsfile -@Library( 'acme-shared-library' ) _ - import com.acme.Constants pipeline { ... + libraries { + lib( 'acme-shared-library' ) + } + steps { script { acme.setBuildDisplayName() + echo "devops email: ${com.acme.Constants.DEVOPS_EMAIL}" } } Failure: groovy.lang.MissingPropertyException: No such property: com for class: groovy.lang.Binding at groovy.lang.Binding.getVariable(Binding.java:63) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:224) at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:241) at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:238) at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221) at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221) at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221) at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221) at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221) at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:28) at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20) at WorkflowScript.run(WorkflowScript:29) at ___cps.transform___(Native Method) ... Oh! The following approach seems to work (linter is happy and pipeline works), but is a rather inconvenient/surprising workaround; thus, this is rather interesting for the bug fix, but not a real workaround, let alone a solution, I claim: not using libraries block in pipeline block, but using library including suffix for class in "src/" (as seen above it does not work, if the first library statement is without class usage suffix!) --- old/Jenkinsfile +++ new /Jenkinsfile -@Library( 'acme-shared-library' ) _ - import com.acme.Constants pipeline { ... steps { script { + echo "devops email: ${library( 'acme-shared-library' ).com.acme.Constants.DEVOPS_EMAIL}" acme.setBuildDisplayName() + } } IMHO this is very confusing and should be addressed in another issue, but presumably not in the linter (unless the initial/old approach via @Library and import will be re-recommended, and the linter accepts it).

          I've hit the same issue in my scripted pipeline.  Specifically 

          java.lang.IllegalAccessException: com.acme.Constants was defined in file:///var/lib/jenkins/jobs/***/builds/45/libs/acme-shared-library/vars/acme.groovy which was not inside file:///var/lib/jenkins/jobs/***/builds/45/libs/acme-shared-library/src/

          Matthew Mitchell added a comment - I've hit the same issue in my scripted pipeline.  Specifically  java.lang.IllegalAccessException: com.acme.Constants was defined in file:///var/lib/jenkins/jobs/***/builds/45/libs/acme-shared-library/vars/acme.groovy which was not inside file:///var/lib/jenkins/jobs/***/builds/45/libs/acme-shared-library/src/

          I have been able to workaround this by using the following code:

          // JENKINS-42730
          def lib = library("libs")
          def ocathpr = lib.com.package.qe.helpers.Helper.new(this)
          // END JENKINS_42730
          
          pipeline {
          ......
          

          Raul Arabaolaza added a comment - I have been able to workaround this by using the following code: // JENKINS-42730 def lib = library( "libs" ) def ocathpr = lib.com. package .qe.helpers.Helper. new ( this ) // END JENKINS_42730 pipeline { ......

          Sirine Beji added a comment -

          rarabaolaza  Did you try that code ? because it returns the same error as mmitche

          Did someone figured out this error ?

          Sirine Beji added a comment - rarabaolaza   Did you try that code ? because it returns the same error as mmitche !  Did someone figured out this error ?

          Christoph Vogtländer added a comment - - edited

          The workaround of rarabaolaza is working for me. Instantiating the object before it is used inside the shared library itself.

          So something like

          def lib = library("libs")
          def o = lib.com.package.classA.new()
          
          customStep() // step which is defined in "lib" and also instantiates classA
          
          o.method()
          

          works, while something like

          def lib = library("libs")
          
          customStep() // step which is defined in "lib" and instantiates classA
          
          lib.com.package.classA.new().method() // java.lang.IllegalAccessException
          

          does not

          Christoph Vogtländer added a comment - - edited The workaround of rarabaolaza is working for me. Instantiating the object before it is used inside the shared library itself. So something like def lib = library( "libs" ) def o = lib.com. package . classA . new () customStep() // step which is defined in "lib" and also instantiates classA o.method() works, while something like def lib = library( "libs" ) customStep() // step which is defined in "lib" and instantiates classA lib.com. package . classA . new ().method() // java.lang.IllegalAccessException does not

          Hari Dara added a comment -

          I am seeing this IllegalAccessException too. In my case, I have a util function that takes the library object and the name of the class. It navigates the package and accesses the class using Groovy dynamic attribute name syntax (obj."$attr") and then call new() on it. This works fine when the class is in the same sharedlib as the util function, but if I pass another sharedlib, then I get the exception.

          Hari Dara added a comment - I am seeing this IllegalAccessException too. In my case, I have a util function that takes the library object and the name of the class. It navigates the package and accesses the class using Groovy dynamic attribute name syntax ( obj."$attr" ) and then call new() on it. This works fine when the class is in the same sharedlib as the util function, but if I pass another sharedlib, then I get the exception.

          Hari Dara added a comment - - edited

          To be specific, I am hitting the issue reported by mmitche which comes from here:

                          if (!actual.startsWith(srcUrlC)) {
                              throw new IllegalAccessException(name + " was defined in " + actual + " which was not inside " + srcUrlC);
                          }
          

          This looks like a different issue than the one reported by OP, so not sure why this was classified as a linter issue.

          Hari Dara added a comment - - edited To be specific, I am hitting the issue reported by mmitche which comes from here :                 if (!actual.startsWith(srcUrlC)) {                     throw new IllegalAccessException(name + " was defined in " + actual + " which was not inside " + srcUrlC);                 } This looks like a different issue than the one reported by OP, so not sure why this was classified as a linter issue.

          Hari Dara added a comment -

          FWIW, I was able to solve my above mentioned issue. The issue in my case was that I was indeed making use of a wrong lib object. My logic resolved the package path and assumed that a non-null object implies that the package existed in the lib, but after going through the code, I realized that it will never return null and it is only valid if the class can be resolved, so after I adjusted the logic, it is using the right lib object to resolve and works as expected.

          What is strange is that the code is able to resolve classes from any lib, so it is really a responsibility of the user to make use of the right lib.

          Hari Dara added a comment - FWIW, I was able to solve my above mentioned issue. The issue in my case was that I was indeed making use of a wrong lib object. My logic resolved the package path and assumed that a non- null object implies that the package existed in the lib, but after going through the code , I realized that it will never return null and it is only valid if the class can be resolved, so after I adjusted the logic, it is using the right lib object to resolve and works as expected. What is strange is that the code is able to resolve classes from any lib, so it is really a responsibility of the user to make use of the right lib.

          Jim Klimov added a comment - - edited

          Trying to convert pipelines from @Library notation to dynamic library step (so we can use branch names as parameter, or same branchname of shared lib as the branchname of pipeline/component source, etc.) I've also stumbled upon this issue.

          Like for posters above, it seems that when I use just sort-of-qualified names of classes (with static methods and data fields), I get the "was defined in ... which was not inside" error:

          def libmpci = library("com.myproduct.ci@${BRANCH_NAME}").com.myproduct.ci // preselect the package
          
          // use helper class (with static properties to init it) - ok before a JSL step:
          libmpci.Utils.indentLinesSpacenum = 3
          
          // use step from "vars"
          initDebugSettings(true, false)
          
          // use helper class (with static properties to init it) - fails after a JSL step:
          libmpci.Utils.indentLinesPrepend = '|'
          
          // => java.lang.IllegalAccessException: com.myproduct.ci.Utils was defined in file:///var/lib/jenkins/jobs/SUTLockable-test/builds/488/libs/4a46ae3db26fbcc99db4b40afd24409503b2223922e231a06af47b826ec7a04b/vars/initDebugSettings.groovy which was not inside file:///var/lib/jenkins/jobs/SUTLockable-test/builds/488/libs/4a46ae3db26fbcc99db4b40afd24409503b2223922e231a06af47b826ec7a04b/src/
          

          And notably, the step source under vars/ is the last step called in the pipeline before the "offending" call into src/ class (I did waste some time to track down where such step's source might reference the class - some do, some don't).

          As I found (thanks to posters above), it seems like the trick is to replace "import" lines for classes we want to use with same-named new() calls, e.g.:

          // Obsoleted "Static library" call:
          //@Library('com.myproduct.ci@wip-123456') _
          //import com.myproduct.ci.Utils;
          
          // New dynamically-loaded library call:
          def libmpci = library("com.myproduct.ci@${BRANCH_NAME}").com.myproduct.ci // preselect the package
          def Utils = libmpci.Utils.new()

          ...and on the upside this seems (so far) to not require further changes to convert the code (e.g. no need to replace Utils => libmpci.Utils all over the place), so code like this works for both, I hope (gotta test over time):

          initDebugSettings(true)
          Utils.indentLinesSpacenum = 3
          Utils.indentLinesPrepend = '|'

          Jim Klimov added a comment - - edited Trying to convert pipelines from @Library notation to dynamic library step (so we can use branch names as parameter, or same branchname of shared lib as the branchname of pipeline/component source, etc.) I've also stumbled upon this issue. Like for posters above, it seems that when I use just sort-of-qualified names of classes (with static methods and data fields), I get the "was defined in ... which was not inside" error: def libmpci = library( "com.myproduct.ci@${BRANCH_NAME}" ).com.myproduct.ci // preselect the package // use helper class (with static properties to init it) - ok before a JSL step: libmpci.Utils.indentLinesSpacenum = 3 // use step from "vars" initDebugSettings( true , false ) // use helper class (with static properties to init it) - fails after a JSL step: libmpci.Utils.indentLinesPrepend = '|' // => java.lang.IllegalAccessException: com.myproduct.ci.Utils was defined in file:/// var /lib/jenkins/jobs/SUTLockable-test/builds/488/libs/4a46ae3db26fbcc99db4b40afd24409503b2223922e231a06af47b826ec7a04b/vars/initDebugSettings.groovy which was not inside file:/// var /lib/jenkins/jobs/SUTLockable-test/builds/488/libs/4a46ae3db26fbcc99db4b40afd24409503b2223922e231a06af47b826ec7a04b/src/ And notably, the step source under vars/ is the last step called in the pipeline before the "offending" call into src/ class (I did waste some time to track down where such step's source might reference the class - some do, some don't). As I found (thanks to posters above), it seems like the trick is to replace "import" lines for classes we want to use with same-named new() calls, e.g.: // Obsoleted "Static library" call: //@Library( 'com.myproduct.ci@wip-123456' ) _ // import com.myproduct.ci.Utils; // New dynamically-loaded library call: def libmpci = library( "com.myproduct.ci@${BRANCH_NAME}" ).com.myproduct.ci // preselect the package def Utils = libmpci.Utils. new () ...and on the upside this seems (so far) to not require further changes to convert the code (e.g. no need to replace Utils => libmpci.Utils all over the place), so code like this works for both, I hope (gotta test over time): initDebugSettings( true ) Utils.indentLinesSpacenum = 3 Utils.indentLinesPrepend = '|'

            Unassigned Unassigned
            bdouxx Boudoux Etienne
            Votes:
            15 Vote for this issue
            Watchers:
            25 Start watching this issue

              Created:
              Updated: