【问题标题】:Can't implement JPA groovy class in Google App Engine无法在 Google App Engine 中实现 JPA groovy 类
【发布时间】:2014-03-15 06:02:52
【问题描述】:

我正在尝试使用 groovy/gaelyk 为 Google App Engine 实现 JPA。我的环境:

IDE:Eclipse Kepler SR2
groovy-all-2.0.7.jar
gaelyk-2.0.jar
Google App Engine SDK-1.9.0
MySQL

persistence.xml

<persistence-unit name="Post1Demo">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <!-- We are using JPA provided by Eclipselink -->
    <!-- Post.groovy class is in the project's package -->
    <class>com.sample.gaelyk2.Post</class>
    <exclude-unlisted-classes/>
    <properties>
        <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
        <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/test" />
        <property name="javax.persistence.jdbc.user" value="myname" />
        <property name="javax.persistence.jdbc.password" value="mypassword" />

    </properties>


</persistence-unit>

com.sample.gaelyk2下的src/Post.groovy

package com.sample.gaelyk2

import java.io.Serializable;
import javax.persistence.*

@Entity
@Table(name="post")
class Post implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long COLID

String body
String timestamp
String title
}

WEB-INF/groovy/welcome_db.groovy

import javax.persistence.EntityManager
import javax.persistence.Query
import javax.persistence.EntityManagerFactory
import javax.persistence.Persistence

import com.sample.gaelyk2.Post

try {
String PERSISTENCE_UNIT_NAME = "Post1Demo"      // see persistence.xml

factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME)
EntityManager em = factory.createEntityManager()

THE PROBLEM IS RIGHT HEREEEEEE.......

Query q = em.createQuery("from Post")       // MUST match class name, case sensitive
def postList = q.getResultList()


//
// Fill up the request and forward it to index_db.gtpl
//
request.setAttribute 'posts', postList
forward 'index_db.gtpl' 
} catch (Throwable t) {
println "Error in welcome_db"
forward 'index_db.gtpl'
}

从浏览器运行 localhost:8888/welcom_db.groovy 时出现以下异常。 当我在java中实现整个事情时,我没有这个问题。

SEVERE: Unable to instrument com.sample.gaelyk2.Post. Security restrictions may not be entirely emulated.
java.lang.ArrayIndexOutOfBoundsException: 271
at com.google.appengine.repackaged.org.objectweb.asm.ClassReader.readLabel(ClassReader.java:1880)
at com.google.appengine.repackaged.org.objectweb.asm.ClassReader.readFrameType(ClassReader.java:1860)
at com.google.appengine.repackaged.org.objectweb.asm.ClassReader.readFrame(ClassReader.java:1794)
at com.google.appengine.repackaged.org.objectweb.asm.ClassReader.readCode(ClassReader.java:1214)
at com.google.appengine.repackaged.org.objectweb.asm.ClassReader.readMethod(ClassReader.java:938)
at com.google.appengine.repackaged.org.objectweb.asm.ClassReader.accept(ClassReader.java:669)
at com.google.appengine.repackaged.org.objectweb.asm.ClassReader.accept(ClassReader.java:506)
at com.google.appengine.tools.development.agent.impl.Transformer.rewrite(Transformer.java:146)
at com.google.appengine.tools.development.agent.impl.Transformer.transform(Transformer.java:113)
at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:424)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at com.google.appengine.tools.development.IsolatedAppClassLoader.loadClass(IsolatedAppClassLoader.java:216)
at java.lang.ClassLoader.loadClass(ClassLoader.java:412)
at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:648)
at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:516)
at org.codehaus.groovy.control.ClassNodeResolver.tryAsLoaderClassOrScript(ClassNodeResolver.java:183)
at org.codehaus.groovy.control.ClassNodeResolver.findClassNode(ClassNodeResolver.java:168)
at groovy.util.GroovyScriptEngine$ScriptClassLoader$3.findClassNode(GroovyScriptEngine.java:211)
at org.codehaus.groovy.control.ClassNodeResolver.resolveName(ClassNodeResolver.java:124)
at org.codehaus.groovy.control.ResolveVisitor.resolveToOuter(ResolveVisitor.java:616)
at org.codehaus.groovy.control.ResolveVisitor.resolve(ResolveVisitor.java:268)
at org.codehaus.groovy.control.ResolveVisitor.visitClass(ResolveVisitor.java:1133)
at org.codehaus.groovy.control.ResolveVisitor.startResolving(ResolveVisitor.java:141)
at org.codehaus.groovy.control.CompilationUnit$9.call(CompilationUnit.java:624)
at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:903)
at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:566)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:515)
at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:279)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:258)
at groovy.util.GroovyScriptEngine$ScriptClassLoader.doParseClass(GroovyScriptEngine.java:247)
at groovy.util.GroovyScriptEngine$ScriptClassLoader.parseClass(GroovyScriptEngine.java:229)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:244)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:202)
at groovy.util.GroovyScriptEngine.loadScriptByName(GroovyScriptEngine.java:514)
at groovy.util.GroovyScriptEngine.createScript(GroovyScriptEngine.java:564)
at groovy.util.GroovyScriptEngine.run(GroovyScriptEngine.java:551)
at groovyx.gaelyk.GaelykServlet.runGroovlet(GaelykServlet.groovy:154)
at groovyx.gaelyk.GaelykServlet.doService(GaelykServlet.groovy:118)
at groovyx.gaelyk.GaelykServlet.service(GaelykServlet.groovy:87)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:127)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:63)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:366)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:349)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:98)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:487)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:547)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)


