{"record":{"id":"8e6388b210507ee1","repo":"spring-projects/spring-framework","slug":"cannot-find-current-proxy-set-exposeproxy-prope","errorCode":null,"errorMessage":"Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available, and ensure that AopContext.currentProxy() is invoked in the same thread as the AOP invocation context.","messagePattern":"Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available, and ensure that AopContext\\.currentProxy\\(\\) is invoked in the same thread as the AOP invocation context\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/framework/AopContext.java","lineNumber":70,"sourceCode":"\n\n\tprivate AopContext() {\n\t}\n\n\n\t/**\n\t * Try to return the current AOP proxy. This method is usable only if the\n\t * calling method has been invoked via AOP, and the AOP framework has been set\n\t * to expose proxies. Otherwise, this method will throw an IllegalStateException.\n\t * @return the current AOP proxy (never returns {@code null})\n\t * @throws IllegalStateException if the proxy cannot be found, because the\n\t * method was invoked outside an AOP invocation context, or because the\n\t * AOP framework has not been configured to expose the proxy\n\t */\n\tpublic static Object currentProxy() throws IllegalStateException {\n\t\tObject proxy = currentProxy.get();\n\t\tif (proxy == null) {\n\t\t\tthrow new IllegalStateException(\n\t\t\t\t\t\"Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available, and \" +\n\t\t\t\t\t\t\t\"ensure that AopContext.currentProxy() is invoked in the same thread as the AOP invocation context.\");\n\t\t}\n\t\treturn proxy;\n\t}\n\n\t/**\n\t * Make the given proxy available via the {@code currentProxy()} method.\n\t * <p>Note that the caller should be careful to keep the old value as appropriate.\n\t * @param proxy the proxy to expose (or {@code null} to reset it)\n\t * @return the old proxy, which may be {@code null} if none was bound\n\t * @see #currentProxy()\n\t */\n\tstatic @Nullable Object setCurrentProxy(@Nullable Object proxy) {\n\t\tObject old = currentProxy.get();\n\t\tif (proxy != null) {\n\t\t\tcurrentProxy.set(proxy);\n\t\t}","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-aop/src/main/java/org/springframework/aop/framework/AopContext.java#L52-L88","documentation":"AopContext.currentProxy() returns the AOP proxy bound to the current thread via a ThreadLocal that is only populated when the proxy's exposeProxy flag is true (ProxyConfig.setExposeProxy(true)). It throws IllegalStateException when the ThreadLocal is empty - either because exposeProxy was left false (the default, for performance) or because the call is made outside the AOP invocation on the same thread.","triggerScenarios":"Code inside a proxied bean calls AopContext.currentProxy() without exposeProxy=true; calling currentProxy() from a different thread than the one running the AOP invocation (e.g. inside an @Async method or a spawned thread); calling it from code that is not running under AOP at all.","commonSituations":"Self-invocation through the proxy (AopContext.currentProxy().method()) attempted without enabling exposeProxy; @EnableAspectJAutoProxy(exposeProxy=true) omitted; reactive/async flows where the thread that reads currentProxy() is not the invocation thread.","solutions":["Enable proxy exposure: @EnableAspectJAutoProxy(exposeProxy = true) (Java) or <aop:aspectj-autoproxy expose-proxy=\"true\"/> (XML)","Avoid relying on currentProxy() - refactor self-invocation so the call goes through an injected proxy reference instead","Ensure currentProxy() is invoked on the very thread executing the proxied method (do not hand off to another thread)"],"exampleFix":"// before\n@EnableAspectJAutoProxy\n// inside a proxied bean:\n((MyService) AopContext.currentProxy()).internal();\n\n// after\n@EnableAspectJAutoProxy(exposeProxy = true)\n((MyService) AopContext.currentProxy()).internal();","handlingStrategy":"validation","validationCode":"// Verify exposeProxy and thread before calling:\nif (((Advised) proxy).isExposeProxy()) {\n  Object p = AopContext.currentProxy();\n} else {\n  throw new IllegalStateException(\"exposeProxy=false; cannot use AopContext.currentProxy()\");\n}","typeGuard":"private static boolean proxyExposureEnabled(Advised advised) {\n  return advised != null && advised.isExposeProxy();\n}","tryCatchPattern":"try {\n  Object proxy = AopContext.currentProxy();\n} catch (IllegalStateException ex) {\n  // not in an AOP invocation or exposeProxy disabled - fall back to an injected proxy reference\n}","preventionTips":["Prefer injecting the proxy bean and invoking through it over AopContext.currentProxy()","If you must use currentProxy(), set exposeProxy=true globally via @EnableAspectJAutoProxy","Never read currentProxy() from a thread other than the one performing the AOP invocation"],"tags":["spring-aop","aop-context","expose-proxy","thread-local"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}