如何使用unmanagedBase将添加外部库的Scala项目dockerize?

soat7uwm  于 5个月前  发布在  Scala
关注(0)|答案(1)|浏览(53)

我使用opencv_480查找图像模糊,因为我使用unmanagedBasebuild.sbt中添加了opencv-480.jar作为外部库,添加jar文件后,我可以导入其库并在我的sbt-shell中成功使用。
但现在我想dockerize我的项目,因为我创建了一个我的scala项目的图像使用sbt-native-packager并编写一个docker compose它,当我做docker-compose up它通过一个错误。

scala-service_1  | Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java480 in java.library.path: [/usr/java/packages/lib, /usr/lib64, /lib64, /lib, /usr/lib]
scala-service_1  |  at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2673)
scala-service_1  |  at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:830)
scala-service_1  |  at java.base/java.lang.System.loadLibrary(System.java:1873)
scala-service_1  |  at blurriness.CheckBlurry$.isImageBlurry(CheckBlurry.scala:11)

字符串
这是我的建筑。sbt

import com.typesafe.sbt.packager.docker._

ThisBuild / version := "0.1.0-SNAPSHOT"

ThisBuild / scalaVersion := "2.13.4"

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

enablePlugins(JavaAppPackaging, DockerPlugin)

Docker / packageName := "document-identification-test"

Docker / version := "0.0.1"
dockerExposedPorts := Seq(8085)

dockerChmodType := DockerChmodType.UserGroupWriteExecute
dockerPermissionStrategy := DockerPermissionStrategy.CopyChown
dockerAdditionalPermissions += (DockerChmodType.UserGroupPlusExecute, "/var/run/")

fork := true

    val openCVNativeLibPath = file("/opencv_lib/native_libs")
unmanagedBase := baseDirectory.value / "opencv_lib"

run / javaOptions += s"-Djava.library.path=${openCVNativeLibPath.getAbsolutePath}"

Docker / daemonUserUid := None
Docker / daemonUser := "root"

dockerBaseImage := "openjdk:11"


我已经将native-libsopencv-480.jar添加到opencv_lib目录中(opencv_lib是在根级别创建的)。
这是我的主类CheckBlurry.scala

import logfactory.LogFactory.logger
import org.opencv.core.{Core, CvType, Mat, MatOfDouble}
import org.opencv.imgcodecs.Imgcodecs
import org.opencv.imgproc.Imgproc

object CheckBlurry extends App {
  def isImageBlurry(imagePath: String): Boolean = {
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME)
    val image = Imgcodecs.imread(imagePath)
    val gray = new Mat()
    Imgproc.cvtColor(image, gray, Imgproc.COLOR_BGR2GRAY)
    val laplacian = new Mat()
    Imgproc.Laplacian(gray, laplacian, CvType.CV_64F)
    val variance = new MatOfDouble()
    Core.meanStdDev(laplacian, new MatOfDouble(), variance)
    println("variance: {}", variance.get(0, 0)(0))
    val threshold = 35
    variance.get(0, 0)(0) < threshold
  }

  val isBlurry = isImageBlurry("src/main/resources/blurImage.png")
  
  if (isBlurry) {
    logger.info("Image is blurry")
  } else {
    logger.info("Image is not blurry")
  }
}


我的项目Image是(使用sbt-native-packager创建的)

document-identification-test                   0.0.1           eb7f17b525d1   3 hours ago     736MB


我的docker-compose

version: '3'
services:
  scala-service:
    image: document-identification-test:0.0.1
    ports:
      - "8085:8085"
    volumes:
      - ./opencv_lib:/opencv_lib


我是在正确的为什么还是做了一些错误的dockerizing我的项目?为什么我的项目在sbt-shell中运行,但在docker容器中抛出错误?

8cdiaqws

8cdiaqws1#

为了在docker容器中使用OpenCV-你必须首先在其中安装OpenCV。你可以使用build.sbt中的命令来完成。
首先在根目录下创建一个目录opencv 4,然后在其中粘贴两个文件libopencv_java480.soopencv-480.jar(这些文件将位于**/usr/local/share/java/opencv 4**)。
以下是更新后的build.sbt:

import com.typesafe.sbt.packager.docker._

ThisBuild / version := "0.1.0-SNAPSHOT"

ThisBuild / scalaVersion := "2.13.4"

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

enablePlugins(JavaAppPackaging, DockerPlugin)

Docker / packageName := "document-identification-test"

Docker / version := "0.0.1"
dockerExposedPorts := Seq(8085)

dockerChmodType := DockerChmodType.UserGroupWriteExecute
dockerPermissionStrategy := DockerPermissionStrategy.CopyChown
dockerAdditionalPermissions += (DockerChmodType.UserGroupPlusExecute, "/var/run/")

fork := true

Universal / javaOptions += "-Djava.library.path=/opencv4"

Docker / daemonUserUid := None
Docker / daemonUser := "root"

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

dockerCommands ++= Seq(
  Cmd("RUN", "apk", "add", "--no-cache", "bash make cmake g++ wget unzip"),
  Cmd("RUN", "apk", "add", "--no-cache", "linux-headers"),
  Cmd("RUN", "wget", "-O", "opencv.zip", "https://github.com/opencv/opencv/archive/4.8.0.zip"),
  Cmd("RUN", "unzip", "opencv.zip && rm opencv.zip"),
  Cmd("RUN", "mkdir", "-p", "build && cd build && cmake ../opencv-4.8.0 && make -j4 && make install")
)

字符串
下面是Docker compose:

version: "3"

services:
  testservice:
    image: document-identification-test:0.0.1
    container_name: document-verification
    volumes:
      - ./src/main/resources:/src/main/resources
      - ./opencv4:/opencv4
    ports:
      - "8085:8085"
    networks:
      - verification-network

networks:
  verification-network:
    driver: bridge

相关问题