Search code examples
javaapache-commons-digester

"No such accessible method: setFields() on object: java.util.ArrayList" when using Apache Digester


I'm currently trying to consume a list of strings from some XML using Apache Digester, as described in the How do I add literal elements to a List object? section of the FAQ.

I'm hitting the following error:

[DEBUG] Digester - [SetNextRule]{job/editorial/articlegroup/article} Call java.util.ArrayList.setFields([This, This, is, is, a, a, test, test, , , , ])
[ERROR] Digester - End event threw exception <java.lang.NoSuchMethodException: No such accessible method: setFields() on object: java.util.ArrayList>java.lang.NoSuchMethodException: No such accessible method: setFields() on object: java.util.ArrayList

A simplified version of the XML I am using is as follows:

<job>
    <editorial>
        <articlegroup>
            <article>
                <text>
                    <content><![CDATA[This]]></content>
                </text>
                <text>
                    <content><![CDATA[is]]></content>
                </text>
                <text>
                    <content><![CDATA[a]]></content>
                </text>
                <text>
                    <content><![CDATA[test]]></content>
                </text>
            </article>
        </articlegroup>
    </editorial>
</job>

And the source code:

public class PPJob {

    List<String> fields;

    public List<String> getFields() {
        return fields;
    }
    public void setFields(List<String> fields) {
        this.fields = fields;
    }
}


addObjectCreate("job", PPJob.class);
addSetProperties("job");

addObjectCreate("job/editorial/articlegroup/article", ArrayList.class);
addCallMethod("job/editorial/articlegroup/article/text/content", "add", 1);
addCallParam("job/editorial/articlegroup/article/text/content", 0);
addSetNext("job/editorial/articlegroup/article", "setFields");

PPJob result = (PPJob)super.parse([THE XML]);

I'm pretty much a novice at using the Digester, and I'm having a hard time tracking down examples for what I need.

Can anyone see where I'm going wrong?


Solution

  • Well, this question earned me the "Tumbleweed" badge, and I'm struggling to find some way to re-word the problem so it is easier to comprehend. So here's an update on my progress:

    I decided to abandon the Commons Digester in the end, time constraints made it difficult to chase up the issue up further and as a result I haven't logged a bug to the Digester project (if someone else does let me know and I'll share my experience).

    The javax XPath functions proved more straightforward for achieving my requirement, I resolved to this solution:

    XPathFactory factory = XPathFactory.newInstance();
    XPath xPath = factory.newXPath();
    rootQuery = xPath.compile("/job");
    textFieldsQuery = xPath.compile("/job/editorial/articlegroup/article/text|/job/editorial/articlegroup/article/flashtext");
    
    Node rootNode = (Node)rootQuery.evaluate(new InputSource(is), XPathConstants.NODE);
    
    PPJob job = new PPJob();
    Map<String, String> jobTextFields = new HashMap<String, String>(); 
    NodeList fields = (NodeList)query.evaluate(rootNode, XPathConstants.NODESET);
    for (int i = 0; i < fields.getLength(); i++) {
        Node field = fields.item(i);
        String fieldName = field.getAttributes().getNamedItem("name").getNodeValue();
        String fieldContent = field.getNextSibling().getNodeValue();
        jobTextFields.put(fieldName, fieldContent);
    }       
    job.setTextFields(jobTextFields);
    

    If anyone has a suggestion for this problem I'm still interested to hear why I had so much trouble with the Digester.