tminglei/slick-pg

Profile java.lang.ClassNotFoundException with Play 2.8.2

alternegro opened this issue · 5 comments

My Profile works fine in Play 2.8.1 but I get a Class Not Found exception once I upgrade to 2.8.2.
The only change is the play plugin version.

Profile

package persistence

import com.github.tminglei.slickpg._
import slick.driver.JdbcProfile
import slick.basic.Capability
import play.api.libs.json.{Format, Json, JsValue}

trait MyPostgresProfile
  extends ExPostgresProfile
                          with PgArraySupport
                          with PgDate2Support
                          with PgRangeSupport
                          with PgHStoreSupport
                          with PgPlayJsonSupport
                          with PgSearchSupport
                          with PgPostGISSupport
                          with PgNetSupport
                          with PgLTreeSupport {
  def pgjson = "jsonb" // jsonb support is in postgres 9.4.0 onward; for 9.3.x use "json"

  // Add back `capabilities.insertOrUpdate` to enable native `upsert` support; for postgres 9.5+
  //override protected def computeCapabilities: Set[Capability] = 
  //  super.computeCapabilities + slick.jdbc.JdbcCapabilities.insertOrUpdate

  override val api = MyAPI

  object MyAPI extends API with ArrayImplicits
                           with DateTimeImplicits
                           with JsonImplicits
                           with NetImplicits
                           with LTreeImplicits
                           with RangeImplicits
                           with HStoreImplicits
                           with SearchImplicits
                           with SearchAssistants {
    implicit val strListTypeMapper = new SimpleArrayJdbcType[String]("text").to(_.toList)
    implicit val playJsonArrayTypeMapper =
      new AdvancedArrayJdbcType[JsValue](pgjson,
        (s) => utils.SimpleArrayUtils.fromString[JsValue](Json.parse(_))(s).orNull,
        (v) => utils.SimpleArrayUtils.mkString[JsValue](_.toString())(v)
      ).to(_.toList)
  }
}

object MyPostgresProfile extends MyPostgresProfile

Application.conf

slick {
  dbs {
    default {
      profile = "persistence.MyPostgresProfile$"
      db {
        driver = "org.postgresql.Driver"
        url = "jdbc:postgresql://localhost:5432/somedb"
        user = "user"
        password = "password"
      }
    }
  }
}

Stacktrace

[error] p.a.d.s.DefaultSlickApi - Failed to create Slick database config for key default.
slick.SlickException: Error getting instance of profile "persistence.MyPostgresProfile"
	at slick.basic.DatabaseConfig$.forConfig(DatabaseConfig.scala:95)
	at play.api.db.slick.DefaultSlickApi$DatabaseConfigFactory.create(SlickApi.scala:95)
	at play.api.db.slick.DefaultSlickApi$DatabaseConfigFactory.get$lzycompute(SlickApi.scala:87)
	at play.api.db.slick.DefaultSlickApi$DatabaseConfigFactory.get(SlickApi.scala:86)
	at play.api.db.slick.DefaultSlickApi.dbConfig(SlickApi.scala:70)
	at modules.ServicesModule.dbConfig(ServicesModule.scala:18)
	at modules.ServicesModule.dbConfig$(ServicesModule.scala:18)
	at Altern.dbConfig$lzycompute(Loader.scala:24)
	at Altern.dbConfig(Loader.scala:24)
	at modules.ServicesModule.usersService(ServicesModule.scala:24)
Caused by: java.lang.ClassNotFoundException: persistence.MyPostgresProfile
	at java.base/java.lang.ClassLoader.findClass(ClassLoader.java:718)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
	at slick.util.ClassLoaderUtil$$anon$1.loadClass(ClassLoaderUtil.scala:17)
	at slick.basic.DatabaseConfig$.forConfig(DatabaseConfig.scala:93)
	at play.api.db.slick.DefaultSlickApi$DatabaseConfigFactory.create(SlickApi.scala:95)
	at play.api.db.slick.DefaultSlickApi$DatabaseConfigFactory.get$lzycompute(SlickApi.scala:87)
	at play.api.db.slick.DefaultSlickApi$DatabaseConfigFactory.get(SlickApi.scala:86)
	at play.api.db.slick.DefaultSlickApi.dbConfig(SlickApi.scala:70)
	at modules.ServicesModule.dbConfig(ServicesModule.scala:18)

I'm having the same issue: after an update from play 2.8.1 to 2.8.2 I get the same error when running the application via sbt run. Rolling back to play 2.8.1 indeed fixes the problem. But I'm not sure slick-pg is the culprit here. Everything works in an integration tests configuration and in production configuration (we use sbt-native-packager and docker).

I'm having the same issue: after an update from play 2.8.1 to 2.8.2 I get the same error when running the application via sbt run. Rolling back to play 2.8.1 indeed fixes the problem. But I'm not sure slick-pg is the culprit here. Everything works in an integration tests configuration and in production configuration (we use sbt-native-packager and docker).

Thanks @arteme I'll in production config as well. I didn't get that far.

I'm having the same issue: after an update from play 2.8.1 to 2.8.2 I get the same error when running the application via sbt run. Rolling back to play 2.8.1 indeed fixes the problem. But I'm not sure slick-pg is the culprit here. Everything works in an integration tests configuration and in production configuration (we use sbt-native-packager and docker).

Are you using different versions of java in dev vs production?

No, I have the same java 8u262 in both. I did more experimenting and running the application in dev mode but outside sbt from the docker staging directory also works for me. Strange that neither run/fork := true nor different sbt classpath layering strategies have any effect on sbt run.

This appears to be a Play Dev.mode classloading issue. If I add my custom profile as an unmanaged library, everything works as expected.