从 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")
整个项目的图像。
最佳答案
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.scala
和PostgresTest.connect()
- 没有SecurityException
sbt console
和:paste
模式,效果很好sbt runMain
使用上面的代码 + 调用connect()
方法 - 工作正常- 通过
IntelliJ
脚本向导和 main 方法 - 它们都工作正常。
SBT - 1.1.1
和 Scala - 2.12.4
我认为这可能是 IntelliJ 方面的问题。如果我上面描述的任何场景不适合您,请通知我。
关于java - 如何在不遇到 SecurityException 的情况下从 Scala 脚本引用 java.sql?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51790356/