0

I'm trying to implement JPA with groovy/gaelyk for Google App Engine. My environment:

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>

src/Post.groovy under com.sample.gaelyk2

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'
}

I got the following exception when running localhost:8888/welcom_db.groovy from the browser. I don't have this problem when I implement the whole thing in 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

I've been googleing for the last 2 weeks, but I could not find the solution. I suspected the problem is with Groovy Class Loader, but I don't know how to fix it.

The confusion is at the bottom of the stack trace I had the following:

file:/C:/Users/myuser/Documents/workspace/GaeAppGaelyk2/war/WEB-INF/classes/_Post1Demo login successful

Thanks.

user2618844
  • 352
  • 3
  • 13

2 Answers2

1

If you need to use JPA for any reason instead of built in datastore entities support you should write your entities in Java which is 100% interoperable with Groovy. DataNucleus which is used as JPA implementation needs to instrument the classes and it's obviously unable to do it for compiled Groovy classes. You can still use Groovy and Gaelyk for the rest of your code.

musketyr
  • 808
  • 5
  • 16
0

Here is my revised java class:

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

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' %> 
user2618844
  • 352
  • 3
  • 13