title: Shiro throws an UnavailableSecurityManagerException in custom JSON serialiser
body: <p>I'm working on a REST API of a TomEE 7 based web app, which uses Shiro 1.3.2 for security. When an API request comes in, a <code>SecurityManager</code> and a <code>Subject</code> are created, and the latter is bound to a <code>SubjectThreadState</code>. I can call <code>SecurityUtils.getSubject()</code> anywhere in the endpoint code and the subject is always available.</p>
  
  <p>However, problems arise when I try to do the same inside my custom JSON serialiser. It only serialises specific fields in some classes, so I register it on a per-field basis using this annotation:</p>
  
  <pre><code>@JsonSerialize(using = MySerialiser.class)
  Long myRelatedItemId;
  </code></pre>
  
  <p>I wrote my serialiser based on <a href="https://www.baeldung.com/jackson-annotations" rel="nofollow noreferrer">the example code on this page under "2.7. @JsonSerialize"</a>. The serialiser needs to perform a cache lookup, and for that it has to have a Shiro subject. There is none because, thanks to the annotation above, I don't call the serialiser manually; instead Jersey calls it. This exception gets thrown (<strong>clarification:</strong> when I try to run <code>SecurityUtils.getSubject()</code> from the serialiser code):</p>
  
  <pre><code>org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton.  This is an invalid application configuration.
      at org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:123)
      at org.apache.shiro.subject.Subject$Builder.&lt;init&gt;(Subject.java:627)
      at org.apache.shiro.SecurityUtils.getSubject(SecurityUtils.java:56)
  </code></pre>
  
  <p>I have confirmed that everything works if I call something like <code>ObjectMapper().writeValueAsString()</code> manually from the API endpoint code. However, that is definitely not the proper way to do it, because then the endpoint would effectively send and receive strings instead of the objects they are meant to handle.</p>
  
  <p>I don't understand much about the inner workings of Shiro or Jackson, but it seems like the serialisation is being performed inside another thread, where Shiro's <code>SubjectThreadState</code> doesn't exist. Although if threading really is the cause, then I cannot see why <code>Thread.currentThread().getName()</code> returns the same value both inside and outside the serialiser, as does <code>Thread.currentThread().getId()</code>.</p>
  
  <p>I have tried a vast number of things to no avail, including:</p>
  
  <ul>
  <li>Upgrading to Shiro 1.4.0.</li>
  <li>Upgrading Jackson from 2.7.5 to 2.9.7.</li>
  <li>Saving the <code>SecurityManager</code> instance that is created at the start of the API call inside a static <code>ThreadLocal</code> variable of the serialiser class.</li>
  <li>Writing my own implementation of <code>MessageBodyWriter</code> which, not surprisingly, is called in exactly the same fashion.</li>
  <li>Setting the <code>staticSecurityManagerEnabled</code> parameter to <code>true</code> in the <code>ShiroFilter</code> configuration in my <code>web.xml</code>.</li>
  </ul>
  
  <p>Can anyone suggest how I could make the <code>SecurityManager</code> (or <code>Subject</code>) visible to the serialiser, when it's running in a thread not started by my code (<strong>clarification:</strong> or, otherwise running in parallel and started by Jersey, as far as I can tell)? Thanks in advance.</p>
  
  <h2>Update:</h2>
  
  <p>This stack trace was taken inside the serialiser:</p>
  
  <pre><code>&lt;mypackage&gt;.MySerializer.serialize()
  com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField()
  com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields()
  com.fasterxml.jackson.databind.ser.BeanSerializer.serialize()
  com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue()
  com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize()
  com.fasterxml.jackson.databind.ObjectWriter.writeValue()
  com.fasterxml.jackson.jaxrs.base.ProviderBase.writeTo()
  org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo()
  org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo()
  org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed()
  org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo()
  org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed()
  org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo()
  org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed()
  org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo()
  org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse()
  org.glassfish.jersey.server.ServerRuntime$Responder.processResponse()
  org.glassfish.jersey.server.ServerRuntime$Responder.process()
  org.glassfish.jersey.server.ServerRuntime$2.run()
  </code></pre>
  
  <p>This one was taken in our interceptor class where the <code>Subject</code> is created and bound:</p>
  
  <pre><code>&lt;mypackage&gt;.MySecurityInterceptor.createSession()
  sun.reflect.NativeMethodAccessorImpl.invoke0()
  sun.reflect.NativeMethodAccessorImpl.invoke()
  sun.reflect.DelegatingMethodAccessorImpl.invoke()
  java.lang.reflect.Method.invoke()
  org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke()
  org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed()
  org.apache.openejb.monitoring.StatsInterceptor.record()
  org.apache.openejb.monitoring.StatsInterceptor.invoke()
  sun.reflect.GeneratedMethodAccessor111.invoke()
  sun.reflect.DelegatingMethodAccessorImpl.invoke()
  java.lang.reflect.Method.invoke()
  org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke()
  org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed()
  org.apache.openejb.core.interceptor.InterceptorStack.invoke()
  org.apache.openejb.core.stateless.StatelessContainer._invoke()
  org.apache.openejb.core.stateless.StatelessContainer.invoke()
  org.apache.openejb.core.ivm.EjbObjectProxyHandler.synchronizedBusinessMethod()
  org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod()
  org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke()
  org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke()
  com.sun.proxy.$Proxy279.getEntity()
  org.openapitools.api.impl.MyApiServiceImpl.getEntity()
  org.openapitools.api.MyApi.getEntity()
  sun.reflect.NativeMethodAccessorImpl.invoke0()
  sun.reflect.NativeMethodAccessorImpl.invoke()
  sun.reflect.DelegatingMethodAccessorImpl.invoke()
  java.lang.reflect.Method.invoke()
  org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke()
  org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run()
  org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke()
  org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch()
  org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch()
  org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke()
  org.glassfish.jersey.server.model.ResourceMethodInvoker.apply()
  org.glassfish.jersey.server.model.ResourceMethodInvoker.apply()
  org.glassfish.jersey.server.ServerRuntime$2.run()
  </code></pre>
  
  <p>There are 46 more calls that are identical in both traces after that last line, so I excluded them. They contain a bunch of <code>org.apache.catalina.core</code> and <code>org.glassfish.jersey</code>.</p>