简体   繁体   中英

Unable to run jmeter test in docker, getting class not found exception

I am trying to run jmeter through docker and I am getting a class not found exception. The maven dependency is there and I am able to run it locally with command line.

Here is the exception I am getting:

2021-02-13 17:48:35,315 ERROR o.a.j.JMeter: Uncaught exception in thread Thread[Thread Group 1-2,5,main]
java.lang.NoClassDefFoundError: Could not initialize class com.amazonaws.auth.DefaultAWSCredentialsProviderChain
        at Utils.TestParameters.<init>(TestParameters.java:62) ~[Performance-1.0-SNAPSHOT.jar:?]
        at InitTest.InitTest(InitTest.java:96) ~[Performance-1.0-SNAPSHOT.jar:?]
        at InitTest.runTest(InitTest.java:33) ~[Performance-1.0-SNAPSHOT.jar:?]                                             at org.apache.jmeter.protocol.java.sampler.JavaSampler.sample(JavaSampler.java:197) ~[ApacheJMeter_java.jar:5.4.1]                                                                                                                              at org.apache.jmeter.threads.JMeterThread.doSampling(JMeterThread.java:635) ~[Performance-1.0-SNAPSHOT.jar:?]                                                                                                                               at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:558) ~[Performance-1.0-SNAPSHOT.jar:?]                                                                                                                     at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:489) ~[Performance-1.0-SNAPSHOT.jar:?]                                                                                                                           at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:256) ~[Performance-1.0-SNAPSHOT.jar:?]
        at java.lang.Thread.run(Thread.java:748) [?:1.8.0_282]

As I said, I am able to run this locally but for the sake of this ticket, I am including the above dependency that is in the projects pom.xml:

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-core</artifactId>
    <version>1.11.924</version>
</dependency>

My dockerfile includes the following command which copies my jar to the lib location (this jar includes the above dependency):

COPY Performance-1.0-SNAPSHOT.jar /opt/apache-jmeter-5.4.1/lib/Performance-1.0-SNAPSHOT.jar

I am new to docker so apologies if I am missing something basic here.

EDIT:

Here is my dockerfile:

FROM ubuntu:latest

