Re: Difference in Template Rendering Between Velocity 2.3 and 2.4.1 for Map with List

Mergu Ravi <[email protected]> Wed, 23 Jul 2025 19:16:39 +0530
Newsgroups gmane.comp.jakarta.velocity.user
Message-ID <CAK+i-4JrO-CCsod6s3YkcgiTA5V7bVPB-CO42ER5fz375p+bSA__43837.4998558842$1753278561$gmane$org@mail.gmail.com>
--000000000000ecad42063a98f020
Content-Type: multipart/alternative; boundary="000000000000ecad42063a98f01f"

--000000000000ecad42063a98f01f
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

This PR(https://github.com/apache/velocity-engine/pull/45) is the route
cause for this issue.

Because of this change, in *UberspectImpl.getPropertyGet()* method the
*executor* value is *PropertyExecutor* instead of *MapGetExecutor*

*to replicate this issue sample program:*

import com.fasterxml.jackson.core.JsonProcessingException;
> import com.fasterxml.jackson.databind.ObjectMapper;
> import org.apache.velocity.VelocityContext;
> import org.apache.velocity.app.VelocityEngine;
> import org.apache.velocity.runtime.VelocityEngineVersion;
>
> import java.io.StringWriter;
> import java.util.Map;
>
> public class TestVelocity {
>     public static final String studentData =3D "{ \"student\": { \"values=
\":
> [ " +
>             "{ \"id\": 1, \"name\": \"Alice\", \"age\": 20, \"grade\":
> \"A\" }, " +
>             "{ \"id\": 2, \"name\": \"Bob\", \"age\": 21, \"grade\": \"B\=
"
> } ] } }";
>     public static final String editorContent =3D "{\n" +
>             "    \"students\" :  $student.values\n" +
>             "}\n";
>     public static final String LOG_LABEL =3D "TemplateParser";
>     public static void main(String[] args) throws JsonProcessingException=
 {
>         VelocityEngine velocityEngine =3D new VelocityEngine();
>         StringWriter writer =3D new StringWriter();
>         Map studentsMap =3D new ObjectMapper().readValue(studentData,
> Map.class);
>         VelocityContext context =3D new VelocityContext(studentsMap);
>         velocityEngine.init();
>         velocityEngine.evaluate(context,writer,LOG_LABEL,editorContent);
>         System.out.println("Velocity Version: " +
> VelocityEngineVersion.VERSION);
>         System.out.println(writer.toString());
>     }
> }


*output in v2.3: *
Velocity Version: 2.3
{
    "students" :  [{id=3D1, name=3DAlice, age=3D20, grade=3DA}, {id=3D2, na=
me=3DBob,
age=3D21, grade=3DB}]
}
*output in v 2.4.1:*
Velocity Version: 2.4.1
{
    "students" :  [[{id=3D1, name=3DAlice, age=3D20, grade=3DA}, {id=3D2, n=
ame=3DBob,
age=3D21, grade=3DB}]]
}


*Screenshots:*
*Java program in version 2.3:*
https://github.com/mergurishaan/VelocityIssue/blob/main/jpv23.png?raw=3Dtru=
e
*vg.executor value in 2.3:*
https://github.com/mergurishaan/VelocityIssue/blob/main/vg_23.png?raw=3Dtru=
e
*java program In version 2.4.1:*
https://github.com/mergurishaan/VelocityIssue/blob/main/jpv241.png?raw=3Dtr=
ue
*vg.executor value in 2.4.1: *
https://github.com/mergurishaan/VelocityIssue/blob/main/vg_241.png?raw=3Dtr=
ue

On Tue, Jul 22, 2025 at 7:08=E2=80=AFPM Mergu Ravi <mergu.ravi@gaiansolutio=
ns.com>
wrote:

> Dear Velocity Team,
>
> I hope this message finds you well.
>
> I'm currently using Apache Velocity in my Java application, and I noticed
> a behavioral difference in template rendering when upgrading from version
> *2.3* to *2.4.1*.
> Template:
>
> {
>   "students" :  $student.values
> }
>
> Sample JSON (studentData):
>
> {
>   "student": {
>     "values": [
>       { "id": 1, "name": "Alice", "age": 20, "grade": "A" },
>       { "id": 2, "name": "Bob", "age": 21, "grade": "B" }
>     ]
>   }
> }
>
> Output in Velocity 2.3:
>
> {
>   "students" : [{id=3D1, name=3DAlice, age=3D20, grade=3DA}, {id=3D2, nam=
e=3DBob, age=3D21, grade=3DB}]
> }
>
> Output in Velocity 2.4.1:
>
> {
>   "students" : [[{id=3D1, name=3DAlice, age=3D20, grade=3DA}, {id=3D2, na=
me=3DBob, age=3D21, grade=3DB}]]
> }
>
> Concern:
>
> In *2.4.1*, the result includes an extra set of brackets, indicating that
> Velocity is now treating the .values object as a list containing a list
> instead of a list itself.
>
> This change in behavior breaks backward compatibility in my use case. I'm
> unsure if this change was intentional or a regression.
> Screenshots:
>
> I=E2=80=99ve attached screenshots of the same Java code executed with bot=
h
> versions:
>
>    -
>
>    *velocity-2.3*
>    - [image: Screenshot from 2025-07-22 18-38-28.png]
>
>    -
>
>    *velocity-2.4.1*
>    - [image: Screenshot from 2025-07-22 18-39-00.png]
>
>
> Request:
>
> Could you please clarify if this is:
>
>    -
>
>    An intended change in how Velocity handles map values, or
>    -
>
>    A bug introduced in the recent release?
>
> Additionally, if there's a recommended workaround or best practice for
> handling this in 2.4.1, I=E2=80=99d greatly appreciate the guidance.
>
> Thanks for maintaining such a helpful project!
>
> Best regards,
> *Ravi Mergu*
> ------------------------------
>

