Tapestry 5.0.5 bug, TAPESTRY-1648
有一个domianobject,其中有个property的type是BigDecimal。在增加bigdecimal的translator后。
package com.javaeye.dengyin2000.gtts.tapestry; import java.math.BigDecimal; import org.apache.tapestry.Translator; import org.apache.tapestry.ValidationException; import org.apache.tapestry.ioc.Messages; import org.apache.tapestry.ioc.internal.util.InternalUtils; public class BigDecimalTranslator implements Translator<BigDecimal> { public BigDecimal parseClient(String clientValue, Messages messages) throws ValidationException { if (InternalUtils.isBlank(clientValue)) return null; try { return new BigDecimal(clientValue.trim()); } catch (NumberFormatException ex) { throw new ValidationException(messages.format("number-format-exception", clientValue)); } } public String toClient(BigDecimal value) { return value == null ? "" : value.toString(); } }
然后contribute到AppModule
public static void contributeTranslatorDefaultSource( MappedConfiguration<Class, Translator> configuration) { configuration.add(BigDecimal.class, new BigDecimalTranslator()); } public static void contributeTranslatorSource( MappedConfiguration<String, Translator> configuration) { configuration.add("bigdecimal", new BigDecimalTranslator()); }
当提交form时,会发生一个NPE。错误发生在。org.apache.tapestry.ioc.services.TapestryIOCModule
// String to BigDecimal is important, as String->Double->BigDecimal would lose // precision. add(configuration, String.class, BigDecimal.class, new Coercion<String, BigDecimal>() { public BigDecimal coerce(String input) { return new BigDecimal(input); } });
这里有个很明显的错误。就是当input为null时。就发生了NPE.错误如下:
atorg.apache.tapestry.internal.structure.InternalComponentResourcesImpl.writeParameter(InternalComponentResourcesImpl.java:239)
atorg.apache.tapestry.corelib.base.AbstractTextField._$update_parameter_value(AbstractTextField.java)
atorg.apache.tapestry.corelib.base.AbstractTextField.processSubmission(AbstractTextField.java:181)
atorg.apache.tapestry.corelib.base.AbstractField.processSubmission(AbstractField.java:200)
atorg.apache.tapestry.corelib.base.AbstractField.access$100(AbstractField.java:45)
atorg.apache.tapestry.corelib.base.AbstractField$ProcessSubmissionAction.execute(AbstractField.java:114)
atorg.apache.tapestry.corelib.base.AbstractField$ProcessSubmissionAction.execute(AbstractField.java:108)
atorg.apache.tapestry.corelib.components.Form.onAction(Form.java:364)
...45more
Causedby:java.lang.RuntimeException:Coercionofnulltotypejava.math.BigDecimal(vianull-->String,String-->java.math.BigDecimal)failed:java.lang.NullPointerException
atorg.apache.tapestry.ioc.internal.services.TypeCoercerImpl.coerce(TypeCoercerImpl.java:154)
at$TypeCoercer_1149d2e0ddf.coerce($TypeCoercer_1149d2e0ddf.java)
atorg.apache.tapestry.internal.structure.InternalComponentResourcesImpl.writeParameter(InternalComponentResourcesImpl.java:233)
...52more
Causedby:java.lang.NullPointerException
atjava.math.BigDecimal.<init>(BigDecimal.java:594)
atorg.apache.tapestry.ioc.services.TapestryIOCModule$7.coerce(TapestryIOCModule.java:219)
atorg.apache.tapestry.ioc.services.TapestryIOCModule$7.coerce(TapestryIOCModule.java:217)
atorg.apache.tapestry.ioc.services.CoercionTuple$CoercionWrapper.coerce(CoercionTuple.java:53)
atorg.apache.tapestry.ioc.internal.services.CompoundCoercion.coerce(CompoundCoercion.java:48)
atorg.apache.tapestry.ioc.internal.services.TypeCoercerImpl.coerce(TypeCoercerImpl.java:150)
...54more
我试着想去覆盖TapestryIOCmodule的这快代码。然而没有用。然后google,发现原来这是个bug。这个bug会在5.0.6中解决。可是这是个很明显的错误呀。也不尽快解决掉。具体可以看。https://issues.apache.org/jira/browse/TAPESTRY-1648,然后发贴到Tapestrymaillinglist上问也没有下文。既然这样,也只有去自己修改Tapestry-ioc的sourcecode了。其实这也很简单,如果是是null或者是空字符的话renturnnull就是了。ok把tapestry的ioc用svn上拉下来。简单的修改为
// String to BigDecimal is important, as String->Double->BigDecimal would lose // precision. add(configuration, String.class, BigDecimal.class, new Coercion<String, BigDecimal>() { public BigDecimal coerce(String input) { if (input == null || input.trim().length() == 0) return null; return new BigDecimal(input); } });
打包替换掉tapestry-ioc5.0.5。再跑便程序。ok通过。