Google Cloud SQL - невозможно подключиться к базе данных MySQL - PullRequest
2 голосов
/ 29 июня 2019

Я пытаюсь подключиться к своей базе данных MySQL, размещенной на облачной платформе Google, используя Java и HikariConfig API (как показано в руководстве Google). Я строю свой код в Eclipse, но, несмотря на все, что я мог придумать, мое соединение не работает. Я могу подключиться к той же базе данных, используя Mysql Workbench (используя общедоступный API) и используя localhost (вместо Google App Engine). Я думаю, что мне не хватает файла JAR в моем проекте. Я добавляю код и скриншоты моей библиотеки jar.

ошибка, которую я получаю, ниже:

java.lang.AbstractMethodError: Method com/google/cloud/sql/mysql/SocketFactory.connect(Ljava/lang/String;ILcom/mysql/cj/conf/PropertySet;I)Ljava/io/Closeable; is abstract
at com.google.cloud.sql.mysql.SocketFactory.connect (SocketFactory.java)
at com.mysql.cj.protocol.a.NativeSocketConnection.connect (NativeSocketConnection.java:65)
at com.mysql.cj.NativeSession.connect (NativeSession.java:152)
at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly (ConnectionImpl.java:955)
at com.mysql.cj.jdbc.ConnectionImpl.createNewIO (ConnectionImpl.java:825)
at com.mysql.cj.jdbc.ConnectionImpl.<init> (ConnectionImpl.java:455)
at com.mysql.cj.jdbc.ConnectionImpl.getInstance (ConnectionImpl.java:240)
at com.mysql.cj.jdbc.NonRegisteringDriver.connect (NonRegisteringDriver.java:199)
at com.zaxxer.hikari.util.DriverDataSource.getConnection (DriverDataSource.java:117)
at com.zaxxer.hikari.util.DriverDataSource.getConnection (DriverDataSource.java:123)
at com.zaxxer.hikari.pool.PoolBase.newConnection (PoolBase.java:365)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry (PoolBase.java:194)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry (HikariPool.java:460)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast (HikariPool.java:534)
at com.zaxxer.hikari.pool.HikariPool.<init> (HikariPool.java:115)
at com.zaxxer.hikari.HikariDataSource.<init> (HikariDataSource.java:81)
at com.x.d3sols.web.ConnectionPoolContextListener.createConnectionPool (ConnectionPoolContextListener.java:51)
at com.x.d3sols.web.ConnectionPoolContextListener.contextInitialized (ConnectionPoolContextListener.java:71)
at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized (ContextHandler.java:843)
at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized (ServletContextHandler.java:533)
at org.eclipse.jetty.server.handler.ContextHandler.startContext (ContextHandler.java:816)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext (ServletContextHandler.java:345)
at org.eclipse.jetty.webapp.WebAppContext.startWebapp (WebAppContext.java:1406)
at com.google.apphosting.runtime.jetty9.AppEngineWebAppContext.startWebapp (AppEngineWebAppContext.java:175)
at org.eclipse.jetty.webapp.WebAppContext.startContext (WebAppContext.java:1368)
at org.eclipse.jetty.server.handler.ContextHandler.doStart (ContextHandler.java:778)
at org.eclipse.jetty.servlet.ServletContextHandler.doStart (ServletContextHandler.java:262)
at org.eclipse.jetty.webapp.WebAppContext.doStart (WebAppContext.java:522)
at com.google.apphosting.runtime.jetty9.AppEngineWebAppContext.doStart (AppEngineWebAppContext.java:120)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start (AbstractLifeCycle.java:68)
at com.google.apphosting.runtime.jetty9.AppVersionHandlerMap.createHandler (AppVersionHandlerMap.java:240)
at com.google.apphosting.runtime.jetty9.AppVersionHandlerMap.getHandler (AppVersionHandlerMap.java:178)
at com.google.apphosting.runtime.jetty9.JettyServletEngineAdapter.serviceRequest (JettyServletEngineAdapter.java:120)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.dispatchServletRequest (JavaRuntime.java:722)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.dispatchRequest (JavaRuntime.java:685)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run (JavaRuntime.java:655)
at com.google.apphosting.runtime.JavaRuntime$NullSandboxRequestRunnable.run (JavaRuntime.java:847)
at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run (ThreadGroupPool.java:270)
at java.lang.Thread.run (Thread.java:748)

Это очень важно для меня, любая помощь будет высоко оценена. Спасибо:)

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.sql.DataSource;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

/**
 * Servlet implementation class ConnectionPoolContextListener
 */
