GAE CloudSQL与MySQL访问被拒绝

时间:2012-05-14 14:18:14

标签: java google-app-engine jpa eclipselink google-cloud-sql

我有一个在以下环境下正常运行的Web应用程序

  • GWT 2.4.0
  • RestEasy 2.3.2.Final JAX-RS& JAXB
  • Hibernate JPA 2.0(hibernate-entitymanager + hibernate-validator)4.2.0.Final
  • 本地主机(Ubuntu 12.04)上的MySQL 5.5.22
  • VMware 2.6 tomcat服务器

应用程序正在成功地使用JAX-RS,JAXB,Jackson JSON提供程序,Hibernate JPA注释全部混合到同一个DTO中。

我正在尝试将其移植到GAE CloudSQL。我遇到MySQL访问错误。我不得不将ORM从Hibernate更改为EclipseLink 2.3.2。

提醒

  • 我恭敬地请求回答者不要假设我的代码中出现错误的可能性而不是解决手头的问题 - 如何将基于Hibernate的JPA移植到EclipseLink。除非您认为我的设置或适合Hibernate的代码需要更改才能使用GAE CloudSQL。原因是,应用程序在Hibernate下工作正常。

  • 除非涉及Hibernate JPA 2.0,否则请不要提供如何使Hibernate与GAE CloudSQL协同工作的说明。我意识到互联网上有一个关于如何使用Hibernate和CloudSQL但没有JPA的例子。

  • 如果您有关于如何使DataNucleus JPA 2.0与GAE CloudSQL一起使用的信息,那将非常有用。我无法使其工作,这就是我使用EclipseLink的原因。

  • 此外,MySQL数据源用户和密码能够通过Eclipse数据源资源管理器或SQL资源管理器或SQL Squirrel客户端访问数据库。所以,用户/密码没问题。除非您认为我需要修改MqSQL用户或主机设置。

  • 我已在mysql.db表中添加了一行以包含主机localhost.localdomain。

  • 我已经将启动/调试配置修改为 -Drdbms.url = jdbc:mysql:// localhost:3306 / Site?user = site& password = random& useInformationSchema = true& useUnicode = true& characterEncoding = UTF8& useServerPrepStmts = true,如“使用本地MySQL实例”所示在开发期间“在http://developers.google.com/cloud-sql/docs/developers_guide_java

  • 您的解决建议必须涉及JPA 2.0而不是1.0。

  • 我没有访问我的CloudSQL帐户,而是访问在Ubuntu 12.04上运行的localhost MySQL数据库。我还没有尝试使用此应用程序访问我的CloudSQL数据库。

可能是,我的persistence.xml中需要更多行?可能是我的EMF设置需要修改?可能是,GAE要求获得EMF的顺序与Hibernate不同?也许,我需要禁用DataNucleus?

请提供帮助和建议。非常感谢你。


错误堆栈表示java.security.AccessControlException:访问被拒绝(“java.net.SocketPermission”“localhost”“resolve”):

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
    at com.google.appengine.tools.development.agent.runtime.Runtime.newInstance_(Runtime.java:126)
    at com.google.appengine.tools.development.agent.runtime.Runtime.newInstance(Runtime.java:134)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.Util.getInstance(Util.java:386)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1013)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:982)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927)
    at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2411)
    at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2153)
    at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:792)
    at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
    at com.google.appengine.tools.development.agent.runtime.Runtime.newInstance_(Runtime.java:126)
    at com.google.appengine.tools.development.agent.runtime.Runtime.newInstance(Runtime.java:134)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:381)
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:305)
    at java.sql.DriverManager.getConnection(DriverManager.java:579)
    at java.sql.DriverManager.getConnection(DriverManager.java:190)
    at org.eclipse.persistence.sessions.DefaultConnector.connect(DefaultConnector.java:98)
    ... 55 more
Caused by: java.security.AccessControlException: access denied ("java.net.SocketPermission" "localhost" "resolve")
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:366)
    at java.security.AccessController.checkPermission(AccessController.java:555)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
    at com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkPermission(DevAppServerFactory.java:252)
    at java.lang.SecurityManager.checkConnect(SecurityManager.java:1048)
    at java.net.InetAddress.getAllByName0(InetAddress.java:1203)
    at java.net.InetAddress.getAllByName(InetAddress.java:1127)
    at java.net.InetAddress.getAllByName(InetAddress.java:1063)
    at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:247)
    at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:294)
    at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2332)
    at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2369)

的persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
  version="1.0">
  <persistence-unit name="Site" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>org.blessedgeek.site.jaxrs.dto.Node</class>
    <properties>
      <property name="javax.persistence.jdbc.user" value="site" />
      <property name="javax.persistence.jdbc.password" value="random" />
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/Site" />
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"></property>
    </properties>
  </persistence-unit>
