Skip to content
This repository has been archived by the owner on Jan 13, 2023. It is now read-only.

With Framework V2, trying to get an instance of EntityManagerFactory to be used with endpoint gives java.lang.NoClassDefFoundError #66

Closed
davemg3 opened this issue Oct 7, 2017 · 35 comments

Comments

@davemg3
Copy link

davemg3 commented Oct 7, 2017

Hi,
Uploading my backend to app engine servers after updating my project with Framework V2 gives me a java.lang.NoClassDefFoundError when i try to access to some instance of EntityManagerFactory.
I have a class EMF that i call :
`
public final class EMF {

private static final EntityManagerFactory emfInstance = Persistence
		.createEntityManagerFactory("transactions-optional");

private EMF() {
}

public static EntityManagerFactory get() {
	return emfInstance;
}

}
`
com.google.api.server.spi.SystemService invokeServiceMethod: exception occurred while calling backend method
java.lang.NoClassDefFoundError: Could not initialize class com.example.app.EMF

I thought SystemServiceServlet class was replaced by EndpointsServlet as in my web.xml so i dont understand why it is called

Google Cloud SDK 174.0.0
alpha 2017.09.15
app-engine-java 1.9.57
app-engine-python 1.9.61
bq 2.0.27
core 2017.10.02
gsutil 4.27

On V1 everything was fine.
Could it be close to other github issue :
#53

I created a post on SO on that :
https://stackoverflow.com/questions/46622757/with-framework-v2-trying-to-get-an-instance-of-entitymanagerfactory-to-be-used

Thanls

@loosebazooka
Copy link
Contributor

@tangiel ?

@tangiel
Copy link

tangiel commented Oct 9, 2017

Is this an error when using App Engine or dev server?

@davemg3
Copy link
Author

davemg3 commented Oct 9, 2017

It appeared when using App engine on cloud. My servlets are ok but not my endpoints.

@tangiel
Copy link

tangiel commented Oct 9, 2017

Can you show your web.xml?

@davemg3
Copy link
Author

davemg3 commented Oct 9, 2017