# setup jmeter version to use
ARG JMETER_VERSION="5.4.1"
ARG JMETER_PLUGINS_MANAGER_VERSION="1.3"
ARG CMDRUNNER_VERSION="2.2"
ENV JMETER_HOME /opt/apache-jmeter-${JMETER_VERSION}
ENV JMETER_BIN  ${JMETER_HOME}/bin
ENV MIRROR_HOST https://archive.apache.org/dist/jmeter
ENV JMETER_DOWNLOAD_URL ${MIRROR_HOST}/binaries/apache-jmeter-${JMETER_VERSION}.tgz
ENV JMETER_PLUGINS_DOWNLOAD_URL https://repo1.maven.org/maven2/kg/apc
ENV JMETER_PLUGINS_FOLDER ${JMETER_HOME}/lib/ext/
ENV PATH $PATH:$JMETER_BIN
# Install Everything.
RUN \
  sed -i -e 's/# \(.*multiverse$\)/\1/g' /etc/apt/sources.list && \
  apt-get update && \
  apt-get install -y build-essential && \
  apt-get install -y software-properties-common && \
  apt-get install -y byobu openjdk-8-jre curl git htop man unzip vim wget python3-pip && \
  mkdir -p /tmp/dependencies &&   \
  curl -L --silent ${JMETER_DOWNLOAD_URL} >  /tmp/dependencies/apache-jmeter-${JMETER_VERSION}.tgz &&  \
  mkdir -p /opt && \
  tar -xzf /tmp/dependencies/apache-jmeter-${JMETER_VERSION}.tgz -C /opt &&  \
  rm -rf /tmp/dependencies && \
  rm -rf /var/lib/apt/lists/*
# Install jmeter lib and dependency jars
RUN curl -L --silent ${JMETER_PLUGINS_DOWNLOAD_URL}/jmeter-plugins-manager/${JMETER_PLUGINS_MANAGER_VERSION}/jmeter-plugins-manager-${JMETER_PLUGINS_MANAGER_VERSION}.jar -o ${JMETER_PLUGINS_FOLDER}/jmeter-plugins-manager-${JMETER_PLUGINS_MANAGER_VERSION}.jar
RUN curl -L --silent ${JMETER_PLUGINS_DOWNLOAD_URL}/cmdrunner/${CMDRUNNER_VERSION}/cmdrunner-${CMDRUNNER_VERSION}.jar -o ${JMETER_HOME}/lib/cmdrunner-${CMDRUNNER_VERSION}.jar && \
    java -cp ${JMETER_PLUGINS_FOLDER}/jmeter-plugins-manager-${JMETER_PLUGINS_MANAGER_VERSION}.jar org.jmeterplugins.repository.PluginManagerCMDInstaller && \
    PluginsManagerCMD.sh install jpgc-cmd=2.2,jpgc-dummy=0.4,jpgc-filterresults=2.2,jpgc-synthesis=2.2,jpgc-graphs-basic=2.0 \
    && jmeter --version \
    && PluginsManagerCMD.sh status \
RUN ln -nsf /usr/bin/pip3 /usr/bin/pip
RUN ln -nfs /usr/bin/python3 /usr/bin/python
RUN pip3 install awscli && pip3 install xmltodict

# sheel script has script to convert JTL to CSV
COPY run.sh /
COPY performance.jmx /performance.jmx
COPY Performance-1.0-SNAPSHOT.jar /opt/apache-jmeter-5.4.1/lib/Performance-1.0-SNAPSHOT.jar

# Set environment variables.
ENV HOME /root

# Final cleanup
RUN apt-get --purge autoremove
RUN ["chmod", "+x", "/run.sh"]
# Define working directory.
WORKDIR /
CMD /run.sh

Here is how I start jmeter:

echo "START Running Jmeter on `date`"

JVM_ARGS="-Xms2048m -Xmx8192m" jmeter -n -t /performance.jmx -l /jmeter.jtl 2>&1
java -jar /opt/apache-jmeter-5.4.1/lib/cmdrunner-2.2.jar --tool Reporter --plugin-type AggregateReport --input-jtl /jmeter.jtl --generate-csv /results/results.csv 2>&1
cat /results/results.csv

echo "END Running Jmeter on `date`"

I haven't worked with Docker much, but my suspicion is that the Apache Commons Logging JAR is somehow missing or not on the classpath.

The error java.lang.NoClassDefFoundError: Could not initialize class <SomeClassName> doesn't mean that the class SomeClassName couldn't be found. It means that the JVM found the class but encountered an error performing static initialization. Furthermore, this exception is only thrown if there has already been a previous failure to perform static initialization on this class. You may or may not see a different error earlier on in your logs.

Static initialization of the class DefaultAWSCredentialsProviderChain consists of creating an INSTANCE field using instances of various classes that appear to be in the same package. Of these, EC2ContainerCredentialsProviderWrapper uses an Apache Commons Logging logger, but all the rest seem to only use built-in Java classes or classes in packages under com.amazonaws .

Static initialization for the superclass AWSCredentialsProviderChain also needs to take place, and that also includes a logger from Apache Commons Logging.

Your "dependency" declaration doesn't necessarily mean that your Performance-1.0-SNAPSHOT.jar will contain aws-java-sdk-core-1.11.924.jar (as well as its dependencies)

So I would recommend checking your Performance-1.0-SNAPSHOT.jar (.jar files are normal.zip archives) and ensure that it contains all the dependencies of the AWS Java SDK your test needs and if it doesn't - you will need to amend your pom.xml to build it as a fat (uber) jar

Alternative option is using JMeter Maven Plugin inside your docker file, it will automatically download JMeter, plugins, dependencies, etc. so you won't have to do this manually.

As @luke-woodward suggested, the issue was eventually not with SomeClassName but with the JVM having an issue instantiating it. There was a version mismatch between different dependencies that had to be addressed. My suggestion to anyone who encounters this problem is to look for an underlying reason why SomeClassName cannot be instantiated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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