播放Siena无法连接到GAE上的MySQL

时间:2013-12-05 17:15:17

标签: google-app-engine playframework google-cloud-sql siena

我正在使用play framework 1.2.7,gae module 1.6.0和siena module 2.0.7(也测试了2.0.6)。这是一个简单的项目,应该在App Engine上部署,并连接到Google Cloud SQL中的MySQL数据库。我的项目在本地运行正常,但无法连接到生产中的数据库。看一下日志,它看起来好像是使用postgresql驱动程序而不是mysql驱动程序。

Application.conf

# db=mem
db.url=jdbc:google:mysql://PROJECT_ID:sienatest/sienatest
db.driver=com.mysql.jdbc.GoogleDriver
db.user=root
db.pass=root

这是崩溃堆栈跟踪

play.Logger niceThrowable: Cannot connected to the database : null
java.lang.NullPointerException
    at com.google.appengine.runtime.Request.process-a3b6145d1dbbd04d(Request.java)
    at java.util.Hashtable.put(Hashtable.java:432)
    at java.util.Properties.setProperty(Properties.java:161)
    at org.postgresql.Driver.loadDefaultProperties(Driver.java:121)
    at org.postgresql.Driver.access$000(Driver.java:47)
    at org.postgresql.Driver$1.run(Driver.java:88)
    at java.security.AccessController.doPrivileged(AccessController.java:63)
    at org.postgresql.Driver.getDefaultProperties(Driver.java:85)
    at org.postgresql.Driver.connect(Driver.java:231)
    at java.sql.DriverManager.getConnection(DriverManager.java:571)
    at java.sql.DriverManager.getConnection(DriverManager.java:215)
    at play.modules.siena.GoogleSqlDBPlugin.onApplicationStart(GoogleSqlDBPlugin.java:103)
    at play.plugins.PluginCollection.onApplicationStart(PluginCollection.java:525)
    at play.Play.start(Play.java:533)
    at play.Play.init(Play.java:305)

这里发生了什么?我正在指定正确的驱动程序和url架构,它使用的是postgresql驱动程序。启用了Google Cloud SQL API访问,允许应用程序连接到mysql实例,我没有使用db = mem,...我卡住了,无法弄清楚如何前进! : - ((

更新:我以为我找到了解决方案,但事实并非如此。如果我保留%prod。前缀和正常创建战争(或者只是不定义任何数据库属性),然后应用程序将使用Google DataStore而不是Cloud SQL。如果我在最后创建war文件添加--%prod(或者只删除application.conf中的%prod。前缀),那么它将继续无法连接到显示相同初始错误的数据库。

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

在坚持这么久之后,我在发布问题后立即找到了解决方案。实际上非常愚蠢。

application.conf文件中的生产环境属性必须以%prod开头。所以数据库配置应该是

%prod.db.url=jdbc:google:mysql://PROJECT_ID:sienatest/sienatest
%prod.db.driver=com.mysql.jdbc.GoogleDriver
%prod.db.user=root
%prod.db.pass=root

一切都运行良好。

编辑:这不是解决方案。问题消失了,但应用程序正在使用DataStore而不是Cloud SQL

答案 1 :(得分:0)

最后,我结束了对siena模块源代码的轻微修改并重新编译它。

如果有人有兴趣,你需要在GoogleSqlDBPlugin类第97行的代码中删除/ comment / catch异常:

// Try the connection
                Connection fake = null;
                try {
                    if (p.getProperty("db.user") == null) {
                        fake = DriverManager.getConnection(p.getProperty("db.url"));
                    } else {
                        fake = DriverManager.getConnection(p.getProperty("db.url"), p.getProperty("db.user"), p.getProperty("db.pass"));
                    }
                } finally {
                    if (fake != null) {
                        fake.close();
                    }
                }

由于某种原因,在使用DriverManager.getConnection()启动时连接失败,但在使用basicDatasource.getConnection();启动时它会起作用,这显然是模块在其余代码中使用的方式。因此,如果删除上面的块,并重新编译该模块,一切都将按预期工作。如果您正在使用JDK 7进行编译,则还需要在GoogleSqlDBPlugin文件末尾的ProxyDriver内部类中实现public Logger getParentLogger() throws SQLFeatureNotSupportedException

奇怪的是,我深入研究了DriverManager.getConnection(),看起来有些postgresql驱动程序以某种方式注册,否则我看不出为什么DriverManager.getConnection()会调用org.postgresql.Driver.connect()