Breeze矩阵向量乘法输出JDK版本的原因及解决方法
问题描述
使用OpenJDK 11 + SBT 1.8.0编写基于Breeze库的Scala矩阵向量乘法代码,运行时会输出return java 11 instance;切换其他JDK版本运行时,依然输出构建时所用的JDK版本信息。
代码示例
Main.scala
import breeze.linalg.{DenseMatrix, DenseVector} object Main extends App { val X = DenseMatrix((1.0, 0.0), (1.0, 1.0), (1.0, 2.0), (1.0, 3.0)) val Y = DenseVector(0.0, 1.0) X * Y }
build.sbt
ThisBuild / version := "0.1.0-SNAPSHOT" ThisBuild / scalaVersion := "2.13.10" libraryDependencies ++= Seq( "org.scalanlp" %% "breeze" % "2.1.0" )
原因解析
- 日志输出来源:该输出来自Breeze依赖的
netlib-java库——这个库在初始化底层线性代数运算实现(如BLAS/LAPACK)时,若无法找到优化的本地库(如OpenBLAS),会回退到纯Java实现,同时默认打印当前JVM版本信息。 - 版本固化问题:“总是输出构建时JDK版本”是因为SBT默认会使用启动自身的JVM来运行程序,哪怕你切换了系统全局JDK,只要SBT进程未重启并重新绑定新JDK,运行程序时就会沿用原JVM环境。
解决方法
1. 屏蔽netlib-java的日志输出
添加日志框架依赖并配置日志级别,关闭调试级别的输出:
修改build.sbt,新增SLF4J依赖:
libraryDependencies ++= Seq( "org.scalanlp" %% "breeze" % "2.1.0", "org.slf4j" % "slf4j-simple" % "2.0.7" )
在src/main/resources目录下创建simplelogger.properties文件,写入配置:
org.slf4j.simpleLogger.defaultLogLevel=warn org.slf4j.simpleLogger.log.com.github.fommil.netlib=error
2. 强制运行时使用指定JDK
方式一:启动SBT时指定JDK
通过环境变量绑定目标JDK后启动SBT:
# Linux/macOS JAVA_HOME=/path/to/target-jdk ./sbt run # Windows set JAVA_HOME=C:\path\to\target-jdk sbt run
方式二:在SBT配置中指定运行时JDK
在build.sbt中添加JVM路径配置:
run / javaHome := Some(file("/path/to/target-jdk"))
替换路径为你实际的目标JDK目录即可。
内容的提问来源于stack exchange,提问作者envy grunt
相关产品推荐
相关产品推荐

