users@jersey.java.net

Re: [Jersey] Thread safety of JSON serialization

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Fri, 22 May 2009 10:20:40 +0200

Hi Santtu,

This is a race condition, thanks for reporting it.

Could you log an issue? and in the mean time i will work on a fix.

Paul.

On May 22, 2009, at 9:53 AM, Santtu Vuori wrote:

>
> I have been running some very simple tests against Jersey and
> noticed - by accident the following:
>
> I've created a simple client using commons http client (v3.1) to
> connect to the resource and pull the results. I'm adding "Accept:
> application/json" to header to ensure the data comes back JSON
> formatted. The client spawns 50 parallel threads to do a single HTTP
> GET and every now and then I get the following response from the
> server:
>
>
> Thread-8 RESPCODE: 500
> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Draft//EN">
> <HTML>
> <HEAD>
> <TITLE>Error 500--Internal Server Error</TITLE>
> <META NAME="GENERATOR" CONTENT="WebLogic Server">
> </HEAD>
> <BODY bgcolor="white">
> <FONT FACE=Helvetica><BR CLEAR=all>
> <TABLE border=0 cellspacing=5><TR><TD><BR CLEAR=all>
> <FONT FACE="Helvetica" COLOR="black" SIZE="3"><H2>Error 500--
> Internal Server Error</H2>
> </FONT></TD></TR>
> </TABLE>
> <TABLE border=0 width=100% cellpadding=10><TR><TD VALIGN=top
> WIDTH=100% BGCOLOR=white><FONT FACE="Courier New"><pre>
> java.lang.NullPointerException
> at com.sun.jersey.core.impl.provider.entity.Inflector
> $Replacer.replacement(Inflector.java:851)
> at
> com
> .sun
> .jersey.core.impl.provider.entity.Inflector.pluralize(Inflector.java:
> 519)
> at
> com
> .sun
> .jersey
> .core
> .provider
> .jaxb
> .AbstractListElementProvider
> .getRootElementName(AbstractListElementProvider.java:252)
> at
> com
> .sun
> .jersey
> .json
> .impl
> .provider
> .entity
> .JSONListElementProvider.writeList(JSONListElementProvider.java:106)
> at
> com
> .sun
> .jersey
> .core
> .provider
> .jaxb
> .AbstractListElementProvider
> .writeTo(AbstractListElementProvider.java:144)
> at
> com
> .sun
> .jersey.spi.container.ContainerResponse.write(ContainerResponse.java:
> 254)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl._handleRequest(WebApplicationImpl.java:693)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl.handleRequest(WebApplicationImpl.java:616)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl.handleRequest(WebApplicationImpl.java:607)
> at
> com
> .sun
> .jersey.spi.container.servlet.WebComponent.service(WebComponent.java:
> 309)
> at
> com
> .sun
> .jersey
> .spi
> .container.servlet.ServletContainer.service(ServletContainer.java:425)
> at
> com
> .sun
> .jersey
> .spi
> .container.servlet.ServletContainer.service(ServletContainer.java:590)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:
> 820)
> at weblogic.servlet.internal.StubSecurityHelper
> $ServletServiceAction.run(StubSecurityHelper.java:227)
> at
> weblogic
> .servlet
> .internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:
> 125)
> at
> weblogic
> .servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
> at
> weblogic
> .servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:175)
> at weblogic.servlet.internal.WebAppServletContext
> $ServletInvocationAction.run(WebAppServletContext.java:3498)
> at
> weblogic
> .security
> .acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
> at weblogic.security.service.SecurityManager.runAs(Unknown
> Source)
> at
> weblogic
> .servlet
> .internal
> .WebAppServletContext.securedExecute(WebAppServletContext.java:2180)
> at
> weblogic
> .servlet
> .internal.WebAppServletContext.execute(WebAppServletContext.java:2086)
> at
> weblogic
> .servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1406)
> at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
> at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
> </pre></FONT></TD></TR>
> </TABLE>
>
> </BODY>
> </HTML>
>
> This is the object that I would like to be serialized:
> ==================
> package xxx;
>
> import javax.xml.bind.annotation.XmlRootElement;
>
>
> @XmlRootElement
> public class PoJo {
>
> public final String strField = "This is a hardcoded string";
> public final int intField = 42;
> public final long longField = 0xFFFFFFF;
> public final double doubleField = 0.0000000010;
>
> }
> ==================
>
> And this is the resource:
> ==================
> package xxx;
>
> import java.util.LinkedList;
> import java.util.List;
>
> import javax.ws.rs.GET;
> import javax.ws.rs.Path;
> import javax.ws.rs.Produces;
> import javax.ws.rs.QueryParam;
> import javax.ws.rs.core.GenericEntity;
> import javax.ws.rs.core.MediaType;
>
> import org.apache.log4j.Logger;
>
> import xxx.PoJo;
>
>
> @Path("/")
> public class LoadTestResource {
>
> private static Logger logger =
> Logger.getLogger(LoadTestResource.class);
>
> @GET
> @Path("/")
> @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
> public GenericEntity<List<PoJo>>
> getData(@QueryParam("itemsreturned") Long itemsReturned) {
>
> List<PoJo> pojoList = new LinkedList<PoJo>();
>
> for(int itemsAdded = 0; itemsAdded < itemsReturned; itemsAdded++) {
> pojoList.add(new PoJo());
> }
>
> GenericEntity<List<PoJo>> pojos = new
> GenericEntity<List<PoJo>>(pojoList) {};
>
> return pojos;
> }
> }
> ==================
>
> I'm using Weblogic 10.3, Jersey 1.1.0-ea and 1.0.3.
>
> /Santtu