You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker容器运行失败无法进入,UIC559消息转换镜像报错求助

UIC559消息转换Spark处理器Docker镜像运行问题及解决

问题场景

我正在构建用于UIC559消息转换的Spark处理器Docker镜像,执行命令sudo docker run -it test:v2 /bin/sh尝试进入容器时,出现以下报错:

inside file
Error: Could not find or load main class .bin.sh
Caused by: java.lang.ClassNotFoundException: /bin/sh

相关文件内容

entrypoint.sh脚本

#!/bin/bash
echo inside file
exec java -Djava.security.egd=file:/dev/./urandom -cp /opc/OPCUAClientUIC559_2.1-assembly.jar $*

完整Dockerfile

FROM openjdk:11.0.1 AS build
ARG SCALA_VERSION
ENV SCALA_VERSION ${SCALA_VERSION:-2.12.15}
ARG SBT_VERSION
ENV SBT_VERSION ${SBT_VERSION:-1.3.13}
ARG USER_ID
ENV USER_ID ${USER_ID:-9999}
ARG GROUP_ID 
ENV GROUP_ID ${GROUP_ID:-9999}
# copy the root certificate for sbt and scala package to download thorugh network 
COPY ./CIdependencies/zscaler-rootca.cer /root/zscaler-rootca.cer

# Install sbt and pass root certificate
RUN curl -fsLv --cacert /root/zscaler-rootca.cer "https://github.com/sbt/sbt/releases/download/v$SBT_VERSION/sbt-$SBT_VERSION.tgz" | tar xfz - -C /usr/share 
RUN \
  chown -R root:root /usr/share/sbt && \
  chmod -R 755 /usr/share/sbt && \
  ln -s /usr/share/sbt/bin/sbt /usr/local/bin/sbt && \
# Install Scala and pass root certificate
  curl -fsL --cacert /root/zscaler-rootca.cer "https://downloads.typesafe.com/scala/$SCALA_VERSION/scala-$SCALA_VERSION.tgz" SCALA_DIR=/usr/share/scala-$SCALA_VERSION | tar xfz - -C /usr/share && \
  mv -f /usr/share/scala-$SCALA_VERSION /usr/share/scala && \
  chown -R root:root /usr/share/scala && \
  chmod -R 755 /usr/share/scala && \
  ln -s /usr/share/scala/bin/* /usr/local/bin && \
  echo "@main def main = println(util.Properties.versionMsg)" > test.scala && \
  echo "println(util.Properties.versionMsg)" > test.scala && \
  scala -nocompdaemon test.scala && rm test.scala && \
# Install rpm for sbt-native-packager -see https://github.com/hseeberger/scala-sbt/pull/114
  echo "deb http://deb.debian.org/debian/ oldstable main contrib non-free deb http://deb.debian.org/debian/ oldstable-updates main contrib non-free" > /etc/apt/sources.list && \
  rm /etc/apt/sources.list.d/* && \
  apt-key adv --batch --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0E9840 && \
  apt-get update && apt-get install rpm -y && \
  rm -rf /var/lib/apt/lists/*  

USER root
WORKDIR /root
RUN keytool -noprompt -storepass changeit -importcert -alias zscaler -file ./zscaler-rootca.cer -keystore /etc/ssl/certs/java/cacerts

# Prepare sbt (warm cache)
RUN \
  sbt sbtVersion && \
  mkdir -p project && \
  echo "scalaVersion := \"${SCALA_VERSION}\"" > build.sbt && \
  echo "sbt.version=${SBT_VERSION}" > project/build.properties && \
  echo "// force sbt compiler-bridge download" > project/Dependencies.scala && \
  echo "case object Temp" > Temp.scala && \
  sbt compile && \
  rm -r project && rm build.sbt && rm Temp.scala && rm -r target 

CMD sbt

COPY ./ ./

RUN sbt assembly

FROM ubuntu:latest
ARG GIT_COMMIT
ARG DS_VERSION=0.0.0.0
LABEL Name=OPCUA_ClientUIC559 Version=$DS_VERSION git_commit=$GIT_COMMIT
RUN apt-get update \
    && DEBIAN_FRONTEND=noninteractive apt-get install -y -f --no-install-recommends \
        ca-certificates\
        curl\
    icu-devtools=66.1-2ubuntu2   \
        openjdk-11-jre \
    && apt-get clean           \
    && rm -rf /var/lib/apt/lists/* 

# Create a user, group and changing the ownership to access the built files as root should not be used ideally
RUN groupadd -r opc && useradd --no-log-init -r -g opc opc
RUN mkdir /opc; chown opc.opc /opc

USER opc

# Switch working directory

WORKDIR /opc

COPY --from=build --chown=opc:opc /root/entrypoint.sh /opc/entrypoint.sh

COPY --from=build --chown=opc:opc /root/target/scala-2.12.15/*.jar /opc/OPCUAClientUIC559_2.12.15-assembly.jar
RUN chmod +x /opc/entrypoint.sh
ENTRYPOINT ["bash","/opc/entrypoint.sh"]

已尝试操作

  • 确认构建带entrypoint的镜像后,容器内存在jar包
  • 在docker run命令后传递Java参数:sudo docker run -it test:v2 com.domain.uic559.opcua.OPCUAKafkaStreamUIC559

问题根源

当执行sudo docker run -it test:v2 /bin/sh时,/bin/sh会被当作参数传递给entrypoint脚本。脚本中的$*会把这个参数直接拼到java命令后,导致Java将/bin/sh误认为是要运行的主类名,从而抛出找不到主类的错误。

另外,entrypoint脚本中指定的jar包路径/opc/OPCUAClientUIC559_2.1-assembly.jar与Dockerfile中实际复制的OPCUAClientUIC559_2.12.15-assembly.jar不匹配,这也是潜在的运行问题。

解决方案

方法1:临时进入容器(无需修改镜像)

使用--entrypoint参数覆盖默认的entrypoint,直接运行shell:

sudo docker run -it --entrypoint /bin/sh test:v2

方法2:修复entrypoint脚本(长期解决)

修改entrypoint.sh脚本,增加逻辑判断:如果用户传递的参数是可执行命令(如/bin/sh),则直接执行该命令;否则执行Java程序。同时修正jar包路径:

#!/bin/bash
echo inside file

# 判断第一个参数是否为可执行命令
if command -v "$1" >/dev/null 2>&1; then
    exec "$@"
else
    # 执行Java程序,使用正确的jar包路径
    exec java -Djava.security.egd=file:/dev/./urandom -cp /opc/OPCUAClientUIC559_2.12.15-assembly.jar "$@"
fi

修改后重新构建镜像,即可实现两种场景:

  • 正常运行Java程序:sudo docker run -it test:v2 com.domain.uic559.opcua.OPCUAKafkaStreamUIC559
  • 进入容器shell:sudo docker run -it test:v2 /bin/sh

内容的提问来源于stack exchange,提问作者lakshman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 06:47:49