</persistence>

maven依赖

<properties>
  <resteasy.version>2.3.2.Final</resteasy.version>
</properties>
<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.10</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>com.google.gwt</groupId>
    <artifactId>gwt-user</artifactId>
    <version>2.4.0</version>
  </dependency>
  <dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.0.0.GA</version>
  </dependency>

  <dependency>
    <groupId>com.smartgwt</groupId>
    <artifactId>smartgwt</artifactId>
    <version>3.0</version>
  </dependency>
  <dependency>
    <groupId>com.smartgwt</groupId>
    <artifactId>smartgwt-skins</artifactId>
    <version>3.0</version>
  </dependency>
  <dependency>
    <groupId>com.googlecode.mvp4g</groupId>
    <artifactId>mvp4g</artifactId>
    <version>1.4.0</version>
  </dependency>

  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.18</version>
  </dependency>

  <dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jaxrs</artifactId>
    <version>${resteasy.version}</version>
    <type>jar</type>
  </dependency>
  <dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jaxb-provider</artifactId>
    <version>${resteasy.version}</version>
  </dependency>
  <dependency>
      <groupId>org.jboss.resteasy</groupId>
      <artifactId>resteasy-jackson-provider</artifactId>
      <version>${resteasy.version}</version>
  </dependency>
</dependencies>

应用服务引擎-web.xml中

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

  <threadsafe>true</threadsafe>

  <!-- Configure serving/caching of GWT files -->
  <static-files>
    <include path="**" />

    <include path="**.nocache.*" expiration="0s" />

    <include path="**.cache.*" expiration="365d" />
    <exclude path="**.gwt.rpc" />
  </static-files>

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

  <sessions-enabled>true</sessions-enabled>
  <async-session-persistence enabled="true" />

</appengine-web-app>

的web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Blessed Geek Site</display-name>
  <!-- Auto scan REST service -->
  <context-param>
    <param-name>resteasy.scan</param-name>
    <param-value>true</param-value>
  </context-param>

  <!-- this need same with resteasy servlet url-pattern -->
  <context-param>
    <param-name>resteasy.servlet.mapping.prefix</param-name>
    <param-value>/site</param-value>
  </context-param>

  <listener>
    <listener-class>
      org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
    </listener-class>
  </listener>

  <servlet>
    <servlet-name>resteasy-servlet</servlet-name>
    <description>JAX-RS Tools Generated - Do not modify</description>
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>resteasy-servlet</servlet-name>
    <url-pattern>/site/*</url-pattern>
  </servlet-mapping>
</web-app>

示例DTO类

@Entity
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement (name="node")
@XmlType(propOrder = { "id", "name", "description", "iconURL", "parentID", "active", "type"})
public class Node
implements Serializable{

  public enum Type{
    VIEW, ROOTNode, FOLDER, LEAF
  }

  @XmlAttribute
    @Id
    @GeneratedValue
    private Long id;
  @XmlAttribute
  private String name;
  @XmlAttribute
  private String description;
  @XmlAttribute
  private String iconURL;
  @XmlAttribute
  private long parentID;
  @XmlAttribute
  private boolean active;
  @XmlAttribute
    @Enumerated(EnumType.STRING)
  private Type type;

  public Node() {
    super();
  }

  public Node(String name, String description) {
    super();
    this.name = name;
    this.description = description;
  }

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }

  public String getIconURL() {
    return iconURL;
  }

  public void setIconURL(String iconURL) {
    this.iconURL = iconURL;
  }

  public long getParentID() {
    return parentID;
  }

  public void setParentID(long parentID) {
    this.parentID = parentID;
  }

  public boolean isActive() {
    return active;
  }

  public void setActive(boolean active) {
    this.active = active;
  }

  public Type getType() {
    return type;
  }

  public void setType(Type type) {
    this.type = type;
  }

}

更新2012/05/16

我还将jdbc驱动程序替换为persistence.xml中的com.google.appengine.api.rdbms.AppEngineDriver。仍然遇到相同的访问控制异常。

1 个答案:

答案 0 :(得分:2)

在persistence.xml中,尝试使用:

javax.persistence.jdbc.url = jdbc:google:rdbms://localhost/Site
javax.persistence.jdbc.driver = com.google.appengine.api.rdbms.AppEngineDriver

并将mysql jar(从http://dev.mysql.com/downloads/connector/j/下载)放入appengine-java-sdk-1.6.x / lib / impl

使用本地MySQL和JDO为我工作。