kubernetes-client
kubernetes-client copied to clipboard
No httpclient implementations found on the context classloader in Groovy 3.0.11 in JMeter 5.5
Describe the bug
Below is my code where I am trying to get the list of pods from the default namespace in Groovy 3.0.11 in JMeter 5.5.
But it is throwing the No httpclient implementations found on the context classloader, please ensure your classpath includes an implementation jar error. Please see the below error for more details.
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Grab(group='io.fabric8', module='kubernetes-client', version='6.0.0-RC1')
@Grab(group='io.fabric8', module='knative-client', version='6.0.0-RC1')
@Grab(group='io.fabric8', module='kubernetes-client-api', version='6.0.0-RC1')
@Grab(group='org.slf4j', module='slf4j-api', version='2.0.0-alpha7')
Logger logger = LoggerFactory.getLogger(this.class);
KubernetesClient k8s = new KubernetesClientBuilder().build()
k8s.pods().inNamespace("default").list().getItems()
.forEach(pod ->
println pod.getMetadata().getName()
)
Error
javax.script.ScriptException: io.fabric8.kubernetes.client.KubernetesClientException: An error has occurred.
javax.script.ScriptException: io.fabric8.kubernetes.client.KubernetesClientException: An error has occurred.
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:320) ~[groovy-jsr223-3.0.11.jar:3.0.11]
at org.codehaus.groovy.jsr223.GroovyCompiledScript.eval(GroovyCompiledScript.java:71) ~[groovy-jsr223-3.0.11.jar:3.0.11]
at javax.script.CompiledScript.eval(CompiledScript.java:93) ~[java.scripting:?]
at org.apache.jmeter.util.JSR223TestElement.processFileOrScript(JSR223TestElement.java:217) ~[ApacheJMeter_core.jar:5.5]
at org.apache.jmeter.protocol.java.sampler.JSR223Sampler.sample(JSR223Sampler.java:72) ~[ApacheJMeter_java.jar:5.5]
at org.apache.jmeter.threads.JMeterThread.doSampling(JMeterThread.java:651) ~[ApacheJMeter_core.jar:5.5]
at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:570) ~[ApacheJMeter_core.jar:5.5]
at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:501) ~[ApacheJMeter_core.jar:5.5]
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:268) ~[ApacheJMeter_core.jar:5.5]
at java.lang.Thread.run(Thread.java:833) ~[?:?]
Caused by: io.fabric8.kubernetes.client.KubernetesClientException: An error has occurred.
at io.fabric8.kubernetes.client.KubernetesClientException.launderThrowable(KubernetesClientException.java:103) ~[?:?]
at io.fabric8.kubernetes.client.KubernetesClientException.launderThrowable(KubernetesClientException.java:97) ~[?:?]
at io.fabric8.kubernetes.client.KubernetesClientBuilder.build(KubernetesClientBuilder.java:76) ~[?:?]
at io.fabric8.kubernetes.client.KubernetesClientBuilder$build.call(Unknown Source) ~[?:?]
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47) ~[groovy-3.0.11.jar:3.0.11]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) ~[groovy-3.0.11.jar:3.0.11]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130) ~[groovy-3.0.11.jar:3.0.11]
at Script7.run(Script7.groovy:13) ~[?:?]
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:317) ~[groovy-jsr223-3.0.11.jar:3.0.11]
... 9 more
Caused by: java.lang.reflect.InvocationTargetException
at jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:79) ~[?:?]
at java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) ~[?:?]
at java.lang.reflect.Constructor.newInstance(Constructor.java:483) ~[?:?]
at io.fabric8.kubernetes.client.KubernetesClientBuilder.build(KubernetesClientBuilder.java:69) ~[?:?]
at io.fabric8.kubernetes.client.KubernetesClientBuilder$build.call(Unknown Source) ~[?:?]
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47) ~[groovy-3.0.11.jar:3.0.11]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) ~[groovy-3.0.11.jar:3.0.11]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130) ~[groovy-3.0.11.jar:3.0.11]
at Script7.run(Script7.groovy:13) ~[?:?]
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:317) ~[groovy-jsr223-3.0.11.jar:3.0.11]
... 9 more
Caused by: io.fabric8.kubernetes.client.KubernetesClientException: No httpclient implementations found on the context classloader, please ensure your classpath includes an implementation jar
at io.fabric8.kubernetes.client.utils.HttpClientUtils.createHttpClient(HttpClientUtils.java:171) ~[?:?]
at io.fabric8.kubernetes.client.DefaultKubernetesClient.<init>(DefaultKubernetesClient.java:153) ~[?:?]
at jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:67) ~[?:?]
at java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) ~[?:?]
at java.lang.reflect.Constructor.newInstance(Constructor.java:483) ~[?:?]
at io.fabric8.kubernetes.client.KubernetesClientBuilder.build(KubernetesClientBuilder.java:69) ~[?:?]
at io.fabric8.kubernetes.client.KubernetesClientBuilder$build.call(Unknown Source) ~[?:?]
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47) ~[groovy-3.0.11.jar:3.0.11]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) ~[groovy-3.0.11.jar:3.0.11]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130) ~[groovy-3.0.11.jar:3.0.11]
at Script7.run(Script7.groovy:13) ~[?:?]
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:317) ~[groovy-jsr223-3.0.11.jar:3.0.11]
... 9 more
Fabric8 Kubernetes Client version
6.0.0-RC1
Steps to reproduce
- import the fabric8 directives
- Execute the above code in JMeter 5.5, which has Groovy 3.0.11
- Exceptions can be seen.
Expected behavior
No errors.
Runtime
Kubernetes (vanilla)
Kubernetes API Server version
other (please specify in additional context)
Environment
Windows, Linux, other (please specify in additional context)
Fabric8 Kubernetes Client Logs
No response
Additional context
- tried in 5.12.2 as well, same issue
It seems like JMeter's Groovy engine is not loading the kubernetes-client module. Could you try removing the kubernetes-client-api dependency?
@manusa removing kubernetes-client-api throwing the below error.
2022-07-05 10:06:13,726 ERROR o.a.j.p.j.s.JSR223Sampler: Problem in JSR223 script JSR223 Sampler, message: javax.script.ScriptException: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script5.groovy: 1: unable to resolve class io.fabric8.kubernetes.client.KubernetesClient
@ line 1, column 1.
import io.fabric8.kubernetes.client.KubernetesClient;
^
Script5.groovy: 2: unable to resolve class io.fabric8.kubernetes.client.KubernetesClientBuilder
@ line 2, column 1.
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
^
2 errors
javax.script.ScriptException: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script5.groovy: 1: unable to resolve class io.fabric8.kubernetes.client.KubernetesClient
@ line 1, column 1.
import io.fabric8.kubernetes.client.KubernetesClient;
^
Script5.groovy: 2: unable to resolve class io.fabric8.kubernetes.client.KubernetesClientBuilder
@ line 2, column 1.
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
^
2 errors
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.compile(GroovyScriptEngineImpl.java:183) ~[groovy-jsr223-3.0.11.jar:3.0.11]
at org.apache.jmeter.util.JSR223TestElement.processFileOrScript(JSR223TestElement.java:211) ~[ApacheJMeter_core.jar:5.5]
at org.apache.jmeter.protocol.java.sampler.JSR223Sampler.sample(JSR223Sampler.java:72) ~[ApacheJMeter_java.jar:5.5]
at org.apache.jmeter.threads.JMeterThread.doSampling(JMeterThread.java:651) ~[ApacheJMeter_core.jar:5.5]
at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:570) ~[ApacheJMeter_core.jar:5.5]
at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:501) ~[ApacheJMeter_core.jar:5.5]
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:268) ~[ApacheJMeter_core.jar:5.5]
at java.lang.Thread.run(Thread.java:829) ~[?:?]
Caused by: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script5.groovy: 1: unable to resolve class io.fabric8.kubernetes.client.KubernetesClient
@ line 1, column 1.
import io.fabric8.kubernetes.client.KubernetesClient;
^
Script5.groovy: 2: unable to resolve class io.fabric8.kubernetes.client.KubernetesClientBuilder
@ line 2, column 1.
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
^
2 errors
at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:292) ~[groovy-3.0.11.jar:3.0.11]
at org.codehaus.groovy.control.CompilationUnit$ISourceUnitOperation.doPhaseOperation(CompilationUnit.java:914) ~[groovy-3.0.11.jar:3.0.11]
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:627) ~[groovy-3.0.11.jar:3.0.11]
at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:389) ~[groovy-3.0.11.jar:3.0.11]
at groovy.lang.GroovyClassLoader.lambda$parseClass$3(GroovyClassLoader.java:332) ~[groovy-3.0.11.jar:3.0.11]
at org.codehaus.groovy.runtime.memoize.StampedCommonCache.compute(StampedCommonCache.java:163) ~[groovy-3.0.11.jar:3.0.11]
at org.codehaus.groovy.runtime.memoize.StampedCommonCache.getAndPut(StampedCommonCache.java:154) ~[groovy-3.0.11.jar:3.0.11]
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:330) ~[groovy-3.0.11.jar:3.0.11]
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:314) ~[groovy-3.0.11.jar:3.0.11]
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:257) ~[groovy-3.0.11.jar:3.0.11]
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.getScriptClass(GroovyScriptEngineImpl.java:336) ~[groovy-jsr223-3.0.11.jar:3.0.11]
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.compile(GroovyScriptEngineImpl.java:181) ~[groovy-jsr223-3.0.11.jar:3.0.11]
... 7 more
@manusa I was able to fix it by adding all the fabric8 jars in one folder and associate it with JMeter. Not sure, why Grab is not working :(
Grab is downloading all the jars and keep it in the home directory, but somehow Groovy is not loading them.
I will try to reproduce. It seems that it's skipping the kubernetes-client module for some reason.
Since there's no explicit class loading in your script (which is how it should be) for any of its provided classes, this might be causing some issues.
With a quick glimpse at the code I am seeing that we are not consistent with the way we are loading classes and services (spi).
The safest approach IMHO is to always follow the chain:
- Load class / service with no class loader reference.
- Fall back to the current class class loader
- Fall back to TCCL
This used to be encapsulated in the logic of Adapters and should be used as a reference. Note, that in the current impl of Adapters (1) has been completely removed (2) which I think in some edge cases it may be problematic.
^^^ @shawkins
With a quick glimpse at the code I am seeing that we are not consistent with the way we are loading classes and services (spi).
But do you think this is related to this error?
https://github.com/fabric8io/kubernetes-client/issues/4248#issuecomment-1175104075 seems to highlight that for some reason Groovy is not loading the kubernetes-client module or its transitive dependencies.
The GroovyScriptEngine is using it's own class loader. I would assume that dependencies are loaded through that class loader. Java SPI on the other hand most probably is not using that class loader, so falling back to TCL or the class loader that loaded the KubernetesClient.class most probably would sovle this.
In other words, yeah I think that the issue will be solved by leveraging TCL / current class classloader.
so falling back to TCL or the class loader that loaded the KubernetesClient.class most probably would sovle this.
The code already uses the TCCL: https://github.com/fabric8io/kubernetes-client/blob/10e9f188911ef00e66d3b5731e073ccc6d38f8da/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/HttpClientUtils.java#L157
See https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html#load-java.lang.Class- that clarifies that 1 and 3 on your list are the same.
As for falling back to 2, the class loader of the current class, generally that means the application has mishandled the TCCL - in this case if groovy / jmeter is doing something odd that is plausible, but we should first ensure that the http dependency is present.
See https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html#load-java.lang.Class- that clarifies that 1 and 3 on your list are the same.
touché
Then maybe the issue is that the TCL is not set ? Or not being set to something that has not visibility to the class. In this case using (2) could solve the issue.
As for falling back to 2, the class loader of the current class, generally that means the application has mishandled the TCCL - in this case if groovy / jmeter is doing something odd that is plausible, but we should first ensure that the http dependency is present.
Let's do that. But do you really feel that @Grab is not bringing in transitives?
But do you really feel that
@Grabis not bringing in transitives?
Yes, that is what I'd infer from: https://github.com/fabric8io/kubernetes-client/issues/4248#issuecomment-1175104075
There he should be grapping kubernetes-client but classes from kubernetes-client-api aren't loading - that implies it's not grabbing transitive dependencies.
I'm testing this with Groovy (4.0.3 ), and it works for me.
Tested Script:
@Grab(group='io.fabric8', module='kubernetes-client', version='6.0.0-RC1')
@Grab(group='io.fabric8', module='kubernetes-client-api', version='6.0.0-RC1')
import io.fabric8.kubernetes.client.KubernetesClient
import io.fabric8.kubernetes.client.KubernetesClientBuilder
try (KubernetesClient client = new KubernetesClientBuilder().build()) {
client.pods().inNamespace("default").list().getItems()
.forEach(pod ->
println pod.getMetadata().getName()
)
}
The same script on JMeter fails. However, note that JMeter is using Groovy 3.0.11. I'm not sure if the classloader issues are caused by the groovy engine or JMeter itself when invoking the scripts.
This issue has been automatically marked as stale because it has not had any activity since 90 days. It will be closed if no further activity occurs within 7 days. Thank you for your contributions!
facing the same issue with gradle:
io.fabric8.kubernetes.client.KubernetesClientException: No httpclient implementations found on the context classloader, please ensure your classpath includes an implementation jar
at io.fabric8.kubernetes.client.utils.HttpClientUtils.getHttpClientFactory(HttpClientUtils.java:164)
at io.fabric8.kubernetes.client.KubernetesClientBuilder.build(KubernetesClientBuilder.java:76)
at com.metalbear.mirrord.KubeDataProvider.<init>(KubeDataProvider.kt:8)
at com.metalbear.mirrord.MirrordListener.processStartScheduled$lambda-3(MirrordListener.kt:43)
at com.intellij.openapi.application.TransactionGuardImpl.runWithWritingAllowed(TransactionGuardImpl.java:209)
at com.intellij.openapi.application.TransactionGuardImpl.access$100(TransactionGuardImpl.java:21)
at ...
just added the dependency like so:
dependencies {
implementation("com.github.zafarkhaja:java-semver:0.9.0")
implementation("io.fabric8:kubernetes-client:6.2.0") {
exclude(group = "org.slf4j", module = "slf4j-api")
}
}
Would really appreciate any solutions, thanks
should be addressed by #4689
I'm closing the issue as complete, as the fix should be available and functional since the last release https://github.com/fabric8io/kubernetes-client/releases/tag/v6.4.0
Please, feel free to open a new issue in case the problem persists. It would also be great if any of the affected users could provide feedback and confirm that the fix is working.
I still see this issue in a very basic test app using the latest 6.4.0 JARS. See attached screengrab from Intelij. All JARs are downloaded locally and placed in a libs folder.

Hi @oreillymj This is not any of the scenarios mentioned in the issue (Gradle or JMeter). If you add any of the kubernetes-httpclient-xxx.jar files and place it in your classpath, it should work.
I recreated the project with Maven, and see it pulls in a bunch more dependencies. I needed okhttp3, okio, logging intercepter + more. Somehow when building with downloaded JAR's, I wasn't getting NoClassDef errors at run time (in the Intelij IDE), so it's difficult to figure out what I was missing.