[EL Info]: 2014-03-15 01:21:04.538--ServerSession(1464126150)--EclipseLink, version: Eclipse Persistence Services - 2.5.0.v20130507-3faac2b
[EL Info]: connection: 2014-03-15 01:21:05.859--ServerSession(1464126150)--file:/C:/Users/myuser/Documents/workspace/GaeAppGaelyk2/war/WEB-INF/classes/_Post1Demo login successful
Mar 15, 2014 1:21:06 AM com.google.appengine.tools.development.ApiProxyLocalImpl log
INFO: javax.servlet.ServletContext log: TemplateServlet: Servlet groovyx.gaelyk.GaelykTemplateServlet initialized on class groovy.text.SimpleTemplateEngine

过去 2 周我一直在用 Google 搜索,但找不到解决方案。我怀疑问题出在 Groovy 类加载器上,但我不知道如何解决。

混乱是在堆栈跟踪的底部我有以下内容:

file:/C:/Users/myuser/Documents/workspace/GaeAppGaelyk2/war/WEB-INF/classes /_Post1Demo登录成功

谢谢。

【问题讨论】:

    标签: eclipse google-app-engine jpa groovy gaelyk


    【解决方案1】:

    如果您出于任何原因需要使用 JPA 而不是内置的数据存储实体支持,您应该使用与 Groovy 100% 可互操作的 Java 编写实体。用作 JPA 实现的 DataNucleus 需要对类进行检测,对于已编译的 Groovy 类显然无法做到这一点。您仍然可以在其余代码中使用 Groovy 和 Gaelyk。

    【讨论】:

    • 我将尝试在 java 中实现该类并在 groovy 中使用它。我稍后会在这里报告结果。谢谢。
    【解决方案2】:

    这是我修改后的 java 类:

    Postj2.java

    package com.sample.gaelyk2;
    
    import java.io.Serializable;
    import java.util.Date;
    
    import javax.persistence.Entity;
    import javax.persistence.Transient;
    import javax.persistence.Table;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.Temporal;
    import javax.persistence.TemporalType;
    
    @Entity
    @Table(name="post")
    public class Postj2 implements Serializable {
    
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)     // GenerationType.SEQUENCE
    private Long ID;
    
    private String BODY;
    @Temporal(TemporalType.DATE)
    
    private Date TIME_STAMP;
    
    private String TITLE;   
    
    @Transient 
    protected Object[] jdoDetachedState; 
    
    
    public Long getID() {
        return ID;
    }
    
    public void setID(Long id) {
        this.ID = id;
    }
    
    public String getTITLE() {
        return TITLE;
    }
    
    public void setTITLE(String title) {
        this.TITLE = title;
    }
    
    public String getBODY() {
        return BODY;
    }
    
    public void setBODY(String body) {
        this.BODY = body;
    }
    
    public Date getTIME_STAMP() {
        return TIME_STAMP;
    }
    
    public void setTIME_STAMP(Date timestamp) {
        this.TIME_STAMP = timestamp;
    }
    
    }
    

    创建表格

    CREATE TABLE `post` (
    `ID` bigint(20) NOT NULL AUTO_INCREMENT,
    `BODY` varchar(255) DEFAULT NULL,
    `TIME_STAMP` date DEFAULT NULL,
    `TITLE` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`ID`)
    ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
    

    welcome_db.groovy

    import javax.persistence.EntityManager
    import javax.persistence.Query
    import javax.persistence.EntityManagerFactory
    import javax.persistence.Persistence
    
    import com.sample.gaelyk2.Postj
    
    try {
    String PERSISTENCE_UNIT_NAME = "Post1Demo"      // see persistence.xml
    
    factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME)
    EntityManager em = factory.createEntityManager()
    
    Query q = em.createQuery("select t from Postj2 t")      // MUST match class name, case sensitive
    
    def postList = q.getResultList()
    
    //
    // Fill up the request and forward it to index_db.gtpl
    //
    request.setAttribute 'posts', postList
    forward 'index_db.gtpl' 
    } catch (Throwable t) {
    
    forward 'index_db.gtpl'
    }
    

    index_db.groovy

    <% include '/WEB-INF/includes/header.gtpl' %>
    <% import java.text.SimpleDateFormat %>
    <% def formatter = new SimpleDateFormat("MM/dd/yy") %>
    <% def posts = request.getAttribute('posts') %>
    
    <% if(posts) { %>
    <div class="info">
    <h2>Message Post</h2>
    </div>
    <table>
    <tr>    
    <th>Title</th>
    <th>Message</th>
    <th width=60>Date</th>  
    </tr>
    <% posts.each { post -> %>      
      <tr>      
        <td>${post.TITLE} </td>
        <td>${post.BODY}</td>
        <td>${formatter.format(post.TIME_STAMP)}</td>
      </tr>     
    <%}%>
    </table>
    <%}else{%>
     There are no messages in the system.
    <%}%>
    
    <% include '/WEB-INF/includes/footer_db.gtpl' %> 
    

    【讨论】:

      猜你喜欢
      • 2011-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-11
      相关资源
      最近更新 更多