Bug 780623 - (SOA-3061) Freemarker error when input files contains namespace declaration
Freemarker error when input files contains namespace declaration
Status: ASSIGNED
Product: JBoss Enterprise SOA Platform 5
Classification: JBoss
Component: JBossESB (Show other bugs)
5.1.0 GA
Unspecified Unspecified
high Severity high
: ---
: 5.2.0 GA,5.2.0.ER4
Assigned To: Tom Fennelly
http://jira.jboss.org/jira/browse/SOA...
: Reopened
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2011-05-06 10:28 EDT by Martin Weiler
Modified: 2012-02-22 11:35 EST (History)
4 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2011-11-04 08:49:27 EDT
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
quickstart_freemarker_namespace_failure.zip (14.18 KB, application/zip)
2011-05-06 10:29 EDT, Martin Weiler
no flags Details


External Trackers
Tracker ID Priority Status Summary Last Updated
JBoss Issue Tracker JBESB-3680 None Closed Freemarker error when input files contains namespace declaration 2012-02-22 11:36:01 EST
JBoss Issue Tracker SOA-3061 None Closed Freemarker error when input files contains namespace declaration 2012-02-22 11:36:02 EST

  None (edit)
Description Martin Weiler 2011-05-06 10:28:54 EDT
Help Desk Ticket Reference: https://na7.salesforce.com/500A0000007ASa2
Steps to Reproduce: 1. Deploy attached modified transform_XML2XML quickstart
2. Run 'ant runsuccess' to try the Freemarker template based transformation. The input file SampleOrder.xml (which contains no namespace declaration) is used for this.
3. Run 'ant runfailure', which uses the input file SampleOrderFailure.xml (which contains namespace declaration) to reproduce the error.

Workaround: Workaround Exists
Workaround Description: Until there is a way to strip the namespace from the DOM fragment that has been created by the DomModelCreator, a workaround would be to remove the namespace from the incoming document *before* the SmooksAction, using XSLT:

jboss-esb.xml:
-------------
    <!-- Remove namespace from input document before the SmooksAction -->
    <action name="remove-namespace-using-xslt" class="org.jboss.soa.esb.actions.transformation.xslt.XsltAction">
        <property name="templateFile" value="/smooks.xsl"/>
    </action>     
    <action name="simple-transform" class="org.jboss.soa.esb.smooks.SmooksAction">
        <property name="smooksConfig" value="/smooks-res.xml" />
    </action>

smooks.xsl:
-------------
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/|comment()|processing-instruction()">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

<xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
</xsl:template>

<xsl:template match="@*">
    <xsl:attribute name="{local-name()}">
      <xsl:value-of select="."/>
    </xsl:attribute>
</xsl:template>
</xsl:stylesheet>
project_key: SOA

Using an input file which contains a namespace declaration for a FreeMarker transformation leads to the following error:

13:58:42,859 ERROR [runtime] 
Error on line 1, column 3 in orderLinesFrag.ftl
Expecting a string, date or number here, Expression item.nachname is instead a freemarker.ext.dom.NodeListModel
The problematic instruction:
----------
==> ${item.nachname} [on line 1, column 1 in orderLinesFrag.ftl]
----------

Java backtrace for programmers:
----------
freemarker.core.NonStringException: Error on line 1, column 3 in orderLinesFrag.ftl
Expecting a string, date or number here, Expression item.nachname is instead a freemarker.ext.dom.NodeListModel
        at freemarker.core.Expression.getStringValue(Expression.java:126)
        at freemarker.core.Expression.getStringValue(Expression.java:93)
        at freemarker.core.DollarVariable.accept(DollarVariable.java:76)
        at freemarker.core.Environment.visit(Environment.java:208)
        at freemarker.core.MixedContent.accept(MixedContent.java:92)
        at freemarker.core.Environment.visit(Environment.java:208)
        at freemarker.core.Environment.process(Environment.java:188)
        at freemarker.template.Template.process(Template.java:232)
        at org.milyn.templating.freemarker.FreeMarkerTemplateProcessor.applyTemplate(FreeMarkerTemplateProcessor.java:356)
Comment 1 Martin Weiler 2011-05-06 10:29:14 EDT
Attachment: Added: quickstart_freemarker_namespace_failure.zip
Comment 2 Martin Weiler 2011-05-13 04:44:19 EDT
Workaround Description: Added: Until there is a way to strip the namespace from the DOM fragment that has been created by the DomModelCreator, a workaround would be to remove the namespace from the incoming document *before* the SmooksAction, using XSLT:

jboss-esb.xml:
-------------
    <!-- Remove namespace from input document before the SmooksAction -->
    <action name="remove-namespace-using-xslt" class="org.jboss.soa.esb.actions.transformation.xslt.XsltAction">
        <property name="templateFile" value="/smooks.xsl"/>
    </action>     
    <action name="simple-transform" class="org.jboss.soa.esb.smooks.SmooksAction">
        <property name="smooksConfig" value="/smooks-res.xml" />
    </action>

smooks.xsl:
-------------
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/|comment()|processing-instruction()">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

<xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
</xsl:template>

<xsl:template match="@*">
    <xsl:attribute name="{local-name()}">
      <xsl:value-of select="."/>
    </xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Workaround: Added: [Workaround Exists]
Comment 3 Martin Weiler 2011-05-13 08:15:00 EDT
As the outlined workaround of using an XSLT action comes with a performance impact, here's an approach that should work better (by courtesy of TomF):

Override the DomModelCreator to not produce namespaced DOM fragments, which has an inner class called DOMCreator. In there is where you'd make your changes

Element domElement = element.toDOMElement(document); 

I think it would be a case of replacing that line of code with something that constructs the Element without namespace info attached - and that would be it I think.
Comment 4 Anne-Louise Tangring 2011-07-11 16:06:28 EDT
Candidate, not commited. Can we deal with it in Smooks? Or if it requires an update to freemarker, then we need to punt. Tom C to investigate.
Comment 5 tcunning 2011-07-11 16:11:46 EDT
From Tom F via email : "3061 already has my feedback on it i.e. there should be a fix if we want, but it would require writing of a new class in the ESB, or fixing the relevant class in Smooks." 

Given that, I think we can take it in 5.2.
Comment 6 tcunning 2011-09-12 11:26:05 EDT
Link: Added: This issue relates to JBESB-3680
Comment 7 Tom Fennelly 2011-09-12 14:58:06 EDT
I'm trying to get more information on this from the FreeMarker community.  I wrote a test and sent it to them.  Hopefully there's a code solution I can put into Smooks, or instructions on how to write the FreeMarker template work with the namespaces.
Comment 8 Tom Fennelly 2011-09-13 05:23:31 EDT
OK... there's actually a solution to this issue, without any changes to JBossESB/Smooks.

When using FreeMarker's nodemodel stuff on namespaced XML, you must define the namespaces in the FreeMarker template ala http://freemarker.org/docs/xgui_imperative_learn.html#autoid_73

So, taking the example attached to this JIRA.  The freemarker template must change from...

{code}
${item.nachname}|${item.eintrittsdatum}|Erstellungszeit hhmmss|U|PersNr|${item.anrede}|Name|${item.vorname}|Geb.Datum|Funktion||Verteilstelle|Eintritt|Austritt|
{code}

To...

{code}
<#ftl ns_prefixes={"acme":"http://acme.com/ns"}>
${item["acme:nachname"]}|${item["acme:eintrittsdatum"]}|Erstellungszeit hhmmss|U|PersNr|${item["acme:anrede"]}|Name|${item["acme:vorname"]}|Geb.Datum|Funktion||Verteilstelle|Eintritt|Austritt|{code}

Then it works.
Comment 9 Douglas Palmer 2011-09-20 06:46:44 EDT
This isn't actually a bug but the correct syntax needs documenting.
Comment 10 Douglas Palmer 2011-09-20 06:46:44 EDT
Release Notes Text: Added: Not yet documented
Comment 11 David Le Sage 2011-09-26 23:25:50 EDT
Release Notes Docs Status: Added: Documented as Resolved Issue
Writer: Added: dlesage
Release Notes Text: Removed: Not yet documented Added: https://issues.jboss.org/browse/SOA-3061

If the input file for a Freemarker transformation contained a name-space declaration, users would encounter an freemarker.core.NonStringException.  A fix has been applied so that these name-spaces are now stripped out, meaning users will no longer see the error.
Comment 12 Martin Vecera 2011-11-04 08:49:27 EDT
Verified in ER6.
Comment 13 Martin Weiler 2012-02-22 11:27:39 EST
Reopening this bug because the suggested syntax from comment #8 does not work. In addition, the Release Notes text is incorrect, as no fix has been applied.

Note You need to log in before you can comment on or make changes to this bug.