Ok here below 👍 :

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    version="2.5"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<filter>
    <filter-name>ObjectifyFilter</filter-name>
    <filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>ObjectifyFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
    <!-- Endpoints Frameworks V2: Start of v2 section -->
    <servlet-name>EndpointsServlet</servlet-name>
    <servlet-class>com.google.api.server.spi.EndpointsServlet</servlet-class>
    <!-- V2: End of v2 section -->

    <init-param>
        <param-name>services</param-name>
        <param-value>com.app.backend.RegistrationEndpoint,
            com.app.backend.MessagingEndpoint,
            com.example.app.ContactEndpoint,
            com.example.app.ContactImageEndpoint,
            com.example.app.CustomContactImageEndpoint,
            com.example.app.DeviceInfoEndpoint,
            com.example.app.GroupEndpoint,
            com.example.app.MessageEndpoint,
            com.example.app.feed.CustomShareItemDataEndpoint,
            com.example.app.feed.ShareItemDataIndexEndpoint
        </param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <!-- V2: Start of v2 section -->
    <servlet-name>EndpointsServlet</servlet-name>
    <url-pattern>/_ah/api/*</url-pattern>
    <!-- V2: End of v2 section -->

</servlet-mapping>

<servlet>
    <servlet-name>Register</servlet-name>
    <servlet-class>com.example.app.RegisterServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Register</servlet-name>
    <url-pattern>/register</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>Unregister</servlet-name>
    <servlet-class>com.example.app.UnregisterServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Unregister</servlet-name>
    <url-pattern>/unregister</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>Chat</servlet-name>
    <servlet-class>com.example.app.ChatServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Chat</servlet-name>
    <url-pattern>/chat</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>Custom2</servlet-name>
    <servlet-class>com.example.app.feed.Custom2</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Custom2</servlet-name>
    <url-pattern>/custom2</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>Group</servlet-name>
    <servlet-class>com.example.app.GroupServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Group</servlet-name>
    <url-pattern>/group</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>Friend</servlet-name>
    <servlet-class>com.example.app.feed2.FriendsTableQuery</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Friend</servlet-name>
    <url-pattern>/friend</url-pattern>
</servlet-mapping>


<servlet>
    <servlet-name>Admin</servlet-name>
    <servlet-class>com.example.app.feed2.AdminServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Admin</servlet-name>
    <url-pattern>/admin</url-pattern>
</servlet-mapping>


<servlet>
    <servlet-name>MeContentRefresh</servlet-name>
    <servlet-class>com.example.app.feed2.MeContentRefreshServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>MeContentRefresh</servlet-name>
    <url-pattern>/me/content/onRefresh</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>MeCommentDelete</servlet-name>
    <servlet-class>com.example.app.feed2.MeCommentDeleteServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>MeCommentDelete</servlet-name>
    <url-pattern>/me/comment/delete</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>LanguageService</servlet-name>
    <servlet-class>com.example.app.Language.LanguageServiceServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>LanguageService</servlet-name>
    <url-pattern>/me/language/analyse/entity</url-pattern>
</servlet-mapping>



<servlet>
    <servlet-name>Init</servlet-name>
    <servlet-class>com.example.app.InitServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Init</servlet-name>
    <url-pattern>/init</url-pattern>
</servlet-mapping>



<welcome-file-list>
    <welcome-file>index.html</welcome-file>
</welcome-file-list>

@davemg3
Copy link
Author

davemg3 commented Oct 9, 2017

I tried to go back to V1 endpoint but the update in backend dependencies cause now duplicate file exception for all files com/google/appengine/repackaged/org/apache/commons/codec/language/....txt found it seems in appengine-api-1.0-sdk and also in appengine-endpoints dependencies.
(which is strange given that i import only com.google.appengine:appengine-endpoints:1.9.56' which itself has a dependency on appengine-api-1.0-sdk). Exclude compile or packagingOptions { exclude...} doesnot solve it....

...but sorry lets go back to this issue on V2...:)

@tangiel
Copy link

tangiel commented Oct 9, 2017

Ah, I was a little thrown off. It's not SystemServiceServlet logging the error, but SystemService, which is totally fine. So it seems somehow your EMF class is not being included in your app deployment. Have you done a clean build since the migration? If not, try that. Otherwise, you need to double check that your app is being packaged correctly.

@davemg3
Copy link
Author

davemg3 commented Oct 9, 2017

What do you mean by i need to doublecheck my app is packaged correctly?what is the process for that?...cause already i did so many restart of AS, re-install of gradle, clean, invalidate caches and build either by android studio or command...for server side the deployment on app engine by the command is successful ...but even if the client build is marked as successful, no apk is deployed on device by command line so i have to use Android Studio command to launch and deploy the build of client on device... (I know with V2 we should not use AS for deploying on app engine but is it ok to use it for building client?)...
Thanks for help cause i am kinda of stuck now (V2 is not working and impossible to go back to V1 due to all these new duplicated files cause by appengine dependencies)

@tangiel
Copy link

tangiel commented Oct 9, 2017

If you do a command line gradle build, then you should be able to find the EMF class in your Endpoints app's build directory. There should be a directory containing your web app, and EMF should either be in WEB-INF/classes or inside of a JAR in WEB-INF/lib.

@davemg3
Copy link
Author

davemg3 commented Oct 9, 2017

Indeed it in the following red classed 👍 ...but still exception on app engine server
i did clean, build, gradlew endpointsClientLibs and gradlew appengineDeploy

@davemg3
Copy link
Author

davemg3 commented Oct 9, 2017

image

@tangiel
Copy link

tangiel commented Oct 9, 2017

Can you also double check that there's not an inner stack trace for the NoClassDefFoundError? It actually looks like the EMF class is found, it just can't be initialized. Which likely means something is wrong emfInstance initialization.

@mpoehler
Copy link

It is not related to #53 . #53 only occurs on the devserver and is fixed with the latest Google Cloud SDK version (174.0.0) you are already using.

@davemg3
Copy link
Author

davemg3 commented Oct 10, 2017

@tangiel , i dont see how to get more log from google console...otherwise i got the same issue for all endpoints or servlets calling this entitymanagerfactory. Is there a way to get more outputs?

2017-10-10 (15:09:52.925) Uncaught exception from servlet java.lang.NoClassDefFoundError: Could not initialize class com.example.staffbeta1.EMF at com.example.app.CustomContactImageEndpoint.getEntityManager(CustomContactImageEndpoint.java:585) at com.example.app.CustomContactImageEndpoint.findContactImagesMoment(CustomContactImageEndpoint.java:79) at com.example.app.ContactImageServlet.doGetImpl(ContactImageServlet.java:33) at com.example.app.feed2.WPHttpServlet.doGet(WPHttpServlet.java:41) at javax.servlet.http.HttpServlet.service(HttpServlet.java:617) 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.googlecode.objectify.cache.AsyncCacheFilter.doFilter(AsyncCacheFilter.java:58) at com.googlecode.objectify.ObjectifyFilter.doFilter(ObjectifyFilter.java:48) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:37) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:48) 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.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:257) 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 com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76) at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:146) at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.dispatchServletRequest(JavaRuntime.java:680) at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.dispatchRequest(JavaRuntime.java:642) at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:612) at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:454) at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:461) at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:297) at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:320) at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:312) at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:458) at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:274) at java.lang.Thread.run(Thread.java:745) request_id: "59dcc69f00ff0dc24abd77a6f40001737e6d6773746166663839000132000100" timestamp: "2017-10-10T13:09:52.925Z"

@davemg3
Copy link
Author

davemg3 commented Oct 10, 2017

Something which can be useful ; gradle tells me Some files were skipped. Pass --verbosity=info to see which ones (see log below). It seems all files in web-inf are skipped during deployment and gradle indeed now states :

INFO: We detected that you have a large number of .class files in WEB-INF/classes. You may be able to reduce request latency by packaging your .class files into jars. To do this, supply the --enable_jar_classes flag when using appcfg on command line. If you're using the Cloud SDK based app-maven-plugin, add <stage.enableJarClasses>true</stage.enableJarClasses> in the plugin's tag. If you are using the AppCfg based appengine-maven-plugin, supply true in the plugin's tag. Note that this flag will put the jar in WEB-INF/lib rather than WEB-INF/classes. The classloader first looks in WEB-INF/classes and then WEB-INF/lib when loading a class. As a result, this flag could change classloading order, which may affect the behavior of your app.

deployment log 15.47.59.096000.log

@davemg3
Copy link
Author

davemg3 commented Oct 10, 2017

deployment 16.45.18.098000.log

So i added in my build

stage {
enableJarClasses = true
}

You can see in my log all class with endpoint and servlet in WEB-INF/classes seem to be uploaded but not the WEB-INF/lib .jar
so now i have consequently other different exception thrown as ;


2017-10-10 (16:14:17.201)
WPHttpServlet.java:40
com.example.staffbeta1.feed2.WPHttpServlet doGet: JSON: has 5
2017-10-10 (16:14:16.414)
Uncaught exception from servlet
Class Contact for query has not been resolved. Check the query and any imports/aliases specification
org.datanucleus.exceptions.ClassNotResolvedException: Class Contact for query has not been resolved. Check the query and any imports/aliases specification
at org.datanucleus.query.compiler.JavaQueryCompiler.resolveClass(JavaQueryCompiler.java:906)
at org.datanucleus.query.compiler.JavaQueryCompiler.compileFrom(JavaQueryCompiler.java:218)
at org.datanucleus.query.compiler.JPQLCompiler.compile(JPQLCompiler.java:79)
at org.datanucleus.store.query.AbstractJPQLQuery.compileInternal(AbstractJPQLQuery.java:271)
at org.datanucleus.store.query.Query.setImplicitParameter(Query.java:799)
at org.datanucleus.api.jpa.JPAQuery.setParameter(JPAQuery.java:437)
at org.datanucleus.api.jpa.JPAQuery.setParameter(JPAQuery.java:57)
at com.example.staffbeta1.Contact.byEmailFind(Contact.java:245)
at com.example.staffbeta1.RegisterServlet.doPost(RegisterServlet.java:95)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
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.googlecode.objectify.cache.AsyncCacheFilter.doFilter(AsyncCacheFilter.java:58)
at com.googlecode.objectify.ObjectifyFilter.doFilter(ObjectifyFilter.java:48)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:37)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:48)
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.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:257)
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 com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:146)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.dispatchServletRequest(JavaRuntime.java:680)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.dispatchRequest(JavaRuntime.java:642)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:612)
at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:454)
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:461)
at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:297)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:320)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:312)
at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:458)
at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:274)
at java.lang.Thread.run(Thread.java:745)

@patflynn
Copy link

@davemg3 Are you using Objectify and JPA in the same application?

@davemg3
Copy link
Author

davemg3 commented Oct 10, 2017

Oh...it something i need to clean indeed (it was there since a while cause i wanted to adapt a MessagingEndpoint sample class which use it at the beginning)...could be a cause?

I removed it and now i passed from 1 file to 2 files uploaded on GAE but still a lot of skipped WEB-INF/lib .jar
deployed 17.58.52.113000.log

@patflynn
Copy link

@davemg3 I think the skipped lib libraries at deployment is normal. It just means they've already been uploaded and so we don't do it again. If you deploy to a new project you should see them all go up.

I'm wondering if your config is just slightly wrong somewhere. For instance using Objectify I wouldn't expect to be using the EntityManagerFactory. I have an example app I setup a while back to validate Objectify and Endpoints Framework work together with our new tooling, you may want to take a look to see if anything stands out.

@davemg3
Copy link
Author

davemg3 commented Oct 10, 2017

Sorry I was not clear...my code on server is 29% endpoint with JPA, 70% servlet with datastore/entity (progressively giving up endpoints) and there was this 1% code unsused with Objectify. In previous post , i tried with removing the code with Objectify but still failure...

This time i deleted the instance of GAE and deployed another incremented version : in this case you still think it should be normal lib-lbraries are not deployed? I got still exceptions
deployment 19.10.27.341000.log

On one servlet for example:
org.datanucleus.NucleusContext getValidationHandler: Unable to create validator handler javax.validation.ValidationException: Unable to create a Configuration, because no Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath. at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:271) at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:110) at org.datanucleus.NucleusContext.getValidationHandler(NucleusContext.java:1067) at org.datanucleus.api.jpa.JPAEntityManager.<init>(JPAEntityManager.java:138) at org.datanucleus.api.jpa.JPAEntityManagerFactory.newEntityManager(JPAEntityManagerFactory.java:564) at org.datanucleus.api.jpa.JPAEntityManagerFactory.createEntityManager(JPAEntityManagerFactory.java:529) at com.example.app1.CustomContactImageEndpoint.getEntityManager(CustomContactImageEndpoint.java:585) at com.example.app1.CustomContactImageEndpoint.findContactImagesMoment(CustomContactImageEndpoint.java:79) at com.example.app1.ContactImageServlet.doGetImpl(ContactImageServlet.java:33)....

On another one ;
Uncaught exception from servlet Class Contact for query has not been resolved. Check the query and any imports/aliases specification org.datanucleus.exceptions.ClassNotResolvedException: Class Contact for query has not been resolved. Check the query and any imports/aliases specification at org.datanucleus.query.compiler.JavaQueryCompiler.resolveClass(JavaQueryCompiler.java:906) at org.datanucleus.query.compiler.JavaQueryCompiler.compileFrom(JavaQueryCompiler.java:218) at org.datanucleus.query.compiler.JPQLCompiler.compile(JPQLCompiler.java:79) at org.datanucleus.store.query.AbstractJPQLQuery.compileInternal(AbstractJPQLQuery.java...

so now I am not wondering f it is still the same issue i am trying to track down or this time it is another one related to datanucleus. I understood from SO question that datanucleus/ JPA/en hancer are not yet supported by V2. But there was a work around that i implemented ;

`task datanucleusEnhance {//https://stackoverflow.com/questions/45493314/enhancing-endpoints-in-cloud-endpoints-frameworks-2-0-for-app-engine?noredirect=1&lq=1

description "Enhance JPA 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.tools.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: "JPA") {
        entityFiles.addToAntBuilder(ant, 'fileset', FileCollection.AntType.FileSet)
    }
}

}

classes.dependsOn(datanucleusEnhance)
`

@patflynn
Copy link

patflynn commented Oct 10, 2017 via email

@davemg3
Copy link
Author

davemg3 commented Oct 10, 2017

Ok i need to understand your gradle indeed...cause i feel it doest look like you migrated as per instructions : https://cloud.google.com/endpoints/docs/frameworks/legacy/v1/java/migrating.
Is there a half way? i.e implement all com.google.cloud.tools:appengine-gradle-plugin:1.3.2 related but not the com.google.cloud.tools:endpoints-framework-gradle-plugin:1.0.0 related stuff. I am kind of stuck, i need to dig out what new things this V2 dependencies bring which makes me fail...
Thanks for the link, i will check and try other ways...

if i could go back to 'com.google.appengine:gradle-appengine-plugin:1.9.56' i would do it...(in fact in parallel i tried to go roll back but now that my dependencies are at 1.9.56 i got a lot of issues as this one https://stackoverflow.com/questions/46554771/cannot-find-symbol-method-setbatchpathstring-in-the-generated-source-from-ge or other duplicates files exception)

@patflynn
Copy link

patflynn commented Oct 10, 2017 via email

@patflynn
Copy link

@davemg3 Did you try the suggestion from the stacktrace to include Hibernate Validator on the classpath?

@davemg3
Copy link
Author

davemg3 commented Oct 11, 2017

compile group: 'org.hibernate', name: 'hibernate-validator', version: '6.0.2.Final' gives me an exception on console and i cannot deploy Caused by: com.google.cloud.tools.appengine.api.AppEngineException: Non zero exit: 1 at com.google.cloud.tools.appengine.cloudsdk.process.NonZeroExceptionExitListener.onExit(NonZeroExceptionExitListener.java:30)

compile group: 'org.hibernate', name: 'hibernate-validator', version: '4.1.0.Final' brings some change with deployment successful but with a new exception in servlet:
/register Class Contact for query has not been resolved. Check the query and any imports/aliases specification org.datanucleus.exceptions.ClassNotResolvedException: Class Contact for query has not been resolved. Check the query and any imports/aliases specification at org.datanucleus.query.compiler.JavaQueryCompiler.resolveClass(JavaQueryCompiler.java:906) at org.datanucleus.query.compiler.JavaQueryCompiler.compileFrom(JavaQueryCompiler.java:218) at org.datanucleus.query.compiler.JPQLCompiler.compile(JPQLCompiler.java:79) at org.datanucleus.store.query.AbstractJPQLQuery.compileInternal(AbstractJPQLQuery.java:271)

But I am still curious ; you think it is ok to have all these skipped WEB-INF/lib .jar, even for uploading of a new version? Seeing in gradle console "Uploading 0 files to Google Cloud Storage" seems suspect...
When a simple servlet is call (no endpoint or call to datastore linked) i got :
Apache-HttpClient/UNAVAILABLE (java 1.4)
com.app.staffbeta1.feed2.ExtendedHttpServlet getStringParameter: getStringParameter strValue <html><head> (ExtendedHttpServlet.java:224) <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>500 Server Error</title> </head> <body text=#000000 bgcolor=#ffffff> <h1>Error: Server Error</h1> <h2>The server encountered an error and could not complete your request.<p>Please try again in 30 seconds.</h2> <h2></h2> </body></html>

I feel the root on my issue is somewhere else

@patflynn
Copy link

@davemg3 assuming none of those lib files have changed it seems normal to me. You can verify by deploying to a new GCP project. You should see all the files being uploaded.

For your ClassNotResolvedException you may want to check out this link: https://stackoverflow.com/questions/15297363/google-app-engine-1-7-5-org-datanucleus-exceptions-classnotresolvedexception

Hopefully it'll help. I highly recommend porting your JDO based classes to Objectify.

@davemg3
Copy link
Author

davemg3 commented Oct 11, 2017

Thank you for the link . I tried the solution disabling the auto scanning of entities and explicitly telling which classes to load while building PersistenceUnit will not help for me but i sends me back to previous message (before manual setting of JPA in gradle):

org.datanucleus.metadata.MetaDataManager initialiseFileMetaDataForUse: Found Meta-Data for class com.example.app.Contact but this class is not enhanced!! Please enhance the class before running DataNucleus. (MetaDataManager.java:1144) org.datanucleus.exceptions.NucleusUserException: Found Meta-Data for class com.example.staffbeta1.Contact but this class is not enhanced!! Please enhance the class before running DataNucleus. at org.datanucleus.metadata.MetaDataManager.initialiseClassMetaData(MetaDataManager.java:2593)

Looks like i am in a dead end.I will try your suggestion.
Indeed i understood in my research Objectify was recommended by google instead of JPA/JDO.I was hoping not to have to rewrite my code without knowing the cause of failure

@davemg3
Copy link
Author

davemg3 commented Oct 12, 2017

Last question about your advice ; is there a reason no docs on Android Client+call to endpoints+endpoints+Objectify (to replace the JPA/JDO way)? For web app yes but not even a statement about integration with Android

@patflynn
Copy link

patflynn commented Oct 12, 2017 via email

@davemg3
Copy link
Author

davemg3 commented Oct 16, 2017

Hi.
For those passing by, I didnt find the source of discussed Error with JPA/JDOand migrated successfully to FrameWork V2 with Objectivity and servlet so the topic can be close. Thanks for help
For now my endpoints of new backend send to Client : com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
and Api Explorer https://apis-explorer.appspot.com/apis-explorer/ doesnt update list of Endpoints accordingly, so there might be a changes to be done which has not been specified yet in google cloud documentation and tutorial. (I will test with the sample repository)

@patflynn
Copy link

@frankyn

@frankyn
Copy link
Member

frankyn commented Oct 26, 2017

@patflynn, I didn't understand the request of what should be updated.

@patflynn
Copy link

@frankyn nothing specifically. Just was an FYI that @davemg3 seems to be seeing serving errors when trying to follow the docs.

@tangiel
Copy link

tangiel commented Dec 5, 2017

@davemg3 have you tried deploying to a new App Engine version? If you're seeing an old list of Endpoints, this could be a known issue.

@davemg3
Copy link
Author

davemg3 commented Dec 6, 2017

Hello @tangiel ,
It seems my exception launched on app engine was due to some endpoint classes (my last implementation was using Framework V2, objectify and servlets/endpoints) written as below ;

Not working :
` @apimethod(
name = "getContact",
path = "getContact/{chatId}", //putting chatId in path causes the endpoint didnt work
httpMethod = ApiMethod.HttpMethod.GET)
public Contact getContact(@nAmed("chatId") String chatId) {...

Working:
@apimethod(
name = "getContact",
path = "getContact",
httpMethod = ApiMethod.HttpMethod.GET)
public Contact getContact(@nAmed("chatId") String chatId) {...`

(The formatting on github is not proper for @nAmed but nothing related with my code)
When above change was done, everything started working well since

Thanks for support!

@davemg3 davemg3 closed this as completed Dec 6, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants