Expected behavior of <cfif (#right(dollarAmount,1)# == ".")> - java 20

EDITED to add the full code block in case the error is ME and my rusty coding and not the version of Open JDK.

<!--- for discussion purposes, the dollar amount is set via form submission --->
<cfset dollarAmount = "#form.dollarAmount#" />

<!--- check the formatting, append cents to any hanging decimal as a result 
of user entry of non numeric characters (yes this happened). 'dollarAmount" 
is parsed through a function to remove non numeric characters, but to still 
allow a decimal, thus the possibility of a hanging decimal on the right --->

<cfif (#right(dollarAmount,1)# == ".")>
	 <cfset dollarAmount="#dollarAmount#" & "00" />
</cfif>

<!--- check the formatting again --->

<cfif (#dollarAmount# != "") AND (#isNumeric(dollarAmount)#)>
	<cfset dollarAmount ="#numberFormat(dollarAmount, '0.00')#" />
</cfif>

Before upgrading to JDK 20 this was not an issue. I was running JDK 18 (IIR) before the upgrade.

The IF statement tested a dollar amount and, if after stripping non numeric characters, the remaining right most char was a decimal, then two 0’s were added to avoid an error encountered in previous JDK or Lucee or Railo versions.

This code snippet has been fine for years. But after upgrading to JDK 20, the result is that entering an amount without the cents (example: “20” vs “20.00”), results in two place values being added to the number. So, an entry of “20” becomes “2000.00”. However, if I enter 20.00, then that remains as 20.00.

Why would this change? How is the CFIF statement being evaluated now?

My solution is that I simply REMOVED the first IF statement and now things are working as expected:

<!--- check the formatting, append cents to any hanging decimal as a result of user entry 
of non numeric characters (yes this happened): 8/10/23: this is not giving the expected 
results after upgrade to Open JDK 20 - remove it 

<cfif (#right(dollarAmount,1)# == ".")>
	 <cfset paymentTotal="#dollarAmount#" & "00" />
</cfif> --->

Ubuntu 22.04 LTS
Java (JDK) 20.0.2
Tomcat 9.0.41
Lucee 5.4.1.8

they have made some Unicode related in changes java 19 and 20 which change behaviour, so I wouldn’t be surprised if their are additional changes/problems which need to be addressed

Zac, I notice you aren’t objecting to Derrick’s use of Java 20 with Lucee 5. Have I missed some news, perhaps?

I was in the midst of writing a reply, pointing out your reply of a several weeks ago saying that even Lucee 6 still didn’t support Java 17.

There are still a number of things which don’t work with Java 17 yet, a number of test cases are failing, but we are making progress!.. Base line for Lucee 6 is Java 11, Java 8 is supported as long as we can

Has that changed, for Lucee 6, let alone Lucee 5? Sincere question.

Also, I’d hoped to point to the system requirements page, but it makes no mention of Java version support. Would that or another be the best place for folks to look to, for the current state of Java version supported by each major lucee version?

only 11 is officially supported, as per all release notes to date :slight_smile:

Also, Derrick, can you share what code is SETTING your dollaramount var? It would seem the problem starts there. And there may be a more specific explanation “what changed, where”, perhaps even something that feeds THAT code.

One more thing that I know some will be itching to point out: you don’t need to use the #s there. Cfml can figure out that’s a function (or var) used there. But to be clear, no, it should NOT affect processing, and no, it would not “be faster” without the hashes, and so no, you do not NEED to change it. It’s just “nails on a chalkboard” to some of us when we see it. :slight_smile:

Zac, OK. But what about the rest (first and last points)? Not picking a fight, but trying to help everyone.

And by "last point ", I mean wouldn’t it be better for some one place (like the system requirements page) to list that as another fundamental requirement, versus digging through release notes?

By that I mean, one couldn’t just look at the release note for the build they’re running, as the Java support could have changed in a prior update, right? So they’d have to look back through many potentially, it seems.

(And this doesn’t seem an “it’s open source, do it yourself” sort of thing, but more of a strategic decision to be made and kept updated. That’s why I’m asking.)

Thanks Charlie!!! Indeed, I spent several years away from web development and still have lots of old habits. So, you are saying that I basically never need the # around any variables, or just specific ones?

Also, I edited the post to show the complete block of code I wrote to prevent what was once a possible error. I had users accidentally entering letters at the end of a dollar amount. And often a $ before it, because some of the users of this particular system are (excuse my language), old. As in 80+ and using old browsers which may or may not support some errors checking on the front end. So this was designed to prevent a handing decimal at the end, after I strip away non numeric characters and leave only 0-9 and a “.” And so this worked fine from implementation in 2018 through this past month when I did the upgrade.

Derrick, no, I was not saying never. More on that in a moment.

As for your having changed the original post I still don’t see where you SET the dollaramount. That was my main point.

Also I’d beware your approach of slapping the 00 on the end without some test. I could see that coming back to bite you, even if it works now.

(And if future readers may find my comments confusing or not in line with Derrick’s original question, he may have changed it again since I wrote this.)

Finally back to the hash/pound sign matter, those who’ve been around for years may have seen various attempts over the years by people trying to explain their perspective on when these are and are not needed. To be clear, I was just speaking to your code fragment (and as much for those who would have wanted to jump on it). :slight_smile: I was not intending to elaborate on the point beyond that. Maybe I’ll do a blog post to offer my take, which I’ve found to be accurate over the years and has helped others. But this thread is not the right place. :slight_smile:

1 Like

Specifically?

I updated that docs page too, thanks for reminding me

1 Like

Isn’t Open JDK 20 (and all versions of Open JDK from 11-20) based on java 11?

Basically, but every major release has breaking changes

I made a few more edits to the post to try and make everything clear. In the end, the appending of the ‘00’ is not needed since the var is also being set as 0.00 via the formatting block below it.

BUT, my main question really is how does the newer version of OpenJDK handle evaluating a decimal?

So, for example if you want to take action on a decimal “.” what will JDK 20 do? In this case, I wrote a block that looked for the last character in a string (which happens to be numeric). If that last char is a decimal/period, do something. JDK seems to not wnat to do what it has done before.

I don’t really understand the issue you’re reporting and when I run the exact code, I don’t get the result you said you get.

I put the following exact code in an index.cfm

<cfset dollarAmount = "20" />

<cfif (#right(dollarAmount,1)# == ".")>
	 <cfset paymentTotal="#dollarAmount#" & "00" />
</cfif>

<cfif (#dollarAmount# != "") AND (#isNumeric(dollarAmount)#)>
	<cfset dollarAmount ="#numberFormat(dollarAmount, '0.00')#" />
</cfif>

<cfdump var="#server.lucee.version#">
<cfdump var="#server.java.version#">
<cfdump var="#dollarAmount#">

and ran the following CommandBox command to spin up a test server

start  cfengine=lucee@5.4.1.8 javaVersion=openjdk20

The output on the page is:

5.4.1.8
20.0.2
20.00

You said I should get the number 2000.00, but I got 20.00 as expected. Please include a fully-standalone chunk of code I can run that demonstrates your issue.

Oh wait-- I see the issue. Your repro case is not correct. I think you intended to have this

<cfset dollarAmount="#dollarAmount#" & "00" />

instead of

 <cfset paymentTotal="#dollarAmount#" & "00" />

Ok, I see the issue, but you greatly over-compicated it. Here is the condensed repro case.

0 == "." // Returns true

That’s all you needed to reproduce :slight_smile: Basically a single period is being parsed as the number zero, and then Lucee says they are equivalent. I assume Lucee is simply relying on an underlying class from the JDK to parse a string into a number and Java 20 changed the rules on what can be parsed into a number.

Another way to show that a single period is now regarded as zero is this

dot = '.'
echo( dot + 5 ) // Outputs 5

In fact, here’s the Caster class in Lucee that turns the period into a 0. (Seems it doesn’t even use any JDK double parsing anyway)

createObject('java','lucee.runtime.op.Caster').toDoubleValue('.',true) // returns 0

But here’s the kicker-- this doesn’t just work on Java 20-- I can reproduce this on Java 8!

I’d say the behavior probably changed when you updated Lucee. Either that, or there’s some other thing at play changing the code path.


For funsies here’s a few more answers:

Simply put, hashes are required when interpolating a variable inside a string. Your code is not doing this, so the hashes are extraneous.

Yes, and Windows 11 is “based on” Windows 95. I’m not sure what conclusion you’re trying to draw from that however :slight_smile:

1 Like

Ah.! Thank you!! That is embarrassing that I didn’t change the code example. Yes, the code example should have been:

<cfif (#dollarAmount# != "") AND (#isNumeric(dollarAmount)#)>
	<cfset dollarAmount ="#numberFormat(dollarAmount, '0.00')#" />
</cfif>

When I posted this, I cleaned up the example for simplicity sake. The variable in the actual code is named “paymentAmount” but I changed that to “dollarAmount” here to simplify the issue. Same problem either way in real world (for me).

Thank you for confirming that it is being evaluated as 0.

The only thing I can say here is that this was NOT happening prior to my upgrade to either Lucee or JDK 20. That obviously doesn’t mean my code was well written, just that it wasn’t happening.

As for # signs on variables, I understand, but I also prefer to be able to spot variables in code quickly. As long as there is no performance issue, I am able to scan lots of lines faster and spot the #variables# that stand out. But probably a bad habit.

@Zackster, I took a look at the lucee java 17 issues and the two imageRotate and imageOverlay issues would I believe be solved with something like this:

--add-exports=java.desktop/sun.awt.image=ALL-UNNAMED

This is simply because my guess is that the java module is not described in the lucee project for these types of things, but if you named the module in a module definition you could refer to lucee specifically there instead of ALL-UNNAMED.

I hope that helps. I couldn’t see an easier way to communicate on the jira page, but likely I missed something obvious haha.