Open ronaldlee opened 8 years ago
Had the same error. Found out that this was due to SBT running all tests in the save JVM - after first run all next runs would end up in weird state when ClassLoaders got kind of mixed up, resulting in errors like one above. Solution in my case was to set fork in test := true
.
I'm closing this as not relating to slick. SBT issue
I believe this is also a problem in Slick, not solely an SBT issue, in a way that Slick currently does not make interactive use of sbt test
possible with certain test setup.
I had the same issue and tried the suggestion above to add fork in test := true
but it didn't help. Then I tried explicitly passing the class loader to Database.forConfig
which also didn't help, in a quite indeterministic way Slick sometimes used the wrong class loader.
Following the stack trace of the exception I got I noticed that JdbcBackend.createDatabase
doesn't pass the class loader to Database.forConfig
when it's called from DatabaseConfig.forConfig
. So when DatabaseConfig.forConfig
it explicitly called Slick might use different class loaders in DatabaseConfig
and in JdbcDataSourceFactory
that end up in a ClassCastException
.
So while the root cause might be a combination of sbt, the test framework and interactive sbt use, there is in fact something Slick could do to help.
I am getting this error after changing the slick hello sample to use postgres instead of the in-memory db. I added Test / fork := true
. Is it certain that this is an SBT bug? I am not so sure.
@joshcough meaning that forking helped?
Also see https://www.scala-sbt.org/1.x/docs/In-Process-Classloaders.html, does setting any value of classLoaderLayeringStrategy
help? (Be sure it's set in the right scope.)
I apologize @nafg, I should have been more clear - the fork did not help. All I did was take the slick hello sample, I added Test / fork := true
in build.sbt
, and I changed application.conf
to be this:
h2mem1 = {
dataSourceClass = "org.postgresql.ds.PGSimpleDataSource"
properties = {
databaseName = "slick_sample"
user = "joshuacough"
password = "..."
}
numThreads = 10
}
Then running the tests gives me this:
sbt:sample-hello-slick> test
[info] TablesSuite:
[info] TablesSuite *** ABORTED ***
[info] java.lang.ClassNotFoundException: slick.jdbc.hikaricp.HikariCPJdbcDataSource$
[info] at java.base/java.lang.ClassLoader.findClass(ClassLoader.java:718)
[info] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:587)
[info] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
[info] at slick.util.ClassLoaderUtil$$anon$1.loadClass(ClassLoaderUtil.scala:17)
[info] at slick.jdbc.JdbcDataSource$.loadFactory$1(JdbcDataSource.scala:36)
[info] at slick.jdbc.JdbcDataSource$.forConfig(JdbcDataSource.scala:41)
[info] at slick.jdbc.JdbcBackend$DatabaseFactoryDef.forConfig(JdbcBackend.scala:341)
[info] at slick.jdbc.JdbcBackend$DatabaseFactoryDef.forConfig$(JdbcBackend.scala:337)
[info] at slick.jdbc.JdbcBackend$$anon$1.forConfig(JdbcBackend.scala:32)
[info] at TablesSuite.$anonfun$new$1(TablesSuite.scala:21)
[info] ...
@joshcough what version of slick?
@nafg actually... I did this off the head of the main
branch. I'll try the v3.3.3
tag.
@nafg I managed to get it to work by using 3.3.3
. Possible that my error just a weird thing that resulted from using main/HEAD
. If you want, you should be able to reproduce this there by using the changes I listed above. But, if you simply closed this again, I wouldn't blame you.
If there's a regression since 3.3.3 we definitely want it fixed. Any chance you could submit a test case, or git bisect the bad commit?
Otherwise if you have a self-contained github repository that demonstrates the issue (working with 3.3.3 and failing with e.g. 3.4.0-M1) that would be very helpful.
Hi,
I am getting this class cast exception: java.lang.ClassCastException: slick.jdbc.hikaricp.HikariCPJdbcDataSource$ cannot be cast to slick.jdbc.JdbcDataSourceFactory
I investigate further and narrow down to the slick.jdbc.JdbcDataSource.scala. Inside the JdbcDataSource object there is an inner function 'loadFactory' which loads the driver and casts it to the 'JdbcDataSourceFactory'. The line that throws such error is this:
clazz.getField("MODULE$").get(clazz).asInstanceOf[JdbcDataSourceFactory]
For some reason, the class loader that loads the driver is not the same as the one used to load the JdbcDataSourceFactory, and I believe that is the cause of this exception. I hack it by using the class loader of the JdbcDataSourceFactory to load the driver and it works:
I am using slick version 3.1.1, scala version 2.11.8. The project itself has a rather complex sbt set up since it hosts multiple sub services and pull in other packages as well. We write a Slick Plugin which is shared with other sub services setup in the sbt(s). I have another simpler project that only hosts a single service and doesn't use plugin for Slick config and that works fine.
Thanks. Ronald