本文介绍了我怎样才能隔离我的Jenkins管道Groovy共享库类加载器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Groovy库可作为全局共享库使用:

I have a Groovy library made available as a Global shared library:

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()}
    """)
  }
}

这个库:

@Library('example') _
node {
  echo "${com.example.MyClass.debug()}"
  com.example.MyClass.run()
}

当作业运行时,我从 debug()得到以下输出,然后从 run()

When the job is run, I get the following output from debug(), followed by an error from run():

  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

很明显,一些Jenkins插件已经依赖于httpcomponents,以下看起来是正确的:

It is clear to me that some Jenkins plugin already has a dependency on httpcomponents, and the following seem true:


  1. 我的 @Grab 注释导致请求的httpclient版本(在〜/ .groovy / grapes 中观察到)。

  2. 但是,该版本未被加载或使用Groovy库,但一些其他版本是一些Jenkins插件的依赖。

  3. 更令人讨厌的是, HttpHost HttpClients 是从不同的类加载器加载的,因此我甚至无法使用泄露到我的Groovy代码的类加载器中的插件版本。

  1. My @Grab annotation caused the requested version of httpclient to be downloaded (as observed in ~/.groovy/grapes).
  2. But, that version is not being loaded or used by the Groovy library, but some other version that is a dependency of some Jenkins plugin.
  3. And, even more annoyingly, HttpHost and HttpClients are being loaded from different classloaders such that I cannot even use the plugin's version that leaked into my Groovy code's classloader.



版本