org.json.simple.parser.JSONParser is not thread safe

Steps to reproduce

http://juliusdavies.ca/json-simple-1.1.1-javadocs/org/json/simple/parser/JSONParser.html

Steps to reproduce:
1. have a slow pc running opencast
2. fire off multiple parallel requests to endpoint which parses Strings to JSONObjects (e.g. conflict checking, create events)

Actual Results:
Endpoint is unable to parse String to JSONObject, throwing various exceptions including ArrayIndexOutOfBoundsException and NoSuchElementException.

Expected Results:
Endpoint should parse String to JSONObject and proceed with method.

Workaround (if any):
have a fast pc run opencast

Activity

Show:
duncan smith
August 18, 2017, 9:43 PM

IndexServiceImpl.java uses a single instance of JSONParser throughout the entire class (line 177). I will investigate whether initialising a parser for each individual method remedies the issue.

duncan smith
August 18, 2017, 9:44 PM

Example of exception when checking for conflicts:

2017-08-18 11:58:18,297 | WARN | (AbstractEventEndpoint:1562) - Unable to parse metadata {"start":"2017-08-18T12:00:00+00:00","device":"hahn3","inputs":"presenter,presentation,presentation2,audio","end":"2017-11-11T12:50:00+00:00","duration":"3000000","rrule":"FREQ=WEEKLY;BYDAY=TU,WE,TH,FR;BYHOUR=12;BYMINUTE=00"}
java.util.NoSuchElementException
at java.util.LinkedList.removeFirst(LinkedList.java:270)[:1.8.0_131]
at org.json.simple.parser.JSONParser.parse(JSONParser.java:144)
at org.json.simple.parser.JSONParser.parse(JSONParser.java:81)
at org.json.simple.parser.JSONParser.parse(JSONParser.java:75)
at org.opencastproject.adminui.endpoint.AbstractEventEndpoint.getNewConflicts(AbstractEventEndpoint.java:1560)
at sun.reflect.GeneratedMethodAccessor96.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.8.0_131]
at java.lang.reflect.Method.invoke(Method.java:498)[:1.8.0_131]
at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:180)[206:org.apache.cxf.cxf-core:3.1.7]
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)[206:org.apache.cxf.cxf-core:3.1.7]
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:189)[207:org.apache.cxf.cxf-rt-frontend-jaxrs:3.1.7]
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:99)[207:org.apache.cxf.cxf-rt-frontend-jaxrs:3.1.7]
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)[206:org.apache.cxf.cxf-core:3.1.7]
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96)[206:org.apache.cxf.cxf-core:3.1.7]
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)[206:org.apache.cxf.cxf-core:3.1.7]
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)[206:org.apache.cxf.cxf-core:3.1.7]
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:254)[213:org.apache.cxf.cxf-rt-transports-http:3.1.7]
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)[213:org.apache.cxf.cxf-rt-transports-http:3.1.7]
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)[213:org.apache.cxf.cxf-rt-transports-http:3.1.7]
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)[213:org.apache.cxf.cxf-rt-transports-http:3.1.7]
at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:180)[213:org.apache.cxf.cxf-rt-transports-http:3.1.7]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:299)[213:org.apache.cxf.cxf-rt-transports-http:3.1.7]
at org.opencastproject.kernel.rest.RestPublisher$RestServlet.handleRequest(RestPublisher.java:535)[102:matterhorn-kernel:3.0.0.SNAPSHOT]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:218)[213:org.apache.cxf.cxf-rt-transports-http:3.1.7]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)[29:javax.servlet-api:3.1.0]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:274)[213:org.apache.cxf.cxf-rt-transports-http:3.1.7]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812)[292:org.eclipse.jetty.servlet:9.2.19.v20160908]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)[292:org.eclipse.jetty.servlet:9.2.19.v20160908]
at org.opencastproject.kernel.rest.JsonpFilter.doFilter(JsonpFilter.java:113)[102:matterhorn-kernel:3.0.0.SNAPSHOT]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)[292:org.eclipse.jetty.servlet:9.2.19.v20160908]
at org.opencastproject.security.urlsigning.filter.UrlSigningFilter.doFilter(UrlSigningFilter.java:85)[155:matterhorn-urlsigning-verifier-service-impl:3.0.0.SNAPSHOT]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)[292:org.eclipse.jetty.servlet:9.2.19.v20160908]
at org.opencastproject.kernel.filter.proxy.TransparentProxyFilter.doFilter(TransparentProxyFilter.java:63)[102:matterhorn-kernel:3.0.0.SNAPSHOT]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)[292:org.eclipse.jetty.servlet:9.2.19.v20160908]
at org.opencastproject.kernel.security.RemoteUserAndOrganizationFilter.doFilter(RemoteUserAndOrganizationFilter.java:247)[102:matterhorn-kernel:3.0.0.SNAPSHOT]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)[292:org.eclipse.jetty.servlet:9.2.19.v20160908]
at org.opencastproject.kernel.rest.CurrentJobFilter.doFilter(CurrentJobFilter.java:87)[102:matterhorn-kernel:3.0.0.SNAPSHOT]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)[292:org.eclipse.jetty.servlet:9.2.19.v20160908]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:311)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.opencastproject.kernel.security.AsyncTimeoutRedirectFilter.doFilter(AsyncTimeoutRedirectFilter.java:60)[102:matterhorn-kernel:3.0.0.SNAPSHOT]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:101)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:146)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:98)[335:org.springframework.web:3.1.4.RELEASE]
at org.springframework.security.web.authentication.www.DigestAuthenticationFilter.doFilter(DigestAuthenticationFilter.java:115)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:102)[335:org.springframework.web:3.1.4.RELEASE]
at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:82)[335:org.springframework.web:3.1.4.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:91)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:182)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173)[333:org.springframework.security.web:3.1.0.RELEASE]
at org.opencastproject.kernel.security.SecurityFilter.doFilter(SecurityFilter.java:124)[102:matterhorn-kernel:3.0.0.SNAPSHOT]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)[292:org.eclipse.jetty.servlet:9.2.19.v20160908]
at org.opencastproject.kernel.security.OrganizationFilter.doFilter(OrganizationFilter.java:135)[102:matterhorn-kernel:3.0.0.SNAPSHOT]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)[292:org.eclipse.jetty.servlet:9.2.19.v20160908]
at org.opencastproject.kernel.filter.https.HttpsFilter.doFilter(HttpsFilter.java:64)[102:matterhorn-kernel:3.0.0.SNAPSHOT]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)[292:org.eclipse.jetty.servlet:9.2.19.v20160908]
at org.opencastproject.kernel.rest.CleanSessionsFilter.doFilter(CleanSessionsFilter.java:89)[102:matterhorn-kernel:3.0.0.SNAPSHOT]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)[292:org.eclipse.jetty.servlet:9.2.19.v20160908]
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)[292:org.eclipse.jetty.servlet:9.2.19.v20160908]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:71)[314:org.ops4j.pax.web.pax-web-jetty:4.3.0]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)[291:org.eclipse.jetty.server:9.2.19.v20160908]
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)[290:org.eclipse.jetty.security:9.2.19.v20160908]
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)[291:org.eclipse.jetty.server:9.2.19.v20160908]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)[291:org.eclipse.jetty.server:9.2.19.v20160908]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:287)[314:org.ops4j.pax.web.pax-web-jetty:4.3.0]
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)[292:org.eclipse.jetty.servlet:9.2.19.v20160908]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)[291:org.eclipse.jetty.server:9.2.19.v20160908]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)[291:org.eclipse.jetty.server:9.2.19.v20160908]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)[291:org.eclipse.jetty.server:9.2.19.v20160908]
at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:80)[314:org.ops4j.pax.web.pax-web-jetty:4.3.0]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)[291:org.eclipse.jetty.server:9.2.19.v20160908]
at org.eclipse.jetty.server.Server.handle(Server.java:499)[291:org.eclipse.jetty.server:9.2.19.v20160908]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)[291:org.eclipse.jetty.server:9.2.19.v20160908]
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)[291:org.eclipse.jetty.server:9.2.19.v20160908]
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)[283:org.eclipse.jetty.io:9.2.19.v20160908]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)[294:org.eclipse.jetty.util:9.2.19.v20160908]
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)[294:org.eclipse.jetty.util:9.2.19.v20160908]
at java.lang.Thread.run(Thread.java:748)[:1.8.0_131]

Stephen Marquard
October 20, 2017, 12:41 AM

PR has been merged into 3.x.

Fixed and reviewed

Assignee

duncan smith

Reporter

duncan smith

Severity

Incorrectly Functioning Without Workaround

Tags (folksonomy)

None

Fix versions

Affects versions

Priority

Major