【问题标题】:Unable to connect to Google Cloud SQL instance from Google App Engine when developing in Eclipse在 Eclipse 中开发时无法从 Google App Engine 连接到 Google Cloud SQL 实例
【发布时间】:2014-11-04 10:52:25
【问题描述】:

编辑:通过检查 Google Developers Console 上的日志文件已解决此问题。错误不是连接到数据库,而是因为我使用 JDK 1.8 而不是 1.7 进行编译。事实证明,即使我告诉 Eclipse 为该项目使用 JDK 1.7,它仍然使用 1.8,因为我的 Eclipse 配置文件中有以下行:

-vm
C:\Program Files\Java\jdk1.8.0_20\bin

当我将其更改为:

-vm
C:\Program Files\Java\jdk1.7.0_71\bin

一切正常。

原问题:

我正在尝试从我的授权 Google App Engine 应用程序连接到 Google Cloud SQL 实例。我首先按照https://cloud.google.com/appengine/docs/java/cloud-sql/#Java_Build_a_starter_application_and_database 的指示进行了一些修改以使用我的 Cloud SQL 实例(我没有实现留言簿数据库,我使用了我自己的,它也只有一个三列表)。我使用 MySQL Workbench 创建了 Cloud SQL 实例。

当我在 本地 调试我的应用程序(在 localhost:8888 上运行它)时,它与我的本地 MySQL 实例 和 Google Cloud SQL 实例完美配合。 但是,当我尝试将我的应用程序部署到 Google App Engine 它只是返回一个 500 服务器错误,我不知道出了什么问题(我对网络编程非常陌生)。我一直在网上搜索这个问题的解决方案,但我还没有找到可以解决问题的方法。

这是我的 servlet 代码:

package com.rmpm;

import java.io.*;
import java.sql.*;
import javax.servlet.http.*;
import com.google.appengine.api.utils.SystemProperty;


@SuppressWarnings("serial")
public class Synaptic_rmpmServlet extends HttpServlet {
    @Override
      public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String url = null;
        resp.setContentType("text/html");
        PrintWriter out = resp.getWriter();

        try {
          if (SystemProperty.environment.value() ==
              SystemProperty.Environment.Value.Production) {
            // Load the class that provides the new "jdbc:google:mysql://" prefix.
            Class.forName("com.mysql.jdbc.GoogleDriver");
            url = "jdbc:google:mysql://<my-project-id>:<my-instance-id>/test"; // Doesn't work
          } else {
            // Local MySQL instance to use during development.
            Class.forName("com.mysql.jdbc.Driver");
            url = "jdbc:mysql://173.###.##.###:3306/test"; // Connects to Google Cloud SQL instance when root password is provided
            //url = "jdbc:mysql://127.0.0.1:3306/test";    // Connects to local MySQL instance
          }
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }

        try {
          Connection conn = DriverManager.getConnection(url, "root", "");
          try {
            String pid = req.getParameter("projID");
            String own = req.getParameter("owner");
            String dur = req.getParameter("duration");
            if (pid == "" || own == "" || dur == "") {
              out.println(
                  "<html><head></head><body>You are missing either a projectID, owner name, or duration! Try again! " +
                  "Redirecting in 3 seconds...</body></html>");
            } 
            else {
                int duration = Integer.parseInt(dur);
                String statement = "INSERT INTO project VALUES(?, ?, ?)";
                PreparedStatement stmt = conn.prepareStatement(statement);
                stmt.setString(1, pid);
                stmt.setString(2, own);
                stmt.setInt(3, duration);
                int success = 2;
                success = stmt.executeUpdate();
                if (success == 1) {
                    out.println(
                            "<html><head></head><body>Success! Redirecting in 3 seconds...</body></html>");
                } else if (success == 0) {
                    out.println(
                            "<html><head></head><body>Failure! Please try again! " +
                            "Redirecting in 3 seconds...</body></html>");
                }
            }
          } finally {
           conn.close();
          }
        } 
        catch (SQLException e) {
            e.printStackTrace();
        }
        resp.setHeader("Refresh", "3; url=/databaseIO.jsp");
      }
}

还有我的 databaseIO.jsp 代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.List" %>
<%@ page import="java.sql.*" %>
<%@ page import="com.google.appengine.api.utils.SystemProperty" %>

<html>
  <body>