--000000000000ecad42063a98f01f
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><div>This PR(<a href=3D"https://github.com/apache/vel=
ocity-engine/pull/45">https://github.com/apache/velocity-engine/pull/45</a>=
) is the route cause for this issue.<br><br></div>Because of this change, i=
n <b>UberspectImpl.getPropertyGet()</b> method the <b>executor</b> value is=
 <b>PropertyExecutor</b> instead of <b>MapGetExecutor</b><div><br></div><b>=
to replicate this issue sample program:</b></div><div><b><br></b></div><blo=
ckquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204=
,204);padding-left:1ex" class=3D"gmail_quote">import com.fasterxml.jackson.=
core.JsonProcessingException;<br>import com.fasterxml.jackson.databind.Obje=
ctMapper;<br>import org.apache.velocity.VelocityContext;<br>import org.apac=
he.velocity.app.VelocityEngine;<br>import org.apache.velocity.runtime.Veloc=
ityEngineVersion;<br><br>import java.io.StringWriter;<br>import java.util.M=
ap;<br><br>public class TestVelocity {<br>=C2=A0 =C2=A0 public static final=
 String studentData =3D &quot;{ \&quot;student\&quot;: { \&quot;values\&quo=
t;: [ &quot; +<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &quot;{ \&quot;=
id\&quot;: 1, \&quot;name\&quot;: \&quot;Alice\&quot;, \&quot;age\&quot;: 2=
0, \&quot;grade\&quot;: \&quot;A\&quot; }, &quot; +<br>=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 &quot;{ \&quot;id\&quot;: 2, \&quot;name\&quot;: \&qu=
ot;Bob\&quot;, \&quot;age\&quot;: 21, \&quot;grade\&quot;: \&quot;B\&quot; =
} ] } }&quot;;<br>=C2=A0 =C2=A0 public static final String editorContent =
=3D &quot;{\n&quot; +<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &quot; =
=C2=A0 =C2=A0\&quot;students\&quot; : =C2=A0$student.values\n&quot; +<br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &quot;}\n&quot;;<br>=C2=A0 =C2=A0=
 public static final String LOG_LABEL =3D &quot;TemplateParser&quot;;<br>=
=C2=A0 =C2=A0 public static void main(String[] args) throws JsonProcessingE=
xception {<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 VelocityEngine velocityEngine =3D=
 new VelocityEngine();<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 StringWriter writer =
=3D new StringWriter();<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 Map studentsMap =3D =
new ObjectMapper().readValue(studentData, Map.class);<br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 VelocityContext context =3D new VelocityContext(studentsMap);<br=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 velocityEngine.init();<br>=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 velocityEngine.evaluate(context,writer,LOG_LABEL,editorContent);<br=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 System.out.println(&quot;Velocity Version: &qu=
ot; + VelocityEngineVersion.VERSION);<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 System=
.out.println(writer.toString());<br>=C2=A0 =C2=A0 }<br>}</blockquote><div><=
br></div><div><b>output in v2.3:=C2=A0</b><br><div style=3D"margin-left:40p=
x">Velocity Version: 2.3<br>{<br>=C2=A0 =C2=A0 &quot;students&quot; : =C2=
=A0[{id=3D1, name=3DAlice, age=3D20, grade=3DA}, {id=3D2, name=3DBob, age=
=3D21, grade=3DB}]<br>}</div><b>output=C2=A0in v 2.4.1:</b></div><div><div =
style=3D"margin-left:40px">Velocity Version: 2.4.1<br>{<br>=C2=A0 =C2=A0 &q=
uot;students&quot; : =C2=A0[[{id=3D1, name=3DAlice, age=3D20, grade=3DA}, {=
id=3D2, name=3DBob, age=3D21, grade=3DB}]]<br>}<br><br></div></div><div><br=
></div><div><b>Screenshots:</b><br></div><div><b>Java program in version 2.=
3:</b> <a href=3D"https://github.com/mergurishaan/VelocityIssue/blob/main/j=
pv23.png?raw=3Dtrue">https://github.com/mergurishaan/VelocityIssue/blob/mai=
n/jpv23.png?raw=3Dtrue</a></div><div><b>vg.executor value in 2.3:</b>=C2=A0=
<a href=3D"https://github.com/mergurishaan/VelocityIssue/blob/main/vg_23.pn=
g?raw=3Dtrue">https://github.com/mergurishaan/VelocityIssue/blob/main/vg_23=
.png?raw=3Dtrue</a></div><div><b>java program In version 2.4.1:</b>=C2=A0<a=
 href=3D"https://github.com/mergurishaan/VelocityIssue/blob/main/jpv241.png=
