0

I have a Maven Google App Engine Java Project which uses JAX-RS web services. When the project is deployed on Google Cloud Platform sometimes I get a 500 Server Error response when accessing /api/sites.

    org.eclipse.jetty.servlet.ServletHandler doHandle:  (ServletHandler.java:624)
javax.servlet.ServletException: java.lang.NullPointerException
    at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:432)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:370)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:848)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1772)
    at com.googlecode.objectify.ObjectifyFilter.doFilter(ObjectifyFilter.java:48)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
    at ro.h23.pricechecker.productgaewebserver.filters.URLFilter.doFilter(URLFilter.java:64)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
    at com.googlecode.objectify.ObjectifyFilter.doFilter(ObjectifyFilter.java:48)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
    at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:582)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:524)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
    at com.google.apphosting.runtime.jetty9.ParseBlobUploadHandler.handle(ParseBlobUploadHandler.java:120)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1182)
    at com.google.apphosting.runtime.jetty9.AppEngineWebAppContext.doHandle(AppEngineWebAppContext.java:171)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:512)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at com.google.apphosting.runtime.jetty9.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:297)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
    at org.eclipse.jetty.server.Server.handle(Server.java:534)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320)
    at com.google.apphosting.runtime.jetty9.RpcConnection.handle(RpcConnection.java:202)
    at com.google.apphosting.runtime.jetty9.RpcConnector.serviceRequest(RpcConnector.java:81)
    at com.google.apphosting.runtime.jetty9.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:123)
    at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.dispatchServletRequest(JavaRuntime.java:693)
    at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.dispatchRequest(JavaRuntime.java:655)
    at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:625)
    at com.google.apphosting.runtime.JavaRuntime$NullSandboxRequestRunnable.run(JavaRuntime.java:819)
    at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:274)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
    at org.glassfish.jersey.jackson.internal.FilteringJacksonJaxbJsonProvider.writeTo(FilteringJacksonJaxbJsonProvider.java:130)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:266)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:251)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163)
    at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:109)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163)
    at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:85)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1135)
    at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:662)
    at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:395)
    at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:385)
    at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:280)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:272)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:268)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:316)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:298)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:268)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:289)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:256)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:703)
    at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:416)
    ... 40 more

The code for the Jersey web service is:

@GET
@Produces({MediaType.APPLICATION_JSON})
public List<Site> getSites() {
    //List<Site> siteList = DatastoreDBManager.getInstance().getSites();
    List<Site> siteList = ofy().load().type(Site.class).list();
    //return Response.status(Status.OK).entity(new GenericEntity<List<Site>>(siteList){}).build(); 
    return siteList;
}

The Maven pom:

<dependency>
        <groupId>com.google.appengine</groupId>
        <artifactId>appengine-api-1.0-sdk</artifactId>
        <version>1.9.64</version>
</dependency>
....
<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-client</artifactId>
    <version>2.26</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-server</artifactId>
    <version>2.26</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet-core</artifactId>
    <version>2.26</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>2.26</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.inject</groupId>
    <artifactId>jersey-hk2</artifactId>
    <version>2.26</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.26</version>
</dependency>

Because of the NullPointerException, as far as I can tell, the only possible explanation is that the provider is not injected in the FilteringJacksonJaxbJsonProvider class. Why? Am I missing a dependency? Why this happens only sometimes?

I have tried using the following dependency with a similar result:

<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
    <version>2.9.4</version>
</dependency>

The strange part is that, sometimes when I deploy the application, it does not work and sometimes it does. After a while it doesn't work anymore and after more time it works again. Google Cloud Platform dynamically manages the number of instances of the application. It seems that for some of the instances I get a 500 HTTP response code.

The Site class has only four string properties. I know that I can replace in the web services with return new Gson().toJson(siteList); but I really want to use the built-in conversion feature.

Any ideas?

helldrain
  • 141
  • 1
  • 1
  • 7
  • It is not a duplicate of the NullPointerException question. I have updated my question to reflect that (see the bold paragraph). – helldrain Jun 12 '18 at 21:22
  • You may want to take a look at the [answers of](https://stackoverflow.com/questions/44409226/how-to-create-rest-application-using-google-app-engine) [some other questions](https://stackoverflow.com/questions/18805063/app-engine-jax-rs-with-jersey-no-working) that are similar to yours and check if they work for you and to have your JAX-RS service properly set up. – Rodrigo C. Jun 13 '18 at 12:52
  • Alternatively, you could try [Cloud Endpoints](https://cloud.google.com/endpoints/docs/quickstart-endpoints). You may want to check the [answers](https://stackoverflow.com/questions/49713083/what-are-the-problems-with-using-jax-rs-instead-of-cloud-endpoints-on-google-app) [shown here](https://stackoverflow.com/questions/9453561/restful-service-framework-for-appengine) for more info. – Rodrigo C. Jun 13 '18 at 12:53
  • @RodrigoC. I have checked all the relevant questions and no luck. I am looking for a solution for two weeks now. Also I do not want to use another technology (i.e., Cloud Endpoints) because I am reusing a part of my server in a non-google app engine project. – helldrain Jun 14 '18 at 05:06
  • The temporary fix for now (which is working) is to have the web services return a string obtained using GSON – helldrain Jun 14 '18 at 05:07
  • Have you seen [this](https://stackoverflow.com/a/19708873/3058302)? It looks similar to your issue. – Mangu Jun 18 '18 at 09:48
  • Has any of the Sites retrieved have a null value in the properties ? – Daniel Przybylowski Jul 17 '18 at 09:57
  • "The strange part is that, sometimes when I deploy the application, it does not work and sometimes it does. After a while it doesn't work anymore and after more time it works again." The Site object does not have any null properties. The site objects do not change at runtime. – helldrain Jul 18 '18 at 10:53
  • I'm having similar issue. Have you found a definitive solution other than the string obtained using GSON? – Simone Conti Mar 10 '20 at 07:36
  • Unfortunatelly, not. – helldrain Mar 11 '20 at 08:43

1 Answers1

-1

I had the exact same problem and after a lot of debugging I found out that for me the problem was a CORSFilter I used.

import java.io.IOException;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;

@Provider
public class CORSFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
            throws IOException {

        responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
        responseContext.getHeaders().add("Access-Control-Allow-Headers", "Content-Type");
        responseContext.getHeaders().add("Access-Control-Allow-Methods", "DELETE");

    }

}

Removing that filter resolved the issue. Hope it helps.

Simone Conti
  • 544
  • 3
  • 9
  • 20
  • 1
    I had no such filter. I think you need to do some more tests, because that problem did not always appeared. Maybe it is a coincidence that once you removed the filter everything was ok. – helldrain Mar 16 '20 at 04:35