CloudSQL Eclipse Java Standard GAE java.lang.UnsatisfiedLinkError - PullRequest
0 голосов
/ 05 июня 2018

Я создаю простое стандартное приложение Java App Engine Google, которое подключается к экземпляру Google CloudSQL.Когда я выполняю проект из командной строки, используя mvn clean appengine:run или mvn clean appengine:deploy, я могу успешно подключиться к базе данных в экземпляре CloudSQL.

Однако, если я запускаю или отлаживаю проект из Eclipse «Запуск от имени» -> App Engine или «Отладка как» -> App Engine, я получаю следующую ошибку при DriverManager.getConnection (serverURL) выполняется.

INFO: Dev App Server is now running 
connecting to: REDACTED
Jun 05, 2018 10:06:06 AM com.google.cloud.sql.mysql.SocketFactory connect
INFO: Connecting to Cloud SQL instance [REDACTED].
Jun 05, 2018 10:06:06 AM com.google.cloud.sql.mysql.SocketFactory connect
INFO: Using GAE Unix Sockets
java.sql.SQLException: java.lang.UnsatisfiedLinkError: The operation 
completed successfully.

at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:964)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:897)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:886)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:860)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:877)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:873)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:443)
at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:389)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:330)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at generic.HelloAppEngine.init(HelloAppEngine.java:55)
at javax.servlet.GenericServlet.init(GenericServlet.java:244)
at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:643)
at org.eclipse.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:499)
at org.eclipse.jetty.servlet.ServletHolder.ensureInstance(ServletHolder.java:791)
at org.eclipse.jetty.servlet.ServletHolder.prepare(ServletHolder.java:776)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:579)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:524)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:512)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)
at com.google.appengine.tools.development.jetty9.DevAppEngineWebAppContext.doScope(DevAppEngineWebAppContext.java:94)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
at com.google.appengine.tools.development.jetty9.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:597)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
at org.eclipse.jetty.server.Server.handle(Server.java:534)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:283)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:108)
at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
at java.lang.Thread.run(Unknown Source)


Caused by: java.lang.UnsatisfiedLinkError: The operation completed successfully.
at jnr.ffi.provider.jffi.AsmRuntime.newUnsatisifiedLinkError(AsmRuntime.java:40)
at jnr.unixsocket.Native$LibC$jnr$ffi$0.socket(Unknown Source)
at jnr.unixsocket.Native.socket(Native.java:92)
at jnr.unixsocket.UnixSocketChannel.<init>(UnixSocketChannel.java:101)
at jnr.unixsocket.UnixSocketChannel.open(UnixSocketChannel.java:65)
at com.google.cloud.sql.mysql.SocketFactory.connect(SocketFactory.java:61)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:300)
at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2192)
at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2225)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2024)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:779)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
... 35 more

Мой POM.xml -

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <packaging>war</packaging>
    <version>0.1.0-SNAPSHOT</version>

    <groupId>generic</groupId>
    <artifactId>testdb</artifactId>

    <properties>
        <appengine.api.sdk.version>1.9.63</appengine.api.sdk.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.showDeprecation>true</maven.compiler.showDeprecation>
        </properties>

        <dependencies>
            <dependency>
                <groupId>com.google.cloud</groupId>
                <artifactId>google-cloud-bom</artifactId>
                <version>0.47.0-alpha</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        <!-- Compile/runtime dependencies -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency> <!-- Only used locally -->
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.42</version>
        </dependency>
        <dependency>
            <groupId>com.google.cloud.sql</groupId>
            <artifactId>mysql-socket-factory</artifactId>
            <version>1.0.8</version>
        </dependency>

        <!-- Test Dependencies -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <!-- for hot reload of the web application -->
        <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <webResources>
                        <!-- in order to interpolate version from pom into appengine-web.xml -->
                        <resource>
                            <directory>${basedir}/src/main/webapp/WEB-INF</directory>
                            <filtering>true</filtering>
                            <targetPath>WEB-INF</targetPath>
                        </resource>
                    </webResources>
                </configuration>
            </plugin>

            <plugin>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>appengine-maven-plugin</artifactId>
                <version>1.3.1</version>
            </plugin>
        </plugins>
    </build>
</project>

Мой сервлет:

package generic;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.common.base.Stopwatch;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.concurrent.TimeUnit; 

@SuppressWarnings("serial")
@WebServlet(
    name = "HelloAppEngine",
    urlPatterns = {"/hello"}
)
public class HelloAppEngine extends HttpServlet {

    Connection conn;

  @Override
  public void doGet(HttpServletRequest req, HttpServletResponse resp) 
      throws IOException {

    resp.setContentType("text/plain");
    resp.setCharacterEncoding("UTF-8");

    resp.getWriter().print("Hello App Engine!\r\n");

    if(conn!=null)
        resp.getWriter().println("connected:"+conn.toString());

    }

    @Override
    public void init()
    {
      //String url = System.getProperty("cloudsql");
      String serverURL = "jdbc:mysql://google/DB?cloudSqlInstance=INSTANCE&"+               "socketFactory=com.google.cloud.sql.mysql.SocketFactory&user=USER&password=PWD&useSSL=false";

      //System.out.println("connecting to: " + url);
      System.out.println("connecting to: " + serverURL);
      try {
        conn = DriverManager.getConnection(serverURL);

      } catch (SQLException e) {
          e.printStackTrace();
      }
    }
}

Мой appengine-web.xml:

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

  <threadsafe>true</threadsafe>
  <runtime>java8</runtime>

</appengine-web-app>

Пожалуйста, помогите мне запустить и отладить это приложение в Eclipse !!

1 Ответ

0 голосов
/ 08 июня 2018

ОБНОВЛЕНИЕ: проблема была исправлена.Обновите библиотеку сокетов Cloud SQL JDBC до последней версии.

В заводской библиотеке сокетов JDBC Cloud SQL существует проблема;он неправильно полагает, что код работает на серверах App Engine: https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory/issues/77. Они работают над исправлением (как отмечено в проблеме GitHub), и, к сожалению, не существует немедленного обходного пути, пока вы используетеБиблиотека фабрики сокетов.

Причина, по которой mvn appengine:run работал, заключалась в том, что вы использовали старую версию (1.3.1) плагина com.google.cloud.tools:appengine-maven-plugin.Обновление до 1.3.2 сломает вещи, как это происходит в настоящее время с плагином Eclipse (плагин Cloud Tools for Eclipse).

Технические подробности

Для тех, кто интересуется техническими подробностямипервопричину, обратитесь к проблеме GitHub выше и к следующему: https://github.com/GoogleCloudPlatform/google-cloud-eclipse/issues/3136. В основном, последние версии плагинов делают переменные окружения GAE_RUNTIME и GAE_ENV доступными на локальном сервере разработки App Engine, что сделало JDBCБиблиотека сокетов неправильно полагает, что она находится на рабочем сервере.

...