?raw=3Dtrue">https://github.com/mergurishaan/VelocityIssue/blob/main/jpv241=
.png?raw=3Dtrue</a><br></div><div><b>vg.executor value in 2.4.1:=C2=A0</b><=
a href=3D"https://github.com/mergurishaan/VelocityIssue/blob/main/vg_241.pn=
g?raw=3Dtrue">https://github.com/mergurishaan/VelocityIssue/blob/main/vg_24=
1.png?raw=3Dtrue</a></div></div><br><div class=3D"gmail_quote gmail_quote_c=
ontainer"><div dir=3D"ltr" class=3D"gmail_attr">On Tue, Jul 22, 2025 at 7:0=
8=E2=80=AFPM Mergu Ravi &lt;<a href=3D"mailto:[email protected]=
">[email protected]</a>&gt; wrote:<br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex"><div dir=3D"ltr"><p>Dear Velocity Team,</p=
><p>I hope this message finds you well.</p>
<p>I&#39;m currently using Apache Velocity in my Java application, and I no=
ticed a behavioral difference in template rendering when upgrading from ver=
sion <strong>2.3</strong> to <strong>2.4.1</strong>.</p><h3>Template:</h3>
<pre><code>{
  &quot;students&quot; :  $student.values
}
</code></pre>
<h3>Sample JSON (<code>studentData</code>):</h3>
<pre><code>{
  &quot;student&quot;: {
    &quot;values&quot;: [
      { &quot;id&quot;: 1, &quot;name&quot;: &quot;Alice&quot;, &quot;age&q=
uot;: 20, &quot;grade&quot;: &quot;A&quot; },
      { &quot;id&quot;: 2, &quot;name&quot;: &quot;Bob&quot;, &quot;age&quo=
t;: 21, &quot;grade&quot;: &quot;B&quot; }
    ]
  }
}
</code></pre>
<h3>Output in Velocity 2.3:</h3>
<pre><code>{
  &quot;students&quot; : [{id=3D1, name=3DAlice, age=3D20, grade=3DA}, {id=
=3D2, name=3DBob, age=3D21, grade=3DB}]
}
</code></pre>
<h3>Output in Velocity 2.4.1:</h3>
<pre><code>{
  &quot;students&quot; : [[{id=3D1, name=3DAlice, age=3D20, grade=3DA}, {id=
=3D2, name=3DBob, age=3D21, grade=3DB}]]
}
</code></pre>
<h3>Concern:</h3>
<p>In <strong>2.4.1</strong>, the result includes an extra set of brackets,=
 indicating that Velocity is now treating the <code>.values</code> object a=
s a list containing a list instead of a list itself.</p>
<p>This change in behavior breaks backward compatibility in my use case. I&=
#39;m unsure if this change was intentional or a regression.</p>
<h3>Screenshots:</h3>
<p>I=E2=80=99ve attached screenshots of the same Java code executed with bo=
th versions:</p>
<ul><li>
<p><code><b><font size=3D"4">velocity-2.3</font></b></code></p></li><li><im=
g src=3D"cid:ii_mdekqo901" alt=3D"Screenshot from 2025-07-22 18-38-28.png" =
width=3D"554" height=3D"470"><br><br></li><li>
<p><code><font size=3D"4"><b>velocity-2.4.1</b></font></code></p></li><li><=
img src=3D"cid:ii_mdekq5uk0" alt=3D"Screenshot from 2025-07-22 18-39-00.png=
" width=3D"554" height=3D"470"><br><br></li></ul>
<h3>Request:</h3>
<p>Could you please clarify if this is:</p>
<ul><li>
<p>An intended change in how Velocity handles map values, or</p>
</li><li>
<p>A bug introduced in the recent release?</p>
</li></ul>
<p>Additionally, if there&#39;s a recommended workaround or best practice f=
or handling this in 2.4.1, I=E2=80=99d greatly appreciate the guidance.</p>
<p>Thanks for maintaining such a helpful project!</p>
<p>Best regards,<br><strong>Ravi Mergu</strong></p>
<hr></div>
</blockquote></div>

--000000000000ecad42063a98f01f--
--000000000000ecad42063a98f020--