tags:

views:

21

answers:

1

I use the following Grails code to render a collection of SomeClass-objects as XML:

def someObjects = SomeClass.findAllByFoo(foo)
if (someObjects) {
  render(contentType:"text/xml", text:someObjects as XML)
}

This works as expected most of the time. However, sometimes and depending on the content of someObjects the code fails with the following NullPointerException (please note that someObjects != null):

java.lang.NullPointerException
    at grails.converters.XML.getElementName(XML.java:128)
    at grails.converters.XML.convertAnother(XML.java:163)
    at grails.converters.XML.convertAnother(XML.java:163)
    at grails.converters.XML.convertAnother(XML.java:163)
    at grails.converters.XML.render(XML.java:111)
    at grails.converters.XML.toString(XML.java:281)
    at project.SomethingController$_closure8.doCall(project.SomethingController:217)
    at project.SomethingController$_closure8.doCall(project.SomethingController)
    at java.lang.Thread.run(Thread.java:637)

This is the definition of the SomeClass class:

class SomeClass {
  List<A> a = new ArrayList<A>()
  List<B> b = new ArrayList<B>()
  List<C> c = new ArrayList<C>()
  static hasMany = [a : A, b : B, c : C]
}

I've found that the exception can be avoided simply by changing the SomeClass definition to:

class SomeClass {
  def a = new ArrayList<A>()
  def b = new ArrayList<B>()
  def c = new ArrayList<C>()
  static hasMany = [a : A, b : B, c : C]
}

My questions are:

  • What am I doing wrong in my interaction with "render as XML"? Is NPE expected here?
  • Why does the latter SomeClass definition work whereas the former does not?
+1  A: 

it seems that problem in definition because XML converter can't convert null element(whole field or just element of list).

class SomeClass {
  List<A> a = new ArrayList<A>()
  List<B> b = new ArrayList<B>()
  List<C> c = new ArrayList<C>()
  static hasMany = [a : A, b : B, c : C]
}

Really strange definition. static hasMany = [a : A, b : B, c : C] tries to create three fields a, b, c and each field has type java.util.Set. Sot just try this definition:

    class SomeClass {
      static hasMany = 
       [
            a : A, 
            b : B, 
            c : C
       ]
    }

It has to be OK.

Your examle:

class SomeClass {
  def a = new ArrayList<A>()
  def b = new ArrayList<B>()
  def c = new ArrayList<C>()
  static hasMany = [a : A, b : B, c : C]
}

is working because of dynamic typing nature. Here you have no strict type check and variables could be easily reassigned to different type.

Olexandr