Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Migrated JDO project to google cloud endpoints v2, server returns NoClassDefFoundError

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!

like image 438
juanmeanwhile Avatar asked Aug 12 '18 12:08

juanmeanwhile


2 Answers

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.

like image 146
Ying Li Avatar answered Nov 11 '22 09:11

Ying Li


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.

like image 24
Jacob Beacham Avatar answered Nov 11 '22 08:11

Jacob Beacham