This is an automated email from the ASF dual-hosted git repository. jacopoc pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
commit 7395c892ae5dd39b2e09548ab7b4638e2c38e2ed Author: Jacopo Cappellato <[email protected]> AuthorDate: Tue Oct 27 13:23:46 2026 +0100 Close EntityListIterator in list/multi form rendering even on errors The EntityListIterator used to render list and multi forms was closed only at the end of renderItemRows, so an exception thrown while rendering the header or the rows left the iterator and its database connection open. Closing is now done in a finally block in renderListFormString and renderMultiFormString, which own the iterator for the whole rendering. Co-Authored-By: Claude Opus 5.5 <[email protected]> --- .../apache/ofbiz/widget/renderer/FormRenderer.java | 71 +++++++++++++--------- 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/FormRenderer.java b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/FormRenderer.java index e3846c9bc5..6e2f654767 100644 --- a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/FormRenderer.java +++ b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/FormRenderer.java @@ -912,15 +912,18 @@ public class FormRenderer { context.put("highIndex", modelForm.isOverridenListSize() ? listSize : highIndex); } context.put("actualPageSize", highIndex - lowIndex); + } + } - if (iter instanceof EntityListIterator) { - try { - // CHECKSTYLE_OFF: ALMOST_ALL - ((EntityListIterator) iter).close(); - // CHECKSTYLE_ON: ALMOST_ALL - } catch (GenericEntityException e) { - Debug.logError(e, "Error closing list form render EntityListIterator: " + e.toString(), MODULE); - } + private void closeEntityListIterator(Map<String, Object> context) { + Object obj = context.get(modelForm.getListName()); + if (obj instanceof EntityListIterator) { + try { + // CHECKSTYLE_OFF: ALMOST_ALL + ((EntityListIterator) obj).close(); + // CHECKSTYLE_ON: ALMOST_ALL + } catch (GenericEntityException e) { + Debug.logError(e, "Error closing list form render EntityListIterator: " + e.toString(), MODULE); } } } @@ -935,17 +938,21 @@ public class FormRenderer { // render formatting wrapper open formStringRenderer.renderFormatListWrapperOpen(writer, context, modelForm); - int numOfColumns = 0; - boolean containsData = this.checkFormData(context); - // ===== render header row ===== - if (!modelForm.getHideHeader() && containsData) { - numOfColumns = this.renderHeaderRow(writer, context); - } - if (!containsData) { - formStringRenderer.renderEmptyFormDataMessage(writer, context, modelForm); + try { + int numOfColumns = 0; + boolean containsData = this.checkFormData(context); + // ===== render header row ===== + if (!modelForm.getHideHeader() && containsData) { + numOfColumns = this.renderHeaderRow(writer, context); + } + if (!containsData) { + formStringRenderer.renderEmptyFormDataMessage(writer, context, modelForm); + } + // ===== render the item rows ===== + this.renderItemRows(writer, context, formStringRenderer, true, numOfColumns); + } finally { + this.closeEntityListIterator(context); } - // ===== render the item rows ===== - this.renderItemRows(writer, context, formStringRenderer, true, numOfColumns); // render formatting wrapper close formStringRenderer.renderFormatListWrapperClose(writer, context, modelForm); @@ -964,17 +971,21 @@ public class FormRenderer { // render formatting wrapper open formStringRenderer.renderFormatListWrapperOpen(writer, context, modelForm); - int numOfColumns = 0; - boolean containsData = this.checkFormData(context); - // ===== render header row ===== - if (!modelForm.getHideHeader() && containsData) { - numOfColumns = this.renderHeaderRow(writer, context); - } - if (!containsData) { - formStringRenderer.renderEmptyFormDataMessage(writer, context, modelForm); + try { + int numOfColumns = 0; + boolean containsData = this.checkFormData(context); + // ===== render header row ===== + if (!modelForm.getHideHeader() && containsData) { + numOfColumns = this.renderHeaderRow(writer, context); + } + if (!containsData) { + formStringRenderer.renderEmptyFormDataMessage(writer, context, modelForm); + } + // ===== render the item rows ===== + this.renderItemRows(writer, context, formStringRenderer, false, numOfColumns); + } finally { + this.closeEntityListIterator(context); } - // ===== render the item rows ===== - this.renderItemRows(writer, context, formStringRenderer, false, numOfColumns); formStringRenderer.renderFormatListWrapperClose(writer, context, modelForm); @@ -1252,9 +1263,9 @@ public class FormRenderer { } int itemIndex = -1; if (iter instanceof EntityListIterator) { - EntityListIterator eli = (EntityListIterator) iter; // INFO Spotbugs reports here "'eli' is never closed" but that's on purpose + // not closed here: the iterator is still needed to render the rows, it is closed by the caller try { - if (eli.getResultsSizeAfterPartialList() > 0) { + if (((EntityListIterator) iter).getResultsSizeAfterPartialList() > 0) { itemIndex++; } } catch (GenericEntityException gee) {