<%
String url = null;
if (SystemProperty.environment.value() ==
SystemProperty.Environment.Value.Production) {
  // Load the class that provides the new "jdbc:google:mysql://" prefix.
  Class.forName("com.mysql.jdbc.GoogleDriver");
  url = "jdbc:google:mysql://<my-project-id>:<my-instance-id>/test";   // Doesn't work
} else {
  // Local MySQL instance to use during development.
  Class.forName("com.mysql.jdbc.Driver");
  url = "jdbc:mysql://173.###.##.###:3306/test";       // Connects to Google Cloud SQL instance when root password is provided
  //url = "jdbc:mysql://127.0.0.1:3306/test";          // Connects to local MySQL instance
}

Connection conn = DriverManager.getConnection(url, "root", "");
ResultSet rs = conn.createStatement().executeQuery(
    "SELECT * FROM project");
%>

<table style="border: 1px solid black">
<tbody>
<tr>
<th width="40%" style="background-color: #CCFFCC; margin: 5px">projectID</th>
<th style="background-color: #CCFFCC; margin: 5px">owner</th>
<th style="background-color: #CCFFCC; margin: 5px">duration</th>
</tr>

<%
while (rs.next()) {
    String aPID = rs.getString(1);
    String anOwner = rs.getString(2);
    int aDur = rs.getInt(3);
 %>
<tr>
<td><%= aPID %></td>
<td><%= anOwner %></td>
<td><%= aDur %></td>
</tr>
<%
}
conn.close();
%>

</tbody>
</table>
<br />
No more projects!
<p><strong>Add a project:</strong></p>
<form action="/sign" method="post">
    <div>Project ID: <input type="text" name="projID"></input></div>
    <br />
    <div>Owner: <input type="text" name="owner"></input></div>
    <br />
    <div>Duration: <input type="text" name="duration"></input></div>
    <br />
    <div><input type="submit" value="Insert Project"></input></div>
  </form>
  </body>
 </html>

根据我在网上阅读的内容,我了解到当以 root 用户身份从我的授权 Google App Engine 应用程序连接到我的 Google Cloud SQL 实例时,我不需要密码。当我在调试模式下本地连接到 Google Cloud SQL 实例时,我确实提供了我在 Google Developers Console 中设置的 root 密码,并且它运行良好。

我做了什么:

  • 我已经使用链接到我的 Google App Engine 应用程序的 Google 帐户登录到 Eclipse。
  • 我已经在 appengine-web.xml 文件中包含了&lt;use-google-connector-j&gt;true&lt;/use-google-connector-j&gt; 行。
  • 我已将 mysql-connector-java-5.1.33-bin.jar 复制到项目的 war/WEB-INF/lib 文件夹和 D:\Program_Files\Eclipse\plugins\com.google 的 GAE SDK 目录.appengine.eclipse.sdkbundle_1.9.13\appengine-java-sdk-1.9.13\lib\impl (网上看了类似的问题说要这样做)。
  • 我已授权我的 Google App Engine 应用程序连接到我的 Google Cloud SQL 实例。
  • 我已授权本地网络连接到我的 Google Cloud SQL 实例。
  • 我 100% 确定 JDBC url 中的 &lt;my-project-id&gt;&lt;my-instance-id&gt; 字段是正确的。
  • 我尝试在 JDBC url 中使用我的 Google Cloud SQL 实例的 IP 地址,而不是 project-id 和 instance-id。

我正在使用什么:

  • Eclipse SE Luna (4.4.1) 与 Google Plugin for Eclipse (4.4) 和 Google App Engine Java SDK (1.9.13)。我使用插件从 Eclipse 直接部署到 Google App Engine。
  • JDK 1.7
  • Windows 8.1 64 位

如果您需要任何其他信息,请在此处发布,因为我会定期检查。

【问题讨论】:

  • 应用引擎出现 500 错误的一个常见原因是应用启动时间过长。你怎么知道500错误和数据库连接有关?日志说什么?
  • 非常感谢...我什至不知道该日志已退出!我想我应该假设有类似的东西用于调试目的,但我不想看。我已经用实际问题和我的解决方案更新了我的问题。
  • 嘿,我想我和你有同样的问题。它快把我逼疯了。日志在哪里,所以我可以看到问题所在?谢谢!

标签: java eclipse google-app-engine jdbc google-cloud-sql


【解决方案1】:

本地 mysql 将处理您的代码,我遇到了同样的问题,但是当我将 .GoogleDriver 更改为 .Driver 时,它开始工作了

【讨论】:

  • 请考虑改进问题的格式。我很难理解你的意思。
猜你喜欢
  • 2019-11-27
  • 2015-12-18
  • 1970-01-01
  • 1970-01-01
  • 2017-06-17
  • 1970-01-01
  • 1970-01-01
  • 2020-06-07
  • 1970-01-01
相关资源
最近更新 更多