scala can't find java.sql.Date and I don't know why

Viewed 198

I'm having a problem loading the class java.sql.Date my test example looks like this:

import java.sql.Date

object TestTest {

  def main(args : Array[java.lang.String]): Unit = 
    {
    val d = new java.sql.Date(0)
    System.out.println(d )
    } 
  }

It compiles cleanly without command line arguments or $CLASSPATH set.

scalac test_test.scala

If I run it from the scala repl it behaves as expected.

Welcome to Scala 2.11.12 (OpenJDK 64-Bit Server VM, Java 11.0.6).
Type in expressions for evaluation. Or try :help.

scala> :load test_test.scala
Loading test_test.scala...
import java.sql.Date
defined object TestTest

scala> TestTest.main(Array())
1969-12-31

If I run it using java it runs as expected

$ java -version
openjdk version "11.0.6" 2020-01-14
OpenJDK Runtime Environment (build 11.0.6+10-post-Debian-1deb10u1)
OpenJDK 64-Bit Server VM (build 11.0.6+10-post-Debian-1deb10u1, mixed mode, sharing)
$ java TestTest
1969-12-31

If I run it from the command line using scala this happens:

$ scala TestTest
java.lang.ClassNotFoundException: java.sql.Date
        at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        at TestTest$.main(test_test.scala:7)
        at TestTest.main(test_test.scala)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at scala.reflect.internal.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:70)
        at scala.reflect.internal.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:31)
        at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:101)
        at scala.reflect.internal.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:70)
        at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
        at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:22)
        at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:39)
        at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:29)
        at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:39)
        at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:65)
        at scala.tools.nsc.MainGenericRunner.run$1(MainGenericRunner.scala:87)
        at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:98)
        at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:103)
        at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

I think I've had a similar problem before. Something about the new module mechanism in Java 9 and the way it screws up the ClassLoader hierarchy for scala, but in that case it didn't work even in the REPL and I've tried passing --module-include arguments and anyway if I list the modules available to the JVM like this :

$ scala -J--list-modules

...

java.sql@11.0.6

...

so java.sql is in there! The compiler can see it. The REPL can see it, the JVM can see it but somehow the scala runtime can't find it!

Does anybody have any ideas?

0 Answers
Related