繁体   English   中英

无法在 docker 中运行 jmeter 测试,得到 class 未找到异常

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

我正在尝试通过 docker 运行 jmeter 并且我得到一个 class 未发现异常。 maven 依赖项在那里,我可以使用命令行在本地运行它。

这是我得到的例外:

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]

正如我所说,我可以在本地运行它,但为了这张票,我将上述依赖项包含在项目 pom.xml 中:

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

我的 dockerfile 包含以下命令,它将我的 jar 复制到 lib 位置(此 jar 包含上述依赖项):

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

我是 docker 的新手,如果我在这里遗漏了一些基本的东西,我深表歉意。

编辑:

这是我的 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

下面是我如何启动 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`"

我没有经常使用 Docker,但我怀疑 Apache Commons Logging JAR 不知何故在类路径中丢失或不在。

错误java.lang.NoClassDefFoundError: Could not initialize class <SomeClassName>并不意味着找不到 class SomeClassName 这意味着 JVM 找到了 class 但在执行 static 初始化时遇到错误。 此外,仅当先前已在此 class 上执行 static 初始化失败时,才会引发此异常。 您之前可能会或可能不会在日志中看到不同的错误。

Static class DefaultAWSCredentialsProviderChain的初始化包括使用似乎在同一个 package 中的各种类的实例创建一个INSTANCE字段。 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 .

还需要对超类AWSCredentialsProviderChain进行 Static 初始化,这还包括来自 Apache Commons Logging 的记录器。

您的“依赖项”声明并不一定意味着您的Performance-1.0-SNAPSHOT.jar将包含aws-java-sdk-core-1.11.924.jar (以及它的依赖项)

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修改您的 pom.xml 以将其构建为胖(超级)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.

正如@luke-woodward 所建议的那样,问题最终不在于SomeClassName ,而是 JVM 在实例化它时出现问题。 必须解决的不同依赖项之间存在版本不匹配。 我对遇到此问题的任何人的建议是寻找SomeClassName无法实例化的根本原因。

暂无
暂无

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

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