繁体   English   中英

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

[英]How can I isolate my Jenkins pipeline Groovy shared library classloader?

我有一个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()的错误:

  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,以下似乎是正确的:

  1. 我的@Grab注释导致了httpclient的请求版本被下载(在~/.groovy/grapes观察到)。
  2. 但是,Groovy库没有加载或使用该版本,但是某些其他版本是某些Jenkins插件的依赖项。
  3. 而且,更令人讨厌的是, HttpHostHttpClients正在从不同的类加载器加载,因此我甚至无法使用泄漏到我的Groovy代码的类加载器中的插件版本。

版本

  • 詹金斯:2.20

插件版本

  • Groovy:2.0
  • 管道:2.5
  • 管道:Groovy:2.30
  • 管道:共享Groovy库:2.8

有没有办法在与Jenkins插件隔离的类加载器中运行我的Groovy? Jenkins和Groovy如何共享库代码来组织类加载器? 这种类型的泄漏是否是故意插入的?

这是一个错误还是我做错了什么? 我意识到我是詹金斯背后的几个版本,所以这是尝试的一件事。

除非我很幸运能够拥有其他插件没有的依赖关系,或者很幸运能够与类加载器碰巧找到的任何版本兼容,因此系统无法使用。

当库限定为文件夹时, @Grab不起作用。 只有在全局设置中配置库时, @Grab在库中使用@Grab 根据插件结构文档,这是故意的,而不是Jenkins的错误。

文档继续说:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM