This is an automated email from the ASF dual-hosted git repository. heneveld pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git
commit 41d5d32873d49dbcef10af71050b5120b4a4ab4c Author: Alex Heneveld <[email protected]> AuthorDate: Tue May 30 12:29:24 2023 +0100 more resilient catching of freemarker exception when creating classes --- .../brooklyn/util/core/text/TemplateProcessor.java | 46 ++++++++++++++-------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/org/apache/brooklyn/util/core/text/TemplateProcessor.java b/core/src/main/java/org/apache/brooklyn/util/core/text/TemplateProcessor.java index d6f848eb49..815a9642c7 100644 --- a/core/src/main/java/org/apache/brooklyn/util/core/text/TemplateProcessor.java +++ b/core/src/main/java/org/apache/brooklyn/util/core/text/TemplateProcessor.java @@ -180,8 +180,37 @@ public class TemplateProcessor { return super.wrap(objOrig); } + static final ThreadLocal<Boolean> handleUnknownTypeLoopPrevention = new ThreadLocal<>(); + @Override protected TemplateModel handleUnknownType(final Object o) throws TemplateModelException { + if (handleUnknownTypeLoopPrevention.get()!=null) { + return super.handleUnknownType(o); + } + try { + handleUnknownTypeLoopPrevention.set(true); + // can get "Class inrospection data lookup aborded" from freemarker ClassIntrospector:250 + // if thread is interrupted because class lookup uses wait on a shared cache; + // if the "interruption" is because of us, retry in this instance + while (true) { + try { + return handleUnknownTypeReal(o); + } catch (Exception e) { + if (WorkflowExpressionResolution.isInterruptSetToPreventWaiting()) { + if (Exceptions.isRootCauseIsInterruption(e) || e.toString().contains(InterruptedException.class.getSimpleName())) { + Thread.yield(); + continue; + } + } + throw e; + } + } + } finally { + handleUnknownTypeLoopPrevention.remove(); + } + } + + protected TemplateModel handleUnknownTypeReal(final Object o) throws TemplateModelException { if (o instanceof EntityInternal) return EntityAndMapTemplateModel.forEntity((EntityInternal)o, null); if (o instanceof Location) return LocationAndMapTemplateModel.forLocation((LocationInternal)o, null); @@ -193,22 +222,7 @@ public class TemplateProcessor { // deproxy to reduce freemarker introspection interrupted errors o = Entities.deproxy((BrooklynObject) o); } - // can get "Class inrospection data lookup aborded" from freemarker ClassIntrospector:250 - // if thread is interrupted because class lookup uses wait on a shared cache; - // if the "interruption" is because of us, retry in this instance - while (true) { - try { - return super.handleUnknownType(o); - } catch (Exception e) { - if (WorkflowExpressionResolution.isInterruptSetToPreventWaiting()) { - if (Exceptions.isRootCauseIsInterruption(e) || e.toString().contains(InterruptedException.class.getSimpleName())) { - Thread.yield(); - continue; - } - } - throw e; - } - } + return handleUnknownType(o); } }
