I've tried to migrate a google cloud project using JDO from endpoints v1 to v2. I've followed the migration guide and some solutions here to try to make the datanucleous plugin enhance my classes, and upload them to the google cloud, but there is no luck.
I'm gonna post the build.gradle followed by the server error returned when a client tries to connect to an endpoint, which is a NoClassFound error.
build.gradle:
buildscript {
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
// App Engine Gradle plugin
classpath 'com.google.cloud.tools:appengine-gradle-plugin:1.3.3'
// Endpoints Frameworks Gradle plugin
classpath 'com.google.cloud.tools:endpoints-framework-gradle-plugin:1.0.2'
}
}
repositories {
mavenCentral();
jcenter()
}
apply plugin: 'java'
apply plugin: 'war'
// [START apply_plugins]
apply plugin: 'com.google.cloud.tools.appengine'
apply plugin: 'com.google.cloud.tools.endpoints-framework-server'
// [END apply_plugins]
dependencies {
compile ('com.google.endpoints:endpoints-framework:2.0.8') {
exclude group: 'com.google.guava', module: 'guava-jdk5'
}
compile 'javax.servlet:servlet-api:2.5'
compile 'com.ganyo:gcm-server:1.0.2'
compile 'javax.jdo:jdo-api:3.0.1'
compile 'org.datanucleus:datanucleus-core:3.1.3'
compile 'org.datanucleus:datanucleus-api-jdo:3.1.3'
compile 'org.datanucleus:datanucleus-accessplatform-jdo-rdbms:4.1.1'
compile 'com.google.appengine.orm:datanucleus-appengine:2.1.2'
compile 'com.google.code.gson:gson:2.2.4'
compile 'org.apache.commons:commons-lang3:3.5'
}
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
appengine { // App Engine tasks configuration
deploy { // deploy configuration
version = findProperty("appengine.deploy.version")
def promoteProp = findProperty("appengine.deploy.promote")
if (promoteProp != null) {
promote = new Boolean(promoteProp)
}
}
}
endpointsServer {
// Endpoints Framework Plugin server-side configuration
hostname = "komilibro.appspot.com"
}
task datanucleusEnhance {
description "Enhance JDO model classes using DataNucleus Enhancer"
dependsOn processResources
doLast {
// define the entity classes
def entityFiles = fileTree(sourceSets.main.output.classesDir).matching {
include 'com/meanwhile/komi/head/**/*.class'
}
println "Enhancing with DataNucleus the following files"
entityFiles.getFiles().each {
println it
}
// define Ant task for DataNucleus Enhancer
ant.taskdef(
name : 'datanucleusenhancer',
classpath : sourceSets.main.runtimeClasspath.asPath,
classname : 'org.datanucleus.enhancer.EnhancerTask'
// the below is for DataNucleus Enhancer 3.1.1
//classname : 'org.datanucleus.enhancer.tools.EnhancerTask'
)
// run the DataNucleus Enhancer as an Ant task
ant.datanucleusenhancer(
classpath: sourceSets.main.runtimeClasspath.asPath,
verbose: true,
api: "JDO") {
entityFiles.addToAntBuilder(ant, 'fileset', FileCollection.AntType.FileSet)
}
}
}
classes.dependsOn(datanucleusEnhance)
Taking a look to the server logs after a user request, I can see two errors: first:
org.datanucleus.store.types.TypeManagerImpl loadJavaTypes: User-defined type
mapping class "org.datanucleus.store.types.sco.simple.Collection" was not found.
Please check the mapping file class specifications and your CLASSPATH. The class
must be in the CLASSPATH.
And this is the second. PMF is just a class used to load and instance of the PersistenceManager.
com.google.api.server.spi.SystemService invokeServiceMethod: exception occurred while calling backend method (SystemService.java:375)
java.lang.NoClassDefFoundError: Could not initialize class com.meanwhile.komi.head.PMF
So, seems like the classes needed are not in place, but also the TypeManagerImpl does not find the Collection class (default java Collection is used in the endpoints). I'm a little lost here, so help is really welcome.
Thanks!
Add this in your gradle build file:
task datanucleusEnhance {
description "Enhance JDO model classes using DataNucleus Enhancer"
dependsOn compileJava
doLast {
// define the entity classes
def entityFiles = fileTree(sourceSets.main.output.classesDir).matching {
include 'com/mycom/*.class', 'org/myorg/*.class'
}
println "Enhancing with DataNucleus the following files"
entityFiles.getFiles().each {
println it
}
// define Ant task for DataNucleus Enhancer
ant.taskdef(
name : 'datanucleusenhancer',
classpath : sourceSets.main.runtimeClasspath.asPath,
classname : 'org.datanucleus.enhancer.EnhancerTask'
// the below is for DataNucleus Enhancer 3.1.1
//classname : 'org.datanucleus.enhancer.tools.EnhancerTask'
)
// run the DataNucleus Enhancer as an Ant task
ant.datanucleusenhancer(
classpath: sourceSets.main.runtimeClasspath.asPath,
verbose: true,
api: "JDO") {
entityFiles.addToAntBuilder(ant, 'fileset', FileCollection.AntType.FileSet)
}
}
}
classes.dependsOn(datanucleusEnhance)
The entityFiles is where you configure your JPA entity annotated classes.
At the very end of this migration page, there is a section labeled "Issues with JPA/JDO Datanucleus enhancement," which links to a StackOverflow example with a working gradle configuration for Datanucleus. I would look very closely for any differences between this canonical example and your own gradle build file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With