Source:
<code>public Object doPost(ExecutionRequest xreq) { OperationResource op = (OperationResource) getTarget(); String opId = op.getId(); if (!srv.accept(opId, op.isChain(), request)) { return ResponseHelper.notFound(); } String executionId = UUID.randomUUID().toString(); OperationContext opCtx = xreq.createContext(request, response, null); opCtx.setCallback(new OperationCallback() { @Override public void onChainEnter(OperationType chain) { } @Override public void onChainExit() { setCompleted(executionId); } @Override public void onOperationEnter(OperationContext context, OperationType type, InvokableMethod method, Map<String, Object> params) { enterMethod(executionId, method); } @Override public void onOperationExit(Object output) { setOutput(executionId, (Serializable) output); } @Override public OperationException onError(OperationException error) { setError(executionId, error.getMessage()); return error; } }); String repoName = session.getRepositoryName(); NuxeoPrincipal principal = session.getPrincipal(); new Thread(() -> { LoginComponent.pushPrincipal(principal); TransactionHelper.runInTransaction(() -> { <START> try (CloseableCoreSession session = CoreInstance.openCoreSession(repoName, principal)){ <END> opCtx.setCoreSession(session); service.run(opCtx, opId, xreq.getParams()); } catch (OperationException e) { setError(executionId, e.getMessage()); } finally { LoginComponent.popPrincipal(); } }); }, String.format("Nuxeo-AsyncOperation-%s", executionId)).start(); try { String statusURL = String.format("%s%s/%s/%s", ctx.getServerURL(), getPath(), executionId, STATUS_PATH); return Response.status(HttpServletResponse.SC_ACCEPTED).location(new URI(statusURL)).build(); } catch (URISyntaxException e) { throw new NuxeoException(e); } }</code><technical_language>move LoginComponent.pushPrincipal(principal) try? correct pattern, for instance if exception in runInTransaction finally block executed</technical_language>

Target:
public Object doPost(ExecutionRequest xreq) { OperationResource op = (OperationResource) getTarget(); String opId = op.getId(); if (!srv.accept(opId, op.isChain(), request)) { return ResponseHelper.notFound(); } String executionId = UUID.randomUUID().toString(); OperationContext opCtx = xreq.createContext(request, response, null); opCtx.setCallback(new OperationCallback() { @Override public void onChainEnter(OperationType chain) { } @Override public void onChainExit() { setCompleted(executionId); } @Override public void onOperationEnter(OperationContext context, OperationType type, InvokableMethod method, Map<String, Object> params) { enterMethod(executionId, method); } @Override public void onOperationExit(Object output) { setOutput(executionId, (Serializable) output); } @Override public OperationException onError(OperationException error) { setError(executionId, error.getMessage()); return error; } }); String repoName = session.getRepositoryName(); NuxeoPrincipal principal = session.getPrincipal(); new Thread(() -> { TransactionHelper.runInTransaction(() -> { LoginComponent.pushPrincipal(principal); try (var s = CoreInstance.openCoreSession(repoName, principal)){ opCtx.setCoreSession(s); service.run(opCtx, opId, xreq.getParams()); } catch (OperationException e) { setError(executionId, e.getMessage()); } finally { LoginComponent.popPrincipal(); } }); }, String.format("Nuxeo-AsyncOperation-%s", executionId)).start(); try { String statusURL = String.format("%s%s/%s/%s", ctx.getServerURL(), getPath(), executionId, STATUS_PATH); return Response.status(HttpServletResponse.SC_ACCEPTED).location(new URI(statusURL)).build(); } catch (URISyntaxException e) { throw new NuxeoException(e); } }