无法通过Grab添加外部库的可选依赖项

问题描述 投票:1回答:2

无法在Jenkins的共享库中正确使用具有可选依赖项的外部第三方库。

我有一个共享库,该共享库使用Commons Configurations 2读取varios配置文件,这些文件大多写为YAML文档。

通用配置使用SnakeYAML读取YAML文档,并且对SnakeYAML的依赖关系定义为可选,如下所示:

 <dependency>
      <groupId>org.yaml</groupId>
      <artifactId>snakeyaml</artifactId>
      <version>1.26</version>
      <optional>true</optional>
 </dependency>      

根据documentation of Maven how optional dependencies work,默认情况下未将可选依赖项添加到类路径。如果某人想要依赖于可选依赖项的库部分,则必须将此依赖项添加到他自己的POM中。

当我要与SnakeYAML一起使用Commons Configuration 2时,我在vars/readConfig.groovy中定义了以下变量,如下所示:

@Grapes([
  @Grab(group = "org.apache.commons", module = "commons-configuration2", version = "2.7"),
  @Grab(group = "org.yaml", module = "snakeyaml", version = "1.26")
])
import org.apache.commons.configuration2.BaseConfiguration
import org.apache.commons.configuration2.Configuration
import org.apache.commons.configuration2.YAMLConfiguration

def call() {
    Configuration config = new BaseConfiguration();
    YAMLConfiguration yamlConfiguration = new YAMLConfiguration();  
}

从共享库中调用readConfig()会导致java.lang.ClassNotFoundException并显示以下消息

java.lang.ClassNotFoundException: org.yaml.snakeyaml.DumperOptions
    at jenkins.util.AntClassLoader.findClassInComponents(AntClassLoader.java:1387)
    at jenkins.util.AntClassLoader.findClass(AntClassLoader.java:1342)
    at jenkins.util.AntClassLoader.loadClass(AntClassLoader.java:1089)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:352)
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
    at java.lang.Class.privateGetPublicMethods(Class.java:2902)
    at java.lang.Class.getMethods(Class.java:1615)
    at java.beans.Introspector.getPublicDeclaredMethods(Introspector.java:1336)
    at java.beans.Introspector.getTargetMethodInfo(Introspector.java:1197)
    at java.beans.Introspector.getBeanInfo(Introspector.java:426)
    at java.beans.Introspector.getBeanInfo(Introspector.java:173)
    at groovy.lang.MetaClassImpl$15.run(MetaClassImpl.java:3313)
    at java.security.AccessController.doPrivileged(Native Method)
    at groovy.lang.MetaClassImpl.addProperties(MetaClassImpl.java:3311)
    at groovy.lang.MetaClassImpl.initialize(MetaClassImpl.java:3288)
    at org.codehaus.groovy.reflection.ClassInfo.getMetaClassUnderLock(ClassInfo.java:260)
    at org.codehaus.groovy.reflection.ClassInfo.getMetaClass(ClassInfo.java:302)
    ...

我还检查了目录~/.groovy/grapes中是否存在所有需要的jar,它们都在其中。

jenkins@cb765137c926:~/.groovy$ find . -name "*.jar"
./grapes/commons-logging/commons-logging/jars/commons-logging-1.2.jar
./grapes/org.apache.commons/commons-configuration2/jars/commons-configuration2-2.7.jar
./grapes/org.apache.commons/commons-lang3/jars/commons-lang3-3.9.jar
./grapes/org.apache.commons/commons-text/jars/commons-text-1.8.jar
./grapes/org.yaml/snakeyaml/jars/snakeyaml-1.26.jar

为了进行交叉检查,我编写了以下Groovy脚本,并能够在我的计算机上成功执行它。

@Grapes([
  @Grab(group = 'org.apache.commons', module = 'commons-configuration2', version = '2.7'),
  @Grab(group = 'org.yaml', module = 'snakeyaml', version = '1.26'),
  @GrabConfig(systemClassLoader = true)
])

import org.apache.commons.configuration2.*

println("Start")

YAMLConfiguration y = new YAMLConfiguration()

println y

所以,由于我不太了解Jenkins的内部原理,所以我无法猜测出此问题的原因。但是,很高兴知道是否有一种方法可以使它按预期工作。

jenkins groovy ivy jenkins-groovy jenkins-shared-libraries
2个回答
1
投票

抢劫是建立在常春藤上。我们在Ivy配置中获取可选依赖项的方法是将optional添加到注释的元素conf

@Grab(group='org.apache.commons', module='commons-configuration2', 
      version='2.7', conf='default,optional')

0
投票

@Grab在沙盒中不起作用,因此,这仅在全局配置中定义的共享库中起作用。即使这样做,由于Jenkins为您的脚本创建运行环境的方式,您还是很可能会遇到类加载问题。

出于这种原因,出于性能考虑,@Grab。当您开始工作时,此代码将执行的工作是,在该主服务器上每次构建的开始时,通过Internet下载这些依赖项,以阻止调用。如果网络速度很慢,您可以通过这种方式很快耗尽执行程序。

最佳实践是安装Pipeline Utility Steps Plugin,它提供了readYaml方法。它仅基于SnakeYaml来源,其作用相同。

© www.soinside.com 2019 - 2024. All rights reserved.