首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在不遇到SecurityException的情况下从Scala脚本引用java.sql?

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

Stack Overflow用户
提问于 2018-08-11 00:10:32
回答 1查看 344关注 0票数 6

从Java9开始,从Scala内部调用java.sql中定义的对象时,如果直接从scala脚本使用,就会抛出java.lang.SecurityException。

代码语言:javascript
复制
Java Version: 10.0.1
Scala Version: 2.12.4
sbt Version: 1.2.0

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

build.sbt

代码语言:javascript
复制
name := "mypackage"
version := "0.1"
scalaVersion := "2.12.4"

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

broken-script.scala

代码语言:javascript
复制
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 Output

代码语言:javascript
复制
: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

代码语言:javascript
复制
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

代码语言:javascript
复制
mypackage.Main.run()

println("Success")

整个项目的图像。

EN

回答 1

Stack Overflow用户

发布于 2018-08-16 21:31:10

正如Rich在评论中指出的,问题在于使用Java9或更高版本的because they changed how classloaders work。不理想的修复方法是降级到Java 8。

要确保安装了Java 8 (Linux):

代码语言:javascript
复制
sudo update-alternatives --display java

要默认使用Java 8:

代码语言:javascript
复制
sudo update-alternatives --config java

在切换到Java 8之后,一切工作正常。这个解决方案并不理想,因为它依赖于使用won't be supported for much longer版本的Java。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51790356

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档