@WebListener("Creates a connection pool that is stored in the Servlet's context for later use.")
public class ConnectionPoolContextListener implements ServletContextListener {

    // Saving credentials in environment variables is convenient, but not secure - consider a more
    // secure solution such as https://cloud.google.com/kms/ to help keep secrets safe.
    private static final String DB_USER = "<user>";
    private static final String DB_PASS = "<password>";
    private static final String CLOUD_SQL_CONNECTION_NAME = "<Connection_Name>";
    private static final String DB_NAME = "<DB_Name>";

      private DataSource createConnectionPool() {
            // [START cloud_sql_mysql_servlet_create]
            // The configuration object specifies behaviors for the connection pool.
            HikariConfig config = new HikariConfig();

            //For Localhost - IT WORKS
            /*String url = "jdbc:mysql://<IP_Address>/<DB_NAME>";
            config.setJdbcUrl(url);
            config.setUsername(DB_USER); 
            config.setPassword(DB_PASS);
            config.setDriverClassName("com.mysql.jdbc.Driver");
            config.addDataSourceProperty("useSSL", "false");*/

            //For APP ENGINE - IT DOESNT WORKS
            String url = "jdbc:mysql://google/<DB_NAME>";
            config.setJdbcUrl(url);
            config.setUsername(DB_USER);
            config.setPassword(DB_PASS);
            config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.mysql.SocketFactory");
            config.addDataSourceProperty("cloudSqlInstance", CLOUD_SQL_CONNECTION_NAME);
            config.addDataSourceProperty("useSSL", "false");
            config.setDriverClassName("com.mysql.jdbc.Driver");

            config.setMaximumPoolSize(5);
            config.setMinimumIdle(5);
            config.setConnectionTimeout(60000); 
            config.setIdleTimeout(600000); 
            config.setMaxLifetime(1800000); // 30 minutes
            DataSource pool = new HikariDataSource(config);
            return pool;
          }


      @Override
      public void contextDestroyed(ServletContextEvent event) {
        // This function is called when the Servlet is destroyed.
        HikariDataSource pool = (HikariDataSource) event.getServletContext().getAttribute("my-pool");
        if (pool != null) {
          pool.close();
        }
      }

      @Override
      public void contextInitialized(ServletContextEvent event) {
        // This function is called when the application starts and will safely create a connection pool
        // that can be used to connect to.
        DataSource pool = (DataSource) event.getServletContext().getAttribute("my-pool");
        if (pool == null) {
          pool = createConnectionPool();
          event.getServletContext().setAttribute("my-pool", pool);
        }
      }
}

Вот скриншот моей папки, где я добавил недостающие библиотеки, о которых я мог подумать

Ответы [ 2 ]

2 голосов
/ 29 июня 2019

Мне наконец удалось решить это с помощью комментариев. Видимо, в файле appengine-web.xml отсутствовала строка, которую я добавил, и она была исправлена. Я также заменил некоторые файлы JAR в моем classpath.

Строка, которая будет добавлена ​​в appengine-web.xml:

<use-google-connector-j>true</use-google-connector-j> 

И ваши библиотеки будут выглядеть так: Libs

Пожалуйста, помните о версии всех библиотек, которые вы используете, я использую v8. Для этого требуются все библиотеки, кроме Gson.

1 голос
/ 29 июня 2019

однажды у меня возникла та же проблема (я знаю, насколько это болезненно) и сколько бы мне не пришлось иметь большого опыта работы с Java, но это то, что я могу рассказать вам о том, как я соединяю cloud-sql с app-engine

Помните об этих двух вещах:

Если вы хотите соединить cloud-sql с app-engine соединение должно быть через socket в противном случае он не подключается, и если вы хотите подключиться от localhost к cloud-sql , он должен быть через tcp.В последнем случае ваш публичный ip необходимо добавить в авторизованные сети в разделе connections.

Итак, насколько я могу видеть, что вы делаете, это нормально, но вы можете попытатьсяотформатируйте URL, как указано в документе:

HikariConfig config = new HikariConfig();
config.setJdbcUrl(String.format("jdbc:mysql:///%s", DB_NAME));

и еще одна вещь, которую вы должны быть уверены, что формат CLOUD_SQL_CONNECTION_NAME выглядит следующим образом:

CLOUD_SQL_CONNECTION_NAME = 'project-id:region:instance-id'

// You can get this information from the overview page in google cloud console - sql.

Для болееинформацию, которую вы можете просмотреть по этим двум ссылкам Документы Google и Пример Java

Надеюсь, это поможет.

...