1

I'm trying to connect from a Google Endpoints server to a Google Cloud SQL server. I'm modifying the Greetings.getGreeting() method in this tutorial: https://cloud.google.com/appengine/docs/java/endpoints/getstarted/backend/helloendpoints to call the Cloud mysql database as demonstrated in this tutorial (see doGet method): https://cloud.google.com/appengine/docs/java/cloud-sql/#enable_connector_j

I have made sure that I can connect to the database from my machine mysql client. The database instance "simple" has a single table "simpletable" who's rows hold an entityID and a string. (But I'm not able to connect, so that's not too important yet.)

This is my endpoints code:

package com.example.helloendpoints;

import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.response.NotFoundException;
import com.google.appengine.api.users.User;

import java.sql.*;
import java.util.ArrayList;

import javax.inject.Named;

/**
 * Defines v1 of a helloworld API, which provides simple "greeting" methods.
 */
@Api(
    name = "helloworld",
    version = "v1",
    scopes = {Constants.EMAIL_SCOPE},
    clientIds = {Constants.WEB_CLIENT_ID,
            Constants.ANDROID_CLIENT_ID,
            Constants.IOS_CLIENT_ID,
            Constants.API_EXPLORER_CLIENT_ID},
    audiences = {Constants.ANDROID_AUDIENCE}
)
public class Greetings {

  public static ArrayList<HelloGreeting> greetings = new ArrayList<HelloGreeting>();

  static {
    greetings.add(new HelloGreeting("hello world!"));
    greetings.add(new HelloGreeting("goodbye world!"));
  }

  public HelloGreeting getGreeting(@Named("id") Integer id) throws NotFoundException {

      // pair to use when running local endpoint server
      String urlFromDev = "jdbc:mysql://173.194.XXX.90:3306/simple?user=root";
      String classForNameFromDev = "com.mysql.jdbc.Driver";

      // pair to use when running cloud endpoint server
      String classForNameFromCloud = "com.mysql.jdbc.GoogleDriver";
      String urlFromCloud = "jdbc:google:mysql://"
              + Constants.PROJECT_ID + ":"
              + Constants.CLOUD_SQL_INSTANCE_NAME +"/"
              + Constants.DATABASE_NAME + "?user=root";

      HelloGreeting helloGreeting = new HelloGreeting();
      try {
              Class.forName(classForNameFromDev);
//              Class.forName(classForNameFromCloud);
      } catch (ClassNotFoundException e) {
          e.printStackTrace();
      }
      try {
          Connection connection = DriverManager.getConnection(urlFromDev);
//          Connection connection = DriverManager.getConnection(urlFromCloud);
          try {
              String statement = "Select simplestring from simpletable where entryID = ?";
              PreparedStatement preparedStatement = connection.prepareStatement(statement);
              preparedStatement.setInt(1, id);
              ResultSet resultSet = preparedStatement.executeQuery();
              if (!resultSet.wasNull()) {
                  helloGreeting.setMessage(resultSet.getString("simplestring"));
              } else {
                  throw new NotFoundException("Greeting not found with an index: " + id);
              }
          } finally {
              connection.close();
          }
      } catch (SQLException e) {
          e.printStackTrace();
      }
      return  helloGreeting;
  }


  @ApiMethod(name = "greetings.multiply", httpMethod = "post")
  public HelloGreeting insertGreeting(@Named("times") Integer times, HelloGreeting greeting) {
    HelloGreeting response = new HelloGreeting();
    StringBuilder responseBuilder = new StringBuilder();
    for (int i = 0; i < times; i++) {
      responseBuilder.append(greeting.getMessage());
    }
    response.setMessage(responseBuilder.toString());
    return response;
  }

  @ApiMethod(name = "greetings.authed", path = "hellogreeting/authed")
  public HelloGreeting authedGreeting(User user) {
    HelloGreeting response = new HelloGreeting("hello " + user.getEmail());
    return response;
  }
}

I have tried to enable mysql connector/j in my appengine-web.xml

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    <use-google-connector-j>true</use-google-connector-j>

    <application>backendapitutorial-1XXX</application>
    <version>${app.version}</version>
    <threadsafe>true</threadsafe>

    <system-properties>
        <property name="java.util.logging.config.file" value="WEB-  INF/logging.properties"/>
    </system-properties>
</appengine-web-app>

Whichever way I build+depl0y it (Dev or cloud), I always get java.sql.SQLException: No suitable driver found for jdbc:mysql://173.194.XXX.90:3306/simple?user=root or java.sql.SQLException: No suitable driver found for jdbc:google:mysql://backendapitutorial-XXXX:simple/simple?user=root

(I replaced the real IP and project name with "X"s for this post).

I've already looked at these:

java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/dbname

ClassNotFoundException: com.mysql.jdbc.GoogleDriver

What does 'Class.forName("org.sqlite.JDBC");' do?

I'm building with Maven and working on IntelliJ IDE.

Any help is greatly appreciated. Thanks.

Community
  • 1
  • 1
  • Problem partially solved: I was using maven to build, but I have not added _mysql-connector-java_ as a dependency in my pom. This at least allows my the applicanation to connect whhen running on my local devserver. I also realized that the urlFromCloud, `jdbc:google:mysql://backendapitutorial-XXXX:simple/simple?user=root`, should simply be `jdbc:google:mysql://backendapitutorial-XXXX:simple?user=root`. This I realized when I saw that the Google Appengine console will generate sample code when you are on the database screen and click a "How do I connect" link. – yack spillsaps Sep 24 '15 at 17:53

0 Answers0