为Jenkins共享库配置私有Nexus作为Maven源的问题及解决
问题背景
之前我的Jenkins共享库pom.xml中仅使用Maven中央仓库的公开Java依赖,现在需要引入部署在内部私有Nexus的Java库时,出现如下报错:
unable to resolve class com.somecompany.SomeClass
出于安全考虑,我希望完全弃用Maven中央仓库,使用内部Nexus作为统一镜像源。普通流水线执行mvn命令时可以通过settings.xml配置仓库,我想知道共享库场景下如何实现相同配置。
更新1:补充相关配置
共享库内Groovy类代码
import com.somecompany.collections.secret.vault.VaultClient Map getSecrets() { VaultClient client = new VaultClient() Map test = client.getAllSecrets() return test }
对应pom.xml配置
<dependencies> <dependency> <groupId>com.somecompany</groupId> <artifactId>vault-secret-management</artifactId> <version>${vault.secret.management}</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk-ecr</artifactId> </dependency> </dependencies>
流水线代码
@GrabResolver(name='restlet', root='https://nexus.us.somecompany.com/repository/asa-coll-release-maven-hosted/') @Grab(group='com.somecomapny', module='vault-secret-management', version='1.0.20') @Library('jenkins-libraries@feature/DM-27548-try-to-use-vault-client-in-shared-library') String projectName = '6562_GL_CYBERFINANCIAL_IIT_IAC' pipeline { agent { label 'ecs-node' } environment { VAULT_ADDR = 'https://vault.uat.use1.crypto.aws.efx/' VAULT_NAMESPACE = 'intl-collections/dev-use1' VAULT_SECRETS_PATH = 'kv-admin-console/admin-console' VAULT_MAX_RETRIES = 3 VAULT_RETRY_INTERVAL = 10 VAULT_ROLE = 'efx-cloud-ec2-developer-provisioner-role' } stages { stage('Hello') { steps { script { def secret = vaultHelper.getSecrets() println("result: "+secret) } } } } }
运行报错信息
14:46:30 [Pipeline] // node 14:46:30 [Pipeline] End of Pipeline 14:46:30 org.jenkinsci.plugins.workflow.cps.CpsCompilationErrorsException: startup failed: 14:46:30 /mnt/jenkins-ebs/jenkins/jobs/cxs349-test-vault/builds/13/libs/jenkins-libraries/vars/vaultHelper.groovy: 1: unable to resolve class com.equifax.collections.secret.vault.VaultClient 14:46:30 @ line 1, column 1. 14:46:30 import com.equifax.collections.secret.vault.VaultClient 14:46:30 ^ 14:46:30 14:46:30 1 error at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310) at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:958) at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:605) at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:554) at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298) at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268) at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:254) at groovy.lang.GroovyClassLoader.recompile(GroovyClassLoader.java:761) at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:718) at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:787) at java.lang.ClassLoader.loadClass(ClassLoader.java:405) at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell$TimingLoader.loadClass(CpsGroovyShell.java:170) at java.lang.ClassLoader.loadClass(ClassLoader.java:405) at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:677) at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:787) at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:775) at org.jenkinsci.plugins.workflow.cps.global.UserDefinedGlobalVariable.getValue(UserDefinedGlobalVariable.java:57) at org.jenkinsci.plugins.workflow.cps.CpsScript.getProperty(CpsScript.java:135) at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:174) at groovy.lang.Closure.getPropertyTryThese(Closure.java:312) at groovy.lang.Closure.getPropertyDelegateFirst(Closure.java:302) at groovy.lang.Closure.getProperty(Closure.java:287) at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:174) at groovy.lang.Closure.getPropertyTryThese(Closure.java:312) at groovy.lang.Closure.getPropertyOwnerFirst(Closure.java:306) at groovy.lang.Closure.getProperty(Closure.java:295) at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:174) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:456) at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.getProperty(DefaultInvoker.java:39) at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20) at WorkflowScript.run(WorkflowScript:29) at ___cps.transform___(Native Method) at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.get(PropertyishBlock.java:74) at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30) at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.fixName(PropertyishBlock.java:66) at sun.reflect.GeneratedMethodAccessor202.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72) at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21) at com.cloudbees.groovy.cps.Next.step(Next.java:83) at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:174) at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:163) at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:129) at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:268) at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163) at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:185) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:402) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$400(CpsThreadGroup.java:96) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:314) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:278) at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:67) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:136) at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28) at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:59) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) 14:46:30 Finished: FAILURE
更新2:问题已解决
报错原因是@GrabResolver和@Grab注解的作用域只覆盖当前代码文件,之前把注解写在流水线代码中,共享库加载时无法识别到私有仓库配置,因此找不到对应类。
将两个注解从Jenkins流水线移到共享库内部的Groovy代码中即可解决问题,修改后的共享库代码如下:
import com.equifax.collections.secret.vault.VaultClient @groovy.lang.GrabResolver(name='restlet', root='https://nexus.us.equifax.com/repository/asa-coll-release-maven-hosted/') @groovy.lang.Grab(group='com.equifax', module='vault-secret-management', version='1.0.20') Map getSecrets() { VaultClient client = VaultClient.getInstance(); Map test = client.getAllSecrets() return test }
如果需要全局配置所有共享库都走内部Nexus、禁用公共Maven仓库,可以在Jenkins控制器的Groovy全局配置中添加统一的GrabResolver规则,无需每个共享库单独配置注解。
内容的提问来源于stack exchange,提问作者carlitos081
相关产品推荐
相关产品推荐

