我正在try 停靠我的Scala应用程序--在其中我使用Scalapy运行了Python代码.我的Scala版本(2.13.1)、SBT版本(1.2.8).

Main Class in Scala:

import me.shadaj.scalapy.interpreter.CPythonInterpreter
import me.shadaj.scalapy.py

object Main extends App {
  val pythonCode =
    """
      |import os
      |
      |myFile = os.path.join("src", "main", "resources", "myFile.txt")
      |
      |with open(myFile, "w") as file:
      |    file.write("Hello World!")
      |""".stripMargin

  py.local {
    CPythonInterpreter.execManyLines(pythonCode)
  }
}

我在project/plugins.sbt中添加了一个LibraryDependency:

libraryDependencies += "ai.kien" %% "python-native-libs" % "0.2.2"

这是我的建筑.

import com.typesafe.sbt.packager.docker.{DockerChmodType, DockerPermissionStrategy, ExecCmd}
import ai.kien.python.Python

lazy val root = (project in file("."))
  .settings(
    name := "my-project"
  )

ThisBuild / version := "0.1.0-SNAPSHOT"

ThisBuild / scalaVersion := "2.13.1"

ThisBuild / scapegoatVersion := "1.4.0"

enablePlugins(JavaAppPackaging, DockerPlugin)
packageName in Docker:= "my-project"

version in Docker:= "0.0.3"
dockerExposedPorts:= Seq(8083)

dockerChmodType := DockerChmodType.UserGroupWriteExecute
dockerPermissionStrategy := DockerPermissionStrategy.CopyChown
dockerAdditionalPermissions += (DockerChmodType.UserGroupPlusExecute, "/var/run/")
daemonUserUid in Docker := None
daemonUser in Docker    := "root"

dockerCommands ++= Seq(
  ExecCmd("RUN", "apt-get", "update"),
  ExecCmd("RUN", "apt-get", "install", "-y", "python3")
)

fork:= true

lazy val python = Python("/usr/bin/python3")

lazy val javaOpts = python.scalapyProperties.get.map {
  case (k, v) => s"""-D$k=$v"""
}.toSeq

javaOptions ++= javaOpts

libraryDependencies ++= Seq(
  "me.shadaj" %% "scalapy-core" % "0.5.2"
)

现在,如果我用SBT-SHELL在IntelliJ IDEA中运行它,程序运行得很好-但如果我用Run按钮运行,它会给出:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'python3':
libpython3.so: cannot open shared object file: No such file or directory
libpython3.so: cannot open shared object file: No such file or directory
Native library (linux-x86-64/libpython3.so) not found in resource path (/home/zaryab/IdeaProjects/My_Project/target/scala-2.13/classes:/home/zaryab/.ivy2/cache/aopalliance/aopalliance/jars/aopalliance-1.0.jar)

在这一点上,它很好,因为它与SBT-Shell一起工作.但现在我想把它对接起来.为此,我在Build.sbt中添加了一些Docker命令--并且我正在使用sbt-ative-Packager制作我的应用程序映像.

由SBT-Native-Packager自动创建的DockerFile:

FROM openjdk:8
WORKDIR /opt/docker
COPY --chown=root:root opt /opt
EXPOSE 8083
USER root
ENTRYPOINT ["/opt/docker/bin/notary-scraping"]
CMD []
RUN ["apt-get", "update"]
RUN ["apt-get", "install", "-y", "python3"]

但当我运行此图像的容器时,它给出的错误与我使用运行按钮运行时得到的错误相同.

我已经运行了不同的命令来判断‘python3’是否在容器中:

First I run 'docker exec -it my_container /bin/bash'

Then 'which python3' - it prints '/usr/bin/python3'

Python3在容器中,但仍为‘unable to load python3’.我现在应该怎么做才能正确地将它停靠在 docker 上?

推荐答案

您使用的是已经安装了python3的基本映像openjdk:8,因此它将在自己的安装中查找libpython3,而不是您在Build.sbt("/usr/bin/python3")中给出的路径.

现在,您需要做的是更改基本映像,如amazoncorretto:11-alpine3.18-jdk,然后通过命令安装python3和其他所需的模块.

您的构建.sbt将如下所示.

import com.typesafe.sbt.packager.docker.{DockerChmodType, DockerPermissionStrategy, ExecCmd}
import ai.kien.python.Python

lazy val root = (project in file("."))
  .settings(
    name := "my-project"
  )

ThisBuild / version := "0.1.0-SNAPSHOT"

ThisBuild / scalaVersion := "2.13.1"

ThisBuild / scapegoatVersion := "1.4.0"

enablePlugins(JavaAppPackaging, DockerPlugin)
packageName in Docker:= "my-project"

version in Docker:= "0.0.3"
dockerExposedPorts:= Seq(8083)

dockerChmodType := DockerChmodType.UserGroupWriteExecute
dockerPermissionStrategy := DockerPermissionStrategy.CopyChown
dockerAdditionalPermissions += (DockerChmodType.UserGroupPlusExecute, "/var/run/")
daemonUserUid in Docker := None
daemonUser in Docker    := "root"

dockerBaseImage := "amazoncorretto:11-alpine3.18-jdk"

dockerCommands ++= Seq(
  ExecCmd("RUN", "apt-get", "update"),
  ExecCmd("RUN", "apt-get", "install", "-y", "python3")
)

fork:= true

lazy val python = Python("/usr/bin/python3")

lazy val javaOpts = python.scalapyProperties.get.map {
  case (k, v) => s"""-D$k=$v"""
}.toSeq

javaOptions ++= javaOpts

libraryDependencies ++= Seq(
  "me.shadaj" %% "scalapy-core" % "0.5.2"
)


dockerCommands ++= Seq(
  ExecCmd("RUN", "apk", "add", "--no-cache", "bash"),
  ExecCmd("RUN", "apk", "add", "--no-cache", "python3"),
  ExecCmd("RUN", "apk", "add", "--no-cache", "py3-pip")
//other modules if required
)

此外,您还需要在python代码中指定路径is(以"/"开头),

  |myFile = os.path.join("/src/main/resources", "myFile.txt")

这对你应该很管用.

Python相关问答推荐

numba jitClass,记录类型为字符串

如何根据参数推断对象的返回类型?

将图像拖到另一个图像

NumPy中条件嵌套for循环的向量化

计算分布的标准差

基于行条件计算(pandas)

如何使用使用来自其他列的值的公式更新一个rabrame列?

循环浏览每个客户记录,以获取他们来自的第一个/最后一个渠道

当条件满足时停止ODE集成?

Flask运行时无法在Python中打印到控制台

使用类型提示进行类型转换

将CSS链接到HTML文件的问题

使用SeleniumBase保存和加载Cookie时出现问题

删除特定列后的所有列

如何编辑此代码,使其从多个EXCEL文件的特定工作表中提取数据以显示在单独的文件中

对数据帧进行分组,并按组间等概率抽样n行

在不中断格式的情况下在文件的特定部分插入XML标签

迭代工具组合不会输出大于3的序列

为什么这个正则表达式没有捕获最后一次输入?

如何将ManyToManyfield用于Self类