<div dir="ltr"><ul><li>Attaching the sample code file (same code copied inline in the above issue)</li><li>Tested with hotspot vm JDK 17 temu and adopt JDK 8, for the above non-deterministic behavior.</li><li>Also tested with opnJ9 (IBM, jdk8), which returned always a new String, so == comparison will always fail and only .equals will work.</li></ul></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Jun 19, 2022 at 11:29 PM Sasi Peri <<a href="mailto:pvssasikala@gmail.com">pvssasikala@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hello,<div><br></div><div><p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><b>Issue details</b></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif">toLower() and toUpper() return a new String object sometimes
and sometimes a string literal, based on the input string type (and also sometimes
based on the VM/jdk type)</p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"> </p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif">For example</p>
<p style="margin:0in 0in 0in 0.5in;font-size:12pt;font-family:Calibri,sans-serif">-<span style="font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:7pt;line-height:normal;font-family:"Times New Roman"">
</span>HotSpot VM, If the input is a string literal,
which *already* has all “lower case letters”, toLower would return the same
string literal, if not it will convert all letters to lower and returns a new
String() object.</p>
<p style="margin:0in 0in 0in 0.5in;font-size:12pt;font-family:Calibri,sans-serif">-<span style="font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:7pt;line-height:normal;font-family:"Times New Roman"">
</span>However, openJ9 (e.g. IBM jdk8 ditsro, ) always
returns a new String object not a literal.</p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"> </p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif">This behavior is non deterministic, inconsistent, you cannot
always predict if the outcome is a new string object OR an interned string from
pool (particularly from unit testing stand point).</p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"> </p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><b>Sample code to show case above behavior</b></p>
<table border="1" cellspacing="0" cellpadding="0" style="border-collapse:collapse;border:none">
<tbody><tr>
<td width="623" valign="top" style="width:467.5pt;border:1pt solid windowtext;padding:0in 5.4pt">
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><b><span style="font-size:9pt;font-family:Menlo;color:rgb(127,0,85)">package</span></b><span style="font-size:9pt;font-family:Menlo;color:black"> com.bugs;</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><b><span style="font-size:9pt;font-family:Menlo;color:rgb(127,0,85)">import</span></b><span style="font-size:9pt;font-family:Menlo;color:black"> java.util.Locale;</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo"> </span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><b><span style="font-size:9pt;font-family:Menlo;color:rgb(127,0,85)">public</span></b><span style="font-size:9pt;font-family:Menlo;color:black"> </span><b><span style="font-size:9pt;font-family:Menlo;color:rgb(127,0,85)">class</span></b><span style="font-size:9pt;font-family:Menlo;color:black"> TestStringFunction </span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black">{</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> </span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><b><span style="font-size:9pt;font-family:Menlo;color:rgb(127,0,85)"> public</span></b><span style="font-size:9pt;font-family:Menlo;color:black"> </span><b><span style="font-size:9pt;font-family:Menlo;color:rgb(127,0,85)">static</span></b><span style="font-size:9pt;font-family:Menlo;color:black"> </span><b><span style="font-size:9pt;font-family:Menlo;color:rgb(127,0,85)">void</span></b><span style="font-size:9pt;font-family:Menlo;color:black"> main(String </span><span style="font-size:9pt;font-family:Menlo;color:rgb(106,62,62)">args</span><span style="font-size:9pt;font-family:Menlo;color:black">[])</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> {</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> String </span><span style="font-size:9pt;font-family:Menlo;color:rgb(106,62,62)">s1</span><span style="font-size:9pt;font-family:Menlo;color:black"> = </span><span style="font-size:9pt;font-family:Menlo;color:rgb(42,0,255)">"abc"</span><span style="font-size:9pt;font-family:Menlo;color:black">;</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> String </span><span style="font-size:9pt;font-family:Menlo;color:rgb(106,62,62)">s2</span><span style="font-size:9pt;font-family:Menlo;color:black"> = </span><span style="font-size:9pt;font-family:Menlo;color:rgb(42,0,255)">"ABC"</span><span style="font-size:9pt;font-family:Menlo;color:black">;</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> </span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> System.</span><b><i><span style="font-size:9pt;font-family:Menlo;color:rgb(0,0,192)">out</span></i></b><span style="font-size:9pt;font-family:Menlo;color:black">.println(</span><span style="font-size:9pt;font-family:Menlo;color:rgb(42,0,255)">"----- case:
when string already lower ----------"</span><span style="font-size:9pt;font-family:Menlo;color:black">);</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><i><span style="font-size:9pt;font-family:Menlo;color:black;background:rgb(212,212,212)"> testIfEqualsLower</span></i><span style="font-size:9pt;font-family:Menlo;color:black">(</span><span style="font-size:9pt;font-family:Menlo;color:rgb(106,62,62)">s1</span><span style="font-size:9pt;font-family:Menlo;color:black">);</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> </span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> System.</span><b><i><span style="font-size:9pt;font-family:Menlo;color:rgb(0,0,192)">out</span></i></b><span style="font-size:9pt;font-family:Menlo;color:black">.println(</span><span style="font-size:9pt;font-family:Menlo;color:rgb(42,0,255)">"----- case:
when string with upper case ----------"</span><span style="font-size:9pt;font-family:Menlo;color:black">);</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><i><span style="font-size:9pt;font-family:Menlo;color:black;background:rgb(212,212,212)"> testIfEqualsLower</span></i><span style="font-size:9pt;font-family:Menlo;color:black">(</span><span style="font-size:9pt;font-family:Menlo;color:rgb(106,62,62)">s2</span><span style="font-size:9pt;font-family:Menlo;color:black">);</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> </span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> </span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> }</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> </span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><b><span style="font-size:9pt;font-family:Menlo;color:rgb(127,0,85)"> private</span></b><span style="font-size:9pt;font-family:Menlo;color:black"> </span><b><span style="font-size:9pt;font-family:Menlo;color:rgb(127,0,85)">static</span></b><span style="font-size:9pt;font-family:Menlo;color:black"> </span><b><span style="font-size:9pt;font-family:Menlo;color:rgb(127,0,85)">void</span></b><span style="font-size:9pt;font-family:Menlo;color:black"> <span style="background:rgb(212,212,212)">testIfEqualsLower</span>(String
</span><span style="font-size:9pt;font-family:Menlo;color:rgb(106,62,62)">s</span><span style="font-size:9pt;font-family:Menlo;color:black">) </span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> {</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> </span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><b><span style="font-size:9pt;font-family:Menlo;color:rgb(127,0,85)"> if</span></b><span style="font-size:9pt;font-family:Menlo;color:black">(</span><span style="font-size:9pt;font-family:Menlo;color:rgb(106,62,62)">s</span><span style="font-size:9pt;font-family:Menlo;color:black">.toLowerCase() == </span><span style="font-size:9pt;font-family:Menlo;color:rgb(42,0,255)">"abc"</span><span style="font-size:9pt;font-family:Menlo;color:black">)</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> {</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> System.</span><b><i><span style="font-size:9pt;font-family:Menlo;color:rgb(0,0,192)">out</span></i></b><span style="font-size:9pt;font-family:Menlo;color:black">.println(</span><span style="font-size:9pt;font-family:Menlo;color:rgb(42,0,255)">"YES -
literal"</span><span style="font-size:9pt;font-family:Menlo;color:black">);</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> }</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> </span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><b><span style="font-size:9pt;font-family:Menlo;color:rgb(127,0,85)"> if</span></b><span style="font-size:9pt;font-family:Menlo;color:black">(</span><span style="font-size:9pt;font-family:Menlo;color:rgb(106,62,62)">s</span><span style="font-size:9pt;font-family:Menlo;color:black">.toLowerCase().equals(</span><span style="font-size:9pt;font-family:Menlo;color:rgb(42,0,255)">"abc"</span><span style="font-size:9pt;font-family:Menlo;color:black">))</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> {</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> System.</span><b><i><span style="font-size:9pt;font-family:Menlo;color:rgb(0,0,192)">out</span></i></b><span style="font-size:9pt;font-family:Menlo;color:black">.println(</span><span style="font-size:9pt;font-family:Menlo;color:rgb(42,0,255)">"YES – equals func"</span><span style="font-size:9pt;font-family:Menlo;color:black">);</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> }</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> </span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black"> }</span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt">}</span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt"> </span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt"> </span></p>
</td>
</tr>
<tr>
<td width="623" valign="top" style="width:467.5pt;border-right:1pt solid windowtext;border-bottom:1pt solid windowtext;border-left:1pt solid windowtext;border-top:none;padding:0in 5.4pt">
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><b><u><span style="font-size:9pt;font-family:Menlo;color:rgb(192,0,0)">Out put</span></u></b></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><b><u><span style="font-size:9pt;font-family:Menlo;color:rgb(192,0,0)"><span style="text-decoration-line:none"> </span></span></u></b></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black">----- case: when string
already lower ----------</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black">YES - literal</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black">YES – equals func</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo"> </span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black">----- case: when string
with upper case ----------</span><span style="font-size:9pt;font-family:Menlo"></span></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:9pt;font-family:Menlo;color:black">YES - equals func</span><b><span style="font-size:9pt;font-family:Menlo;color:rgb(127,0,85)"></span></b></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><b><span style="font-size:9pt;font-family:Menlo;color:rgb(127,0,85)"> </span></b></p>
</td>
</tr>
</tbody></table>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"> </p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><b>Why this could be an issue or bug prone?</b></p>
<p style="margin:0in 0in 0in 0.5in;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:12pt">-</span><span style="font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:7pt;line-height:normal;font-family:"Times New Roman"">
</span><span style="font-size:12pt">Suppose an unit test is written, for a method doAThing(),
that has toLower/Upper conversions in the middle of the code somewhere, and
apply logic based on that.</span><br><span style="font-size:12pt">-</span><span style="font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:7pt;line-height:normal;font-family:"Times New Roman"">
</span><span style="font-size:12pt">Though general guidance to compare unknown
string (types) is always using equals, sometimes developers can make a mistake
(i.e. suppose they used == in a unit test)</span><br><span style="font-size:12pt">-</span><span style="font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:7pt;line-height:normal;font-family:"Times New Roman"">
</span><span style="font-size:12pt">If the code review did not catch it, this behavior
can cause all unit tests passed, as long unit test is written with “small case
string” as input.</span><br><span style="font-size:12pt">-</span><span style="font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:7pt;line-height:normal;font-family:"Times New Roman"">
</span><span style="font-size:12pt">It could potentially make it to prod, and can be
realized only when it hits a case </span>when input<span style="font-size:12pt"> string has all uppercase OR mixed
case letters, which could be after multiple sprints, at the point not easily detectable.</span><br></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"> </p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><b>Suggestion</b></p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif">It would be great if we always can make a new String() and
return always a String object not an interned string sometimes, as openJ9/ibm
does (with some jdk versions). </p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif">It may not be good idea, to always return “.interned” value
and fill up the intern pool, for these short-lived objects (as they are most times).</p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"> </p>
<p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif">If this is agreed/approved, I can make a change and commit.</p><p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif"><br></p><p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif">Regards</p><p class="MsoNormal" style="margin:0in;font-size:12pt;font-family:Calibri,sans-serif">- SP</p></div></div>
</blockquote></div>