Skip to content

Commit

Permalink
Work around scala/bug#11530
Browse files Browse the repository at this point in the history
java.sql.Wrapper defines

```
<T> T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException;
```

ConnectionPoolDataSourceProxy inherits from DataSourceProxyBase

```
public Object unwrap(Class iface) throws SQLException {
  return null;
}
```

Extending `ConnectionPoolDataSourceProxy` in Scala doesn't work
```
[playframework] [error] /home/jenkins/workspace/scala-2.13.x-integrate-community-build/target-0.9.16/project-builds/playframework-f83a83f4042298df8025a1d271c2e3e565ce83f2/persistence/play-jdbc/src/main/scala/org/jdbcdslog/LogSqlDataSource.scala:16:7: name clash between inherited members:
[playframework] [error] def unwrap[T](x$1: Class[T]): T in trait Wrapper and
[playframework] [error] def unwrap(x$1: Class[_]): Object in class DataSourceProxyBase
[playframework] [error] have same type after erasure: (x$1: Class)Object
[playframework] [error] class LogSqlDataSource extends ConnectionPoolDataSourceProxy {
[playframework] [error]       ^
```

trying to write `ConnectionPoolDataSourceProxy` doesn't work either, i
get basically the same error from javac.

So using a different approach, just an accessor for the field.

(cherry picked from commit d19c4a2c856b64195454854f6ea33a73165040db)
  • Loading branch information
lrytz authored and octonato committed Jun 18, 2019
1 parent 464fa05 commit 1ad816e
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 36 deletions.
6 changes: 6 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import sbt.Keys.parallelExecution
import sbt.ScriptedPlugin._
import sbt._
import sbt.io.Path._
import com.typesafe.tools.mima.core.MissingClassProblem

lazy val BuildLinkProject = PlayNonCrossBuiltProject("Build-Link", "dev-mode/build-link")
.dependsOn(PlayExceptionsProject)
Expand Down Expand Up @@ -140,6 +141,11 @@ lazy val PlayJdbcApiProject = PlayCrossBuiltProject("Play-JDBC-Api", "persistenc

lazy val PlayJdbcProject: Project = PlayCrossBuiltProject("Play-JDBC", "persistence/play-jdbc")
.settings(libraryDependencies ++= jdbcDeps)
.settings(
mimaBinaryIssueFilters ++= Seq(
ProblemFilters.exclude[MissingClassProblem]("org.jdbcdslog.LogSqlDataSource")
)
)
.dependsOn(PlayJdbcApiProject)
.dependsOn(PlaySpecs2Project % "test")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import com.google.common.collect.ImmutableMap;

import org.jdbcdslog.LogSqlDataSource;
import org.jdbcdslog.ConnectionPoolDataSourceProxy;
import org.junit.Rule;
import org.junit.rules.ExpectedException;
import org.junit.Test;
Expand Down Expand Up @@ -226,11 +226,12 @@ public void notSupplyConnectionsAfterShutdown() throws Exception {
}

@Test
public void useLogSqlDataSourceWhenLogSqlIsTrue() throws Exception {
public void useConnectionPoolDataSourceProxyWhenLogSqlIsTrue() throws Exception {
Map<String, String> config = ImmutableMap.of("jndiName", "DefaultDS", "logSql", "true");
Database db = Databases.createFrom("test", "org.h2.Driver", "jdbc:h2:mem:test", config);
assertThat(db.getDataSource(), instanceOf(LogSqlDataSource.class));
assertThat(JNDI.initialContext().lookup("DefaultDS"), instanceOf(LogSqlDataSource.class));
assertThat(db.getDataSource(), instanceOf(ConnectionPoolDataSourceProxy.class));
assertThat(
JNDI.initialContext().lookup("DefaultDS"), instanceOf(ConnectionPoolDataSourceProxy.class));
db.shutdown();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (C) 2009-2019 Lightbend Inc. <https://www.lightbend.com>
*/

package org.jdbcdslog;

import javax.sql.DataSource;

/**
* This class is necessary because ConnectionPoolDataSourceProxy's targetDS field is protected. So
* by defining this helper class, in Java and in the org.jdbcdslog, we can access the protected
* field (because being in the package grants protected access).
*/
public class AccessConnectionPoolDataSourceProxy {
public static DataSource getTargetDatasource(ConnectionPoolDataSourceProxy p) {
return (DataSource) p.targetDS;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ package play.api.db
import javax.sql.DataSource

import com.typesafe.config.Config
import org.jdbcdslog.LogSqlDataSource
import org.jdbcdslog.ConnectionPoolDataSourceProxy
import org.jdbcdslog.AccessConnectionPoolDataSourceProxy
import play.api.Environment
import play.api.Mode
import play.api.inject.Injector
Expand Down Expand Up @@ -103,7 +104,7 @@ object ConnectionPool {
*/
private[db] def wrapToLogSql(dataSource: DataSource, configuration: Config): DataSource = {
if (configuration.getBoolean("logSql")) {
val proxyDataSource = new LogSqlDataSource()
val proxyDataSource = new ConnectionPoolDataSourceProxy()
proxyDataSource.setTargetDSDirect(dataSource)
proxyDataSource
} else {
Expand All @@ -116,8 +117,8 @@ object ConnectionPool {
*/
private[db] def unwrap(dataSource: DataSource): DataSource = {
dataSource match {
case ds: LogSqlDataSource => ds.getTargetDatasource
case _ => dataSource
case ds: ConnectionPoolDataSourceProxy => AccessConnectionPoolDataSourceProxy.getTargetDatasource(ds)
case _ => dataSource
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,25 +67,25 @@ class ConnectionPoolConfigSpec extends PlaySpecification {
}
}

"do not use LogSqlDataSource by default" in new WithApplication(
"do not use ConnectionPoolDataSourceProxy by default" in new WithApplication(
_.configure(
"db.default.driver" -> "org.h2.Driver",
"db.default.url" -> "jdbc:h2:mem:default"
)
) {
val db = app.injector.instanceOf[DBApi]
db.database("default").dataSource.getClass.getName must not contain ("LogSqlDataSource")
db.database("default").dataSource.getClass.getName must not contain ("ConnectionPoolDataSourceProxy")
}

"use LogSqlDataSource when logSql is true" in new WithApplication(
"use ConnectionPoolDataSourceProxy when logSql is true" in new WithApplication(
_.configure(
"db.default.driver" -> "org.h2.Driver",
"db.default.url" -> "jdbc:h2:mem:default",
"db.default.logSql" -> "true"
)
) {
val db = app.injector.instanceOf[DBApi]
db.database("default").dataSource.getClass.getName must contain("LogSqlDataSource")
db.database("default").dataSource.getClass.getName must contain("ConnectionPoolDataSourceProxy")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ package play.api.db

import java.sql.SQLException

import org.jdbcdslog.LogSqlDataSource
import org.jdbcdslog.ConnectionPoolDataSourceProxy
import org.specs2.mutable.After
import org.specs2.mutable.Specification

Expand Down Expand Up @@ -35,7 +35,7 @@ class DatabasesSpec extends Specification {
"create database with log sql" in new WithDatabase {
val config = Map("logSql" -> "true")
val db = Databases(driver = "org.h2.Driver", url = "jdbc:h2:mem:default", config = config)
db.dataSource must beAnInstanceOf[LogSqlDataSource]
db.dataSource must beAnInstanceOf[ConnectionPoolDataSourceProxy]
}

"create default in-memory database" in new WithDatabase {
Expand Down

0 comments on commit 1ad816e

Please sign in to comment.