Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SimpleXML Constructor Exception - Can not create Inner Class

I'm just beginning to experiment with Android Development with SimpleXML and thought it was going quite well until I hit a snag. The code below produces an exception of

W/System.err(665): org.simpleframework.xml.core.ConstructorException: Can not construct inner class

I've looked through the questions on inner classes and think I understand why you would use them (not that mine was necessarily intentional) but despite moving my code round to try and avoid usage I'm still a little stuck and would appreciate any help.

Source Code:

public class InCaseOfEmergencyMedAlertAllergiesActivity extends Activity {
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);


    Serializer serializer = new Persister();
    InputStream xmlstream = this.getResources().openRawResource(R.raw.sample_data_allergies);
    try {
        medalertdata allergyObject = serializer.read(medalertdata.class, xmlstream);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    setContentView(R.layout.allergies);
}

@Root
public class medalertdata {
    @ElementList
    private List<allergy> allergyList;

    public List getAllergies() {
        return allergyList;
    }
}

@Root
public class allergy{

    @Element
    private String to;

    @Element
    private Boolean medical;

    @Element
    private String notes;

    public allergy(String to, Boolean medical, String notes){
        this.to = to;
        this.medical = medical;
        this.notes = notes;
    }

    public String getTo() {
        return to;
    }

    public Boolean getMedical() {
        return medical;
    }

    public String getNotes() {
        return notes;
    }


}

}

With the XML file referenced structured as:

<?xml version="1.0" encoding="ISO-8859-1"?>
<medalertdata>
<allergy>
    <to>Penicillin</to>
    <medical>true</medical>
    <notes></notes>
</allergy>
<allergy>
    <to>Bee Stings</to>
    <medical>false</medical>
    <notes>Sample</notes>
</allergy>
</medalertdata>

Is the problem with how I have annotated the SimpleXML classes or where I am trying to read them? Thanks!

like image 858
Rory Avatar asked Dec 10 '11 19:12

Rory


People also ask

Can you throw an exception in a constructor?

Exceptions: Exceptions in Constructors. When throwing an exception in a constructor, clean up whatever objects and memory allocations you have made prior to throwing the exception, as explained in Exceptions: Throwing Exceptions from Your Own Functions.

What happens if the arguments passed to the constructor are invalid?

Constructors are mostly used to assign values of variables. If the arguments passed to the constructor are invalid, we can throw exceptions. Let's consider a quick example: In the above example, we're performing argument validation before initializing the object.

How to avoid making Constructors trivial to execute?

So, in order to spare them the instructions, you can simply avoid doing anything more specialized in a constructor. So, to keep constructors trivial to execute, you have to: Only throw ArgumentNullException s and ArgumentException s by checking for null or empty strings. Only make assignments to members.

How do you make a constructor fail-safe?

Spare them the instructions of how to use the constructor. Make the constructor private, and create a static factory method that prepares the arguments and constructs the object or fails. Name the method Parse or TryParse if you need to provide a fail-safe.


2 Answers

Try removing @Root from the allergy class.

Also: do you have this two classes each in it's separate file: allergy.java and medalertdata.java?

like image 180
Peter Knego Avatar answered Sep 28 '22 05:09

Peter Knego


I ran into this too while reading some deeply nested XML data into Java objects (and wanting to keep the object structure simple by defining the classes in the same file).

The solution (that doesn't involve splitting into separate files) was to make the nested classes static. (In other words, convert inner classes into static nested classes.) Kinda obvious in retrospective.

Example;
Nested structure:

// ScoreData
//   Sport
//     Category
//       Tournament

Java:

@Root
public class ScoreData {

    @ElementList(entry = "Sport", inline = true)
    List<Sport> sport;

    static class Sport {
        @ElementList(entry = "Category", inline = true)
        List<Category> category;
    }

    // ...
}

Disclaimer: I realise OP got the problem solved already, but maybe this helps others who run into org.simpleframework.xml.core.ConstructorException: Can not construct inner class and don't want to define the classes in separate files as Peter's answer suggests.

like image 35
Jonik Avatar answered Sep 28 '22 06:09

Jonik