Bug 780623 (SOA-3061)

Summary: Freemarker error when input files contains namespace declaration
Product: [JBoss] JBoss Enterprise SOA Platform 5 Reporter: Martin Weiler <mweiler>
Component: JBossESBAssignee: Tom Fennelly <tom.fennelly>
Status: ASSIGNED --- QA Contact:
Severity: high Docs Contact:
Priority: high    
Version: 5.1.0 GACC: tcunning, tom.fennelly
Target Milestone: ---Keywords: Reopened
Target Release: 5.2.0 GA, 5.2.0.ER4   
Hardware: Unspecified   
OS: Unspecified   
URL: http://jira.jboss.org/jira/browse/SOA-3061
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2011-11-04 12:49:27 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
quickstart_freemarker_namespace_failure.zip none

Description Martin Weiler 2011-05-06 14:28:54 UTC
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 14:29:14 UTC
Attachment: Added: quickstart_freemarker_namespace_failure.zip


Comment 2 Martin Weiler 2011-05-13 08:44:19 UTC
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 12:15:00 UTC
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 20:06:28 UTC
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 20:11:46 UTC
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 15:26:05 UTC
Link: Added: This issue relates to JBESB-3680


Comment 7 Tom Fennelly 2011-09-12 18:58:06 UTC
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 09:23:31 UTC
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 10:46:44 UTC
This isn't actually a bug but the correct syntax needs documenting.

Comment 10 Douglas Palmer 2011-09-20 10:46:44 UTC
Release Notes Text: Added: Not yet documented


Comment 11 David Le Sage 2011-09-27 03:25:50 UTC
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 12:49:27 UTC
Verified in ER6.

Comment 13 Martin Weiler 2012-02-22 16:27:39 UTC
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.