You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ofbiz.apache.org by "Jamal Tex Chi (Jira)" <ji...@apache.org> on 2026/10/17 08:52:00 UTC

[jira] [Created] (OFBIZ-13694) BOMNode.substituteNode throws NullPointerException when a ProductManufacturingRule has no quantity

Jamal Tex Chi created OFBIZ-13694:
-------------------------------------

             Summary: BOMNode.substituteNode throws NullPointerException when a ProductManufacturingRule has no quantity
                 Key: OFBIZ-13694
                 URL: https://issues.apache.org/jira/browse/OFBIZ-13694
             Project: OFBiz
          Issue Type: Bug
          Components: manufacturing
    Affects Versions: 24.09.07
         Environment: trunk at 5cef09d, OpenJDK 21, Apache Derby (the default test database). The defect is in the Java code and does not depend on the database.
            Reporter: Jamal Tex Chi


In BOMNode.substituteNode the rule quantity is read like this:

{code:java}
BigDecimal ruleQuantity = BigDecimal.ZERO;
try {
ruleQuantity = rule.getBigDecimal("quantity");
} catch (Exception exc) {
ruleQuantity = BigDecimal.ZERO;
}
...
if (ruleQuantity.compareTo(BigDecimal.ZERO) > 0) {
{code}

GenericValue.getBigDecimal returns null when the field is empty. It does not throw, so the catch never runs and ruleQuantity stays null. The compareTo call then throws:

{code:java}
java.lang.NullPointerException: Cannot invoke "java.math.BigDecimal.compareTo(java.math.BigDecimal)" because "ruleQuantity" is null
{code}

The quantity field of ProductManufacturingRule is optional in the entity definition and in the addProductManufacturingRule service. So a rule saved without a quantity is valid data, but the whole BOM explosion fails as soon as that rule is evaluated.

 

Steps to reproduce:
1. Create a finished product FG, a virtual component product COMP with one variant COMP_V, and a MANUF_COMPONENT ProductAssoc from FG to COMP.
2. Create a ProductManufacturingRule with productId = FG, productIdIn = COMP, productIdInSubst = COMP_V, no productFeature and no quantity.
3. Call getManufacturingComponents (or getBOMTree) for FG with quantity 1.

Expected: COMP is substituted by COMP_V, and the BOM line keeps its own quantity, because a quantity only overrides the line when it is greater than zero.
Actual: NullPointerException from substituteNode, and the explosion fails.

We reproduced this with a rule that has a productFeature condition matching the finished product's feature. The same rule with quantity = 0 works as expected. Without a productFeature the rule is always satisfied, so the code reaches the same compareTo.

Suggested fix: treat null as zero, for example

{code:java}
BigDecimal ruleQuantity = rule.getBigDecimal("quantity");
if (ruleQuantity == null) {
ruleQuantity = BigDecimal.ZERO;
}
{code}

and remove the try/catch, which cannot be reached for this case.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)