On Tue, Jun 13, 2017 at 6:06 PM, Mark Thomas <ma...@apache.org> wrote:
> On 13/06/17 22:01, Mark Thomas wrote: > > On 13/06/17 15:27, Chris Cheshire wrote: > > <snip/> > > >> I'm bewildered at why tomcat operates this way when it comes to Numbers > and > >> Strings. Why is it insistent on coercion when null and zero are > absolutely > >> not the same value. If this is because of autoboxing, then isn't that a > >> bug? A long is not a Long, and when tag attributes must be objects and > not > >> atomic types, shouldn't they be treated accordingly? > > > > Tomcat behaves this way because the specification says it has to. Plenty > > of folks disagree strongly with the specification but Tomcat has to > > implement it. COERCE_TO_ZERO is a specification breaking configuration > > option to workaround this particular behaviour. > > > > I've been digging in to this some more and it appears that > > COERCE_TO_ZERO has been given a wider scope in later versions of Tomcat. > > The test case you present above behaves the way you want with > > COERCE_TO_ZERO set to false in 8.0.x and above. I need to dig into why > > that wider scope wasn't applied to 7.0.x. > > Mystery solved thanks to some svn archaeology and cross-referencing to > the relevant specs. > > Tomcat 7 implements EL 2.2. EL 2.2 requires coercion of "" and null to 0 > for numeric types (section 1.18.3). (As did earlier versions of the EL > spec). > > Initially there weren't many complaints because the coercion rules > weren't implemented correctly in one important case (i.e. they left > these as null rather than coercing to zero). Then bug 43285 [1] got > fixed and the complaints started. > > To address the complaints, Tomcat introduced the system property > org.apache.el.parser.COERCE_TO_ZERO which restored the non-specification > compliant behaviour for the one coercion case that was causing problems. > To align with the EL 2.2. specification, the default was for coercion to > zero to occur. > > The level of complaints about the coercion rules was such that a > backwards compatible change was introduced in EL 3.0 to not coerce to > zero. Given Java EE's normal approach that backwards compatibility > concerns trump all others, it is a sign of the seriousness with which > the issue was taken that an incompatible change was made. > > Tomcat 8, which implemented EL 3.0, switched to the new coercion rules. > To help migration of 7.0.x applications, the role of COERCE_TO_ZERO was > expanded to cover all instances of EL coercion. To align with EL 3.0, > the default was changed not to coerce to zero. > > Which brings us to where we are today. > > The problem you are seeing is a spec compliant coercion that is not > covered by the COERCE_TO_ZERO property in 7.0.x. > > There are several possible solutions: > > 1. Upgrade to 8.x (8.5.x recommended in preference to 8.0.x) > I appreciate that an RPM is not available for Tomcat 8 but 8.0.x has > had stable releases for three years and 8.5.x for 1 year. > > 2. Use one of the workarounds. All pretty ugly. > > 3. Lobby for the extension of scope for COERCE_TO_ZERO in 7.0.x to be > equivalent to the scope in 8.0.x. At this stage in the 7.0.x that is > unlikely to happen. The risk of breakage for other users is too > great. > > 4. Lobby for an additional configuration option for 7.0.x that extends > the of scope for COERCE_TO_ZERO in 7.0.x to be equivalent to the > scope in 8.0.x. This should be doable with care (there was some > refactoring involved in the scope change that would need careful > back-porting). This is also dependent on the CentOS distribution > picking up the change to 7.0.x. I don't know how likely that is. > Given the current package is based on a version over a year old I > suspect that the changes of this being quick are very low. > > None of those options look ideal. I'd probably go with 1 but my > familiarity with Tomcat is such that I usually prefer to work with an > ASF distribution rather than a downstream one anyway. YMMV. > > Mark > > > [1] https://issues.apache.org/bugzilla/show_bug.cgi?id=43285 > > > Mark, Thanks for the investigation into this. You are right in that (1) is the best option. Finding time to translate the ASF distribution into one with appropriate run scripts and configs, along with a mechanism for in-place updating is tough. Having RPMs for that saves me a lot of time which is why I stuck with 7.x for so long. In the meantime I'll figure out the cleanest ugly workaround I can. I definitely won't lobby for any non-security fixes in a product that is 2+ generations old and is probably approaching EOL in the not too distant future. Cheers, Chris