简体   繁体   English

玩Siena无法在GAE上连接到MySQL

[英]Play Siena failing to connect to MySQL on GAE

I am using play framework 1.2.7, gae module 1.6.0 and siena module 2.0.7 (also tested 2.0.6). 我正在使用播放框架1.2.7,gae模块1.6.0和siena模块2.0.7(也已测试2.0.6)。 This is a simple project that should run in play deployed on App Engine and connect to a MySQL database in Google Cloud SQL. 这是一个简单的项目,应在部署在App Engine上的游戏中运行,并连接到Google Cloud SQL中的MySQL数据库。 My project runs fine locally but fails to connect to the database in production. 我的项目在本地运行良好,但无法连接到生产环境中的数据库。 Looking at the logs it looks like it is using the postgresql driver instead of the mysql one. 查看日志,看起来它正在使用postgresql驱动程序而不是mysql驱动程序。

Application.conf 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

This is the crash stack trace 这是崩溃堆栈跟踪

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)

What is going on here? 这里发生了什么? I am specifying the correct driver and url schema and it's using postgresql driver. 我指定了正确的驱动程序和URL架构,它使用的是postgresql驱动程序。 Google Cloud SQL API access is enabled, the app is allowed to connect to the mysql instance, I am not using db=mem, ... I am stuck and can't figure out how to move forward! 启用了Google Cloud SQL API访问,允许该应用连接到mysql实例,我未使用db = mem,...我被卡住了,无法弄清楚如何继续前进! :-(( :-((

UPDATE: I thought I found the solution, but that was not the case. 更新:我以为我找到了解决方案,但事实并非如此。 If I keep the %prod . 如果我保留%prod prefix and create a war normally (or just don't define any DB properties), then the application will use Google DataStore instead of the Cloud SQL . 前缀并正常进行战争(或只是不定义任何数据库属性),那么应用程序将使用Google DataStore而不是Cloud SQL If I create the war file adding --%prod at the end (or just delete the %prod . prefix in the application.conf), then it will keep failing to connect to the database showing the same initial error. 如果我创建的战争文件在末尾添加--%prod (或者只是删除application.conf中的%prod 。前缀),那么它将无法连接到显示相同初始错误的数据库。

Any ideas please? 有什么想法吗?

After being stuck for so long on this I just found the solution in no time after posting the question. 在这个问题上停留了很长时间之后,我在发布问题后立即找到了解决方案。 Quite stupid actually. 其实很愚蠢。

The production environment properties in the application.conf file must be preceded by %prod. application.conf文件中的生产环境属性必须在%prod之前。 so the database config should read 因此数据库配置应读取

%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

And everything runs fine. 一切运行正常。

EDIT: This is NOT the solution. 编辑:这不是解决方案。 The problem went away, but the app is using the DataStore instead of the Cloud SQL 问题消失了,但是应用程序使用的是DataStore而不是Cloud SQL

At the end I ended doing a slight modification in play siena module source code and recompiling it. 最后,我结束了对siena模块源代码的稍作修改并重新编译。

In case anyone is interested, you will need to remove/comment/catch exception in this code around line 97 in GoogleSqlDBPlugin class: 如果有人感兴趣,您将需要在GoogleSqlDBPlugin类的第97行周围的这段代码中删除/注释/捕获异常:

// 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();
                    }
                }

For some reason the connection fails when initiated with DriverManager.getConnection() but it works when initiated with basicDatasource.getConnection(); 出于某种原因,使用DriverManager.getConnection()启动连接时会失败,但是使用basicDatasource.getConnection();启动时,连接会basicDatasource.getConnection(); which apparently is the way used by the module in the rest of the code. 这显然是模块在其余代码中使用的方式。 So if you delete the above block, and recompile the module everything will work as expected. 因此,如果删除上述代码块,然后重新编译模块,一切将按预期工作。 If you are compiling with JDK 7, you will also need to implement public Logger getParentLogger() throws SQLFeatureNotSupportedException in the ProxyDriver inner class at the end of GoogleSqlDBPlugin file. 如果使用JDK 7进行编译,则还需要实现public Logger getParentLogger() throws SQLFeatureNotSupportedException ,在GoogleSqlDBPlugin文件末尾的ProxyDriver内部类中, public Logger getParentLogger() throws SQLFeatureNotSupportedException

Strangely, I digged into the DriverManager.getConnection() and it looked like some postgresql driver is registered somehow, because otherwise I can't see why DriverManager.getConnection() would call to org.postgresql.Driver.connect() . 奇怪的是,我深入研究了DriverManager.getConnection() ,似乎以某种方式注册了一些postgresql驱动程序,因为否则我看不到为什么DriverManager.getConnection()会调用org.postgresql.Driver.connect()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM