java - 如何在不遇到 SecurityException 的情况下从 Scala 脚本引用 java.sql?

标签 java scala jdbc sbt java-9

从 Java 9 开始,当直接从 Scala 脚本使用时,从 Scala 调用 java.sql 中定义的对象会抛出 java.lang.SecurityException。

Java Version: 10.0.1
Scala Version: 2.12.4
sbt Version: 1.2.0

下面的屏幕截图是一个完整的最小工作示例,其中包含工作版本和非工作版本的控制台输出。具体来说:将脚本代码复制到一个类中,然后从该类中运行它,即可解决问题。有没有一种方法可以编写直接使用 java.sql 中的对象的 Scala 脚本?

build.sbt

name := "mypackage"
version := "0.1"
scalaVersion := "2.12.4"

libraryDependencies += "org.postgresql" % "postgresql" % "42.2.4"

broken-script.scala

import java.sql.{Connection, DriverManager}
import java.util.Properties

object Main {

  private def url = "jdbc:postgresql://localhost:5432/postgres"

  val credentials: Properties ={
    val properties = new Properties()
    properties.setProperty("user", "integration_test")
    properties.setProperty("password", "integration-pass")

    properties
  }

  def connect(): Connection =
    DriverManager.getConnection(url, credentials)


  def run(): Unit = {
    connect()
  }

}

Main.run()

如下面的控制台输出所示,broken-script.scala 遇到了 SecurityException。

brokenScript.scala 输出

:load scripts/broken-script.scala
Loading scripts/broken-script.scala...
import java.sql.{Connection, DriverManager}
import java.util.Properties
defined object Main
java.lang.securityException: Prohibited package name: java.sql
  at java.base/java/lang.ClassLoader.preDefineClass(ClassLoader.java:891)
  at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java 1007)
  at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
  at java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:545)
  at java.base/java.net.URLClassLoader.access$100(URLClassLoader.java:83)
  at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:453)
  at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:447)
  at java.base/java.security.AccessController.doPrivileged(Native Method)
  at java.base/net.URLClassLoader.findClass(URLClassLoader.java:446)
  at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:566)
  at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:553)
  at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:499)
  at Main$.connect(scripts/broken-script.scala:26)
  at Main$.run(scripts/broken-script.scala:30)

src/main/scala/mypackage/Main.scala

package mypackage

import java.sql.{Connection, DriverManager}
import java.util.Properties

object Main {

  private def url = "jdbc:postgresql://localhost:5432/postgres"

  val credentials: Properties ={
    val properties = new Properties()
    properties.setProperty("user", "integration_test")
    properties.setProperty("password", "integration-pass")

    properties
  }

  def connect(): Connection =
    DriverManager.getConnection(url, credentials)


  def run(): Unit = {
    connect()
  }

}

working-script.scala

mypackage.Main.run()

println("Success")

整个项目的图像。

enter image description here

最佳答案

SecurityException 这种情况看起来很奇怪。我试图在我的机器上重现您的问题,但尽管我遵循了描述的步骤,但我没有遇到 SecurityException

我使用了下一个代码:

import java.sql.DriverManager
import java.util.Properties

object PostgresTest extends App {

  def connect() = {
    val properties = new Properties()
    properties.setProperty("user", "postgres")
    properties.setProperty("password", "admin")

    println("Attempt to establish connection ...")

    val someMetaData = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgres", properties)
      .getMetaData
      .getDefaultTransactionIsolation

    println(s"If you see this line, it works fine: $someMetaData")
  }
}

我尝试了不同的方法:

  • 使用 sbt 控制台: :load/home/username/space/test-project/src/main/scala/PostgresTest.scalaPostgresTest.connect() - 没有 SecurityException

  • sbt console:paste 模式,效果很好

  • sbt runMain 使用上面的代码 + 调用 connect() 方法 - 工作正常
  • 通过 IntelliJ 脚本向导和 main 方法 - 它们都工作正常。

SBT - 1.1.1Scala - 2.12.4

我认为这可能是 IntelliJ 方面的问题。如果我上面描述的任何场景不适合您,请通知我。

关于java - 如何在不遇到 SecurityException 的情况下从 Scala 脚本引用 java.sql?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51790356/

相关文章:

unit-testing - 如何在specs2中定义DataTables的上下文

java - jdbc如何截断数值?

java - 使用@Formula从出生日期计算年龄

java - 如何使等待 Tomcat 的阻塞 Java 线程可中断

scala - cats scala中的monad更改器(mutator)

scala - 在scala中警告或避免整数除法(导致截断)

java - 逃避的正确方法是什么?使用 Oracle 12c MATCH_RECOGNIZE 时 JDBC PreparedStatement 中的字符?

Java 和 Spring JDBC : How to simulate table in database doesn't exist for testing (without actually dropping or renaming it)

java - 本地化 Spring Boot 验证消息中的消息参数未解析

java - 如何在不将条目分配给 hashmap 的情况下执行 ConcurrentHashMap.computeIfAbsent ?