如何隔离Jenkins管道Groovy共享库类加载器?

如何隔离Jenkins管道Groovy共享库类加载器?,jenkins,groovy,classloader,jenkins-pipeline,Jenkins,Groovy,Classloader,Jenkins Pipeline,我有一个Groovy库作为全局共享库提供: package com.example @Grab(group="org.apache.httpcomponents", module="httpclient", version="[4.5.3,)") import org.apache.http.HttpHost import org.apache.http.impl.client.HttpClients class MyClass implements Serializable { sta

我有一个Groovy库作为全局共享库提供:

package com.example

@Grab(group="org.apache.httpcomponents", module="httpclient", version="[4.5.3,)")
import org.apache.http.HttpHost
import org.apache.http.impl.client.HttpClients

class MyClass implements Serializable {
  static def run() {
    return HttpClients.custom()
    .setProxy(new HttpHost("proxy.example.com", 3128))
    .build()
  }

  static def debug() {
    return ("""
      this: ${this.classLoader.class.toString()} ${this.classLoader.hashCode().toString()}
      HttpHost: ${HttpHost.class.classLoader.class.toString()} ${HttpHost.class.classLoader.hashCode()}
      HttpClients: ${HttpClients.class.classLoader.class.toString()} ${HttpClients.class.classLoader.hashCode()}
    """)
  }
}
以及使用此库的Jenkins脚本化管道作业:

@Library('example') _
node {
  echo "${com.example.MyClass.debug()}"
  com.example.MyClass.run()
}
当作业运行时,我从
debug()
获得以下输出,然后是
run()
的错误:

我很清楚,一些Jenkins插件已经依赖于httpcomponents,以下情况似乎是正确的:

  • 我的
    @Grab
    注释导致下载请求的httpclient版本(如
    ~/.groovy/grapes
    中所述)
  • 但是,Groovy库并没有加载或使用该版本,而是依赖于某个Jenkins插件的其他版本
  • 而且,更令人烦恼的是,
    HttpHost
    HttpClients
    正在从不同的类加载器加载,以至于我甚至无法使用泄漏到Groovy代码的类加载器中的插件版本
  • 版本
    • 詹金斯:2.20
    插件版本
    • Groovy:2.0
    • 管道:2.5
    • 管道:Groovy:2.30
    • 管道:共享Groovy库:2.8
    有没有一种方法可以在与Jenkins插件隔离的类装入器中运行Groovy?Jenkins和Groovy共享库代码如何组织类加载器?插件拉入的类泄漏是故意的吗

    这是一个错误还是我做错了什么?我意识到我在詹金斯身上落后了好几个版本,所以这是一件值得尝试的事情


    就目前而言,除非我有幸拥有其他插件所没有的依赖项,或者幸运地与类加载器碰巧找到的任何版本兼容,否则该系统将无法使用。

    @Grab
    在库的作用域为文件夹时不起作用。只有在全局设置中配置库时,才能在库中使用
    @Grab
    。据报道,这是故意的,不是詹金斯的错误

    文件接着说:

    如果您想在这些库之前加载自己的库(例如,您想要更新版本的velocity或其他库),您可以通过在pom.xml中告诉hpi插件来配置插件以使用不同的类加载器策略


    就我个人而言,在尝试上述操作之前,我会将Jenkins(和Pipelines)升级到可用的最新版本。

    它的范围不限于文件夹;它被配置为“全局共享库”,因为这不是一个插件;没有pom.xml可用于配置pluginFirstClassloader。这个公开问题似乎与我所看到的问题非常相似,如果不是完全相同的话:你曾经在@Patrick解决过这个问题吗?我有一个类似的情况,番石榴从水里漏出来jenkins@JTT没有,从来没有找到解决办法。(目前不使用Jenkins)
      this: class org.jenkinsci.plugins.workflow.cps.CpsGroovyShell$CleanGroovyClassLoader 765101363
      HttpHost: class hudson.ClassicPluginStrategy$AntClassLoader2 804623541
      HttpClients: class hudson.ClassicPluginStrategy$AntClassLoader2 1870591909
    
    hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: org.apache.http.impl.client.HttpClientBuilder.setProxy() is applicable for argument types: (org.apache.http.HttpHost) values: [http://proxy.example.com:3128]
    Possible solutions: setProxy(org.apache.http.HttpHost)
    The following classes appear as argument class and as parameter class, but are defined by different class loader