Tapestry
  1. Tapestry
  2. TAPESTRY-1648

Coercing from null to BigDecimal causes an NPE

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Blocker Blocker
    • Resolution: Fixed
    • Affects Version/s: 5.0.5
    • Fix Version/s: 5.0.6
    • Component/s: tapestry-ioc
    • Labels:
      None

      Description

      I'm working on a currency textfield for bigdecimal and I get this exception because it tries to coerce from null to String (which returns null) and then passes a null into the BigDecimal(String) constructor which causes the NPE.

      org.apache.tapestry.ioc.internal.util.TapestryException: Failure reading parameter value of component CurrencyFieldTestPage:value: Coercion of null to type java.math.BigDecimal (via null --> String, String --> java.math.BigDecimal) failed: java.lang.NullPointerException [at classpath:com/ifactory/cms/cms/integration/app0/pages/CurrencyFieldTestPage.html, line 5, column 78]
      at org.apache.tapestry.internal.structure.ComponentPageElementImpl.invoke(ComponentPageElementImpl.java:935)
      at org.apache.tapestry.internal.structure.ComponentPageElementImpl.access$100(ComponentPageElementImpl.java:69)
      at org.apache.tapestry.internal.structure.ComponentPageElementImpl$10.render(ComponentPageElementImpl.java:349)
      at org.apache.tapestry.internal.services.RenderQueueImpl.run(RenderQueueImpl.java:57)
      at org.apache.tapestry.internal.services.PageMarkupRendererImpl.renderPageMarkup(PageMarkupRendererImpl.java:40)
      at $PageMarkupRenderer_113c1389a35.renderPageMarkup($PageMarkupRenderer_113c1389a35.java)
      at org.apache.tapestry.internal.services.PageResponseRendererImpl.renderPageResponse(PageResponseRendererImpl.java:71)
      at $PageResponseRenderer_113c13899fc.renderPageResponse($PageResponseRenderer_113c13899fc.java)
      at org.apache.tapestry.internal.services.PageRenderRequestHandlerImpl.handle(PageRenderRequestHandlerImpl.java:81)
      at $PageRenderRequestHandler_113c13899f1.handle($PageRenderRequestHandler_113c13899f1.java)
      at org.apache.tapestry.internal.test.PageLinkInvoker.invoke(PageLinkInvoker.java:57)
      at org.apache.tapestry.test.PageTester.invoke(PageTester.java:184)
      at org.apache.tapestry.test.PageTester.renderPage(PageTester.java:144)
      at com.ifactory.cms.cms.components.CurrencyFieldTest.testFormatting(CurrencyFieldTest.java:23)
      Caused by: org.apache.tapestry.ioc.internal.util.TapestryException: Failure reading parameter value of component CurrencyFieldTestPage:value: Coercion of null to type java.math.BigDecimal (via null --> String, String --> java.math.BigDecimal) failed: java.lang.NullPointerException
      at org.apache.tapestry.internal.structure.InternalComponentResourcesImpl.readParameter(InternalComponentResourcesImpl.java:210)
      at com.ifactory.cms.cms.components.CurrencyField._$read_parameter_value(CurrencyField.java)
      at com.ifactory.cms.cms.components.CurrencyField.beginRender(CurrencyField.java:109)
      at com.ifactory.cms.cms.components.CurrencyField.beginRender(CurrencyField.java)
      at org.apache.tapestry.internal.structure.ComponentPageElementImpl$10$1.run(ComponentPageElementImpl.java:345)
      at org.apache.tapestry.internal.structure.ComponentPageElementImpl.invoke(ComponentPageElementImpl.java:931)
      ... 34 more
      Caused by: java.lang.RuntimeException: Coercion of null to type java.math.BigDecimal (via null --> String, String --> java.math.BigDecimal) failed: java.lang.NullPointerException
      at org.apache.tapestry.ioc.internal.services.TypeCoercerImpl.coerce(TypeCoercerImpl.java:154)
      at $TypeCoercer_113c13899e0.coerce($TypeCoercer_113c13899e0.java)
      at org.apache.tapestry.internal.structure.InternalComponentResourcesImpl.readParameter(InternalComponentResourcesImpl.java:206)
      ... 39 more
      Caused by: java.lang.NullPointerException
      at java.math.BigDecimal.<init>(BigDecimal.java:594)
      at org.apache.tapestry.ioc.services.TapestryIOCModule$7.coerce(TapestryIOCModule.java:219)
      at org.apache.tapestry.ioc.services.TapestryIOCModule$7.coerce(TapestryIOCModule.java:217)
      at org.apache.tapestry.ioc.services.CoercionTuple$CoercionWrapper.coerce(CoercionTuple.java:53)
      at org.apache.tapestry.ioc.internal.services.CompoundCoercion.coerce(CompoundCoercion.java:48)
      at org.apache.tapestry.ioc.internal.services.TypeCoercerImpl.coerce(TypeCoercerImpl.java:150)
      ... 41 more
      ... Removed 21 stack frames

        Activity

        Hide
        Howard M. Lewis Ship added a comment -

        Add a number of coercions from null to numeric types (Long, Double, BigInteger, BigDecimal). Updated the type-coercion diagram.

        Show
        Howard M. Lewis Ship added a comment - Add a number of coercions from null to numeric types (Long, Double, BigInteger, BigDecimal). Updated the type-coercion diagram.
        Hide
        Imants Firsts added a comment -

        Why do coercers return zero instead of null for those types? This prevents from distinguishing between null and zero values and as a result does not allow entering null values using TextFields. Are there some undesired side effects when returning null?

        Show
        Imants Firsts added a comment - Why do coercers return zero instead of null for those types? This prevents from distinguishing between null and zero values and as a result does not allow entering null values using TextFields. Are there some undesired side effects when returning null?
        Hide
        Hugo Palma added a comment -

        The coercion of numeric type from null to 0 is causing me problems too.
        As i see it, i think null values should be coerced to null.

        Shouldn't this be re-opened and re-examined ?

        Show
        Hugo Palma added a comment - The coercion of numeric type from null to 0 is causing me problems too. As i see it, i think null values should be coerced to null. Shouldn't this be re-opened and re-examined ?
        Hide
        Cesar Lesc added a comment -

        IMHO a null value is not a Number, and if you need to express something else than a Number use another datatype like String.

        Show
        Cesar Lesc added a comment - IMHO a null value is not a Number, and if you need to express something else than a Number use another datatype like String.
        Hide
        Christian E Gruber added a comment -

        A null value is not a number, but it is not a string, it is the absence of a value. But, the absence of a value is a meaningful state. That is why RDBMSs include "tri state logic". The whole theory of nulls in software is that the absence of a value is not the same thing as a value with a default number. If you want to implement your logic to never have null values, then make all your objects init with defaults, but Java supports nulls and so Tapestry, which is a Java framework, should not make assumptions that are different than the Java language.

        Integer i = null;
        Integer i = 0;

        These are different, and should be distinguishable. Especially because null is often an error state and shoudl be testable wihtout having to guard each and every situation with a null pointer exception trap.

        Since textfields and selections hold string labels/values, it is reasonable that when coercing a null number into such a field, that you coerce it into the empty string, or soemthing similar, not a number 0 which has mathematical meaning that is calculable. Null means not calculable, in a sense. And when coercing a null back into a number, if it's a number object (Integer/Boolean, etc.) then should pass in as a null. If it's a primitive type that doesn't support nulls, then it should go to a default value like 0/false, because there you don't have a choice, in my view.

        Show
        Christian E Gruber added a comment - A null value is not a number, but it is not a string, it is the absence of a value. But, the absence of a value is a meaningful state. That is why RDBMSs include "tri state logic". The whole theory of nulls in software is that the absence of a value is not the same thing as a value with a default number. If you want to implement your logic to never have null values, then make all your objects init with defaults, but Java supports nulls and so Tapestry, which is a Java framework, should not make assumptions that are different than the Java language. Integer i = null; Integer i = 0; These are different, and should be distinguishable. Especially because null is often an error state and shoudl be testable wihtout having to guard each and every situation with a null pointer exception trap. Since textfields and selections hold string labels/values, it is reasonable that when coercing a null number into such a field, that you coerce it into the empty string, or soemthing similar, not a number 0 which has mathematical meaning that is calculable. Null means not calculable, in a sense. And when coercing a null back into a number, if it's a number object (Integer/Boolean, etc.) then should pass in as a null. If it's a primitive type that doesn't support nulls, then it should go to a default value like 0/false, because there you don't have a choice, in my view.
        Hide
        Cesar Lesc added a comment -

        I like your solution with different coertions for primitives types and object types and everyone will be happy.

        Show
        Cesar Lesc added a comment - I like your solution with different coertions for primitives types and object types and everyone will be happy.

          People

          • Assignee:
            Howard M. Lewis Ship
            Reporter:
            Dan Adams
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development