SimpleXML Constructor Exception - Can not create Inner Class - java

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!

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.

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?

Related

Setting an instance variable using dependency

I am working on a project where I am trying to represent a Stock Portfolio. There is a class called Position. Also, there is another class called Portfolio and it's basically represents a set of positions along with additional instance variables/methods.
A single Position is stored in a plain .txt file. In order to read that file, I've created another class: ReaderService. In this class, necessary I/O operations are being performed and in the end, a List<Position> is being returned by the method called readPositions().
Portfolio class depends on ReaderService in order to set its positions field, and I am injecting that dependency via constructor, that is constructor injection.
What I can't be sure about is that it seems like a bad practice to initialize a instance variable of Portfolio class in a setter method by using ReaderService dependency. Does this approach leads to any problems like tight coupling or smt else?
Here is the quick summary
ReaderService:
public class ReaderService {
// necessary fields..
// a method to extract all positions from the each line of .txt file.
public ArrayList<Position> readPositions(){
ArrayList<Position> positions = new ArrayList<>();
...
/* for each line in the file, a new `Position` is being created
and being added to `positions` after necessary file operations performed. */
...
// Initializing a new position and adding it to the list
Position position = new Position(...);
positions.add(position);
return positions;
}
}
Position class:
public class Position {
private String stockCode;
private double balance;
...
// There are more than two fields. Truncated it for the sake of the question.
public Position(String stockCode, double balance, ...) {
this.stockCode = stockCode;
this.balance = balance;
...
}
}
And the class in question; Portfolio class:
public class Portfolio {
private ArrayList<Position> positions;
...
private final DataService dataService;
private final ReaderService readerService;
public Portfolio(DataService dataService, ReaderService readerService){
this.dataService = dataService;
this.readerService = readerService;
}
public ArrayList<Position> getPositions() {
return positions;
}
// Check out this method. Is it a poor design?
public void setPositions() {
try {
this.positions = readerService.readPositions();
}
catch (IOException ex){
ex.printStackTrace();
}
}
}
Is it correct thing to question the following:
"A ReaderService is responsible to read the positions, but you are giving it the responsibility of creating list of positions for Portfolio class as well.'
I mean do I break the Single Responsibility principle here?
I am also considering to make these service classes static.
For the sake of readability, I answer here.
Rather than setPositions(), I would like to create with constructor. And create another class (or you can put it in main class as you said, but you may don't like it) as below.
public class PortfolioService {
private final DataService dataService;
private final ReaderService readerService;
public PortfolioService(DataService dataService, ReaderService readerService) {
this.dataService = dataService;
this.readerService = readerService;
}
public PortfolioService createPortfolio() {
return new Portfolio(readerService.readPositions());
}
}
then, Portfolio class will look like this.
public class Portfolio {
private final List<Position> positions;
public Portfolio(List<Position> positions) {
this.positions = positions;
}
// and do something else with positions
}

Get all static variables of a class without reflection

We have an exception Class A with a few fault codes defined as public static final and it is referenced in many files (more than 100) in our source code.
We want all these fault codes in Class B for some processing.
Currently we have implemented a method called getFaultCodes() in Class A to build a list of fault codes and return the same. The problem with this approach is that whenever an fault code is introduced, it has to be added in getFaultCode method as well. This is error prone, as a user may forget to add the new code to the method.
Moving these fault codes under an enum requires changes in many files all over the source code, so we don't want do this.
class ExceptionA {
public static final String faultCode1 = "CODE1";
public static final String faultCode2 = "CODE1";
public static final String faultCode3 = "CODE1";
List<String> getFaultCodes(){
list.add(faultCode1);
......
return list;
}
}
We are thinking about using reflection, but I'm posting in this forum just to check if there is a better solution. Please provide your suggestion to solve this problem.
Maybe you can go through an interface:
public interface FaultCodeProvider
{
String getFaultCode();
}
Then have your enums implement it:
public enum DefaultFaultCodes
implements FaultCodeProvider
{
FAULT1("text for fault 1"),
// etc
;
private final String value;
DefaultFaultCodes(final String value)
{
this.value = value;
}
#Override
public String getFaultCode()
{
return value;
}
}
Collecting them from the enum is then as easy as cycling through the enum's values().
I have modified code code like below:
class ExceptionA {
public enum codes {
CODE1("CODE1"),
CODE2("CODE2"),
CODE3("CODE3"),
private String code;
codes(String code){
this.code = code;
}
public String getCode() {
return this.code;
}
}
public static final String faultCode1 = code.CODE1;
public static final String faultCode2 = code.CODE2;
public static final String faultCode3 = code.CODE3;
}
So that I need not to change the variables occurrences "faultCode" in the source code, I can access the list of fault codes from other class.

Jaxb, Class has two properties of the same name

With Jaxb (jaxb-impl-2.1.12), UI try to read an XML file
Only a few element in the XML file are interesting, so I would like to skip most of the elements.
The XML I'm trying to read:
<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML file generated by XMLSpy v2010 rel. 3 sp1 (http://www.altova.com)-->
<flx:ModeleREP xsi:schemaLocation="urn:test:mod_rep.xsd mod_rep.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:flx="urn:test:mod_rep.xsd">
<flx:DocumentHeader>
<flx:Identification v="04489"/>
</flx:DocumentHeader>
<flx:TimeSeries>
<flx:Identification v="test1a"/>
<flx:BusinessType v="A01"/>
<flx:Product v="123a"/>
<flx:ResourceObject codingScheme="N" v="testa"/>
<flx:Period>
<flx:TimeInterval v="2011-07-02T00:00/2011-07-16T00:00"/>
<flx:Resolution v="PT2H"/>
<flx:Pt>
<flx:P v="1"/>
<flx:Q unitCode="String" v="1.0"/>
<flx:A currencyIdentifier="String" v="195.0"/>
</flx:Pt>
</flx:Period>
</flx:TimeSeries>
<flx:TimeSeries>
<flx:Identification v="test2a"/>
<flx:BusinessType v="A01"/>
<flx:Product v="a123b"/>
<flx:ResourceObject codingScheme="N" v="test2"/>
<flx:Period>
<flx:TimeInterval v="2011-07-02T00:00/2011-07-16T00:00"/>
<flx:Resolution v="PT2H"/>
<flx:Pt>
<flx:P v="1"/>
<flx:Q unitCode="String" v="1.0"/>
<flx:A currencyIdentifier="String" v="195.0"/>
</flx:Pt>
<flx:Pt>
<flx:P v="2"/>
<flx:Q unitCode="String" v="1.0"/>
<flx:A currencyIdentifier="String" v="195.0"/>
</flx:Pt>
</flx:Period>
</flx:TimeSeries>
</flx:ModeleREP>
my class
#XmlRootElement(name="ModeleREP", namespace="urn:test:mod_rep.xsd")
public class ModeleREP {
#XmlElement(name="TimeSeries")
protected List<TimeSeries> timeSeries;
public List<TimeSeries> getTimeSeries() {
if (this.timeSeries == null) {
this.timeSeries = new ArrayList<TimeSeries>();
}
return this.timeSeries;
}
public void setTimeSeries(List<TimeSeries> timeSeries) {
this.timeSeries = timeSeries;
}
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "TimeSeries")
public class TimeSeries {
#XmlElement(name="ResourceObject")
protected RessourceObject resourceObject;
#XmlElement(name = "Period")
protected Period period;
public RessourceObject getResourceObject() {
return this.resourceObject;
}
public void setResourceObject(RessourceObject resourceObject) {
this.resourceObject = resourceObject;
}
public Period getPeriod() {
return this.period;
}
public void setPeriod(Period period) {
this.period = period;
}
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "ResourceObject")
public class RessourceObject {
#XmlAttribute(name = "codingScheme")
protected String codingScheme;
#XmlAttribute(name = "v")
protected String v;
public String getCodingScheme() {
return this.codingScheme;
}
public void setCodingScheme(String codingScheme) {
this.codingScheme = codingScheme;
}
public String getV() {
return this.v;
}
public void setV(String v) {
this.v = v;
}
}
#XmlAccessorType(XmlAccessType.NONE)
#XmlRootElement(name = "Period")
public class Period {
#XmlElement(name = "TimeInterval")
protected TimeInterval timeInterval;
#XmlElement(name = "Pt")
protected List<Pt> pt;
public TimeInterval getTimeInterval() {
return this.timeInterval;
}
public void setTimeInterval(TimeInterval timeInterval) {
this.timeInterval = timeInterval;
}
public List<Pt> getPt() {
if (this.pt == null) {
this.pt = new ArrayList<Pt>();
}
return this.pt;
}
public void setPt(List<Pt> pt) {
this.pt=pt;
}
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "TimeInterval")
public class TimeInterval {
#XmlAttribute(name = "v")
private String timeIntervalPeriod;
public String getTimeIntervalPeriod() {
return this.timeIntervalPeriod;
}
public void setTimeIntervalPeriod(String timeIntervalPeriod) {
this.timeIntervalPeriod = timeIntervalPeriod;
}
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "Pt")
public class Pt {
#XmlElement(name = "P")
protected P p;
#XmlElement(name = "A")
protected A a;
public P getP() {
return this.p;
}
public void setP(P p) {
this.p = p;
}
public A getA() {
return this.a;
}
public void setA(A a) {
this.a = a;
}
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "P")
public class P {
#XmlAttribute(name = "v")
protected String position;
public String getPosition(){
return this.position;
}
public void setPosition(String position){
this.position=position;
}
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "A")
public class A {
#XmlAttribute(name = "v")
protected String calculatedAmount;
public String getCalculatedAmount() {
return this.calculatedAmount;
}
public void setCalculatedAmount(String calculatedAmount) {
this.calculatedAmount = calculatedAmount;
}
}
when I try to read the XML file, I get this error:
com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Class has two properties of the same name "timeSeries"
this problem is related to the following location:
at public java.util.List testjaxp.ModeleREP.getTimeSeries()
at testjaxp.ModeleREP
this problem is related to the following location:
at protected java.util.List testjaxp.ModeleREP.timeSeries
at testjaxp.ModeleREP
I don't understand this error. And sometimes when I check my object, timeSeries is null.
How can I fix this error/prevent timeSeries from returning null?
I set these properties when I faced this problem. Setting one or both of them may solve your issue:
#XmlRootElement(name="yourRootElementName")
#XmlAccessorType(XmlAccessType.FIELD)
There are multiple solutions: If you annotate on variable declaration then you need #XmlAccessorType(XmlAccessType.FIELD), but if you prefer to annotate either a get- or set-method then you don't.
So you can do:
#XmlRootElement(name="MY_CLASS_A")
#XmlAccessorType(XmlAccessType.FIELD)
public class MyClassA
{
#XmlElement(name = "STATUS")
private int status;
//.. and so on
}
Or:
#XmlRootElement(name="MY_CLASS_A")
public class MyClassA
{
private int status;
#XmlElement(name = "STATUS")
public int getStatus()
{
}
}
You didn't specified what JAXB-IMPL version are you using, but once I had the same problem (with jaxb-impl 2.0.5) and solved it using the annotation at the getter level instead of using it at the member level.
I've also seen some similiar issues like this.
I think, it's because of the place where we use the "#XMLElement" annotation in the (bean) class.
And I think, the JAXB (annotation processor) considers the member field & getter method of the same field element as different properties, when we use the #XMLElement annotation at the field level and throws the IllegalAnnotationExceptions exception.
Exception Message :
Class has two properties of the same name "timeSeries"
At Getter Method :
at public java.util.List testjaxp.ModeleREP.getTimeSeries()
At Member Field :
at protected java.util.List testjaxp.ModeleREP.timeSeries
Solution :
Instead of using #XmlElement in the field, use it in the getter method.
just added this to my class
#XmlAccessorType(XmlAccessType.FIELD)
worked like a cham
Your JAXB is looking at both the getTimeSeries() method and the member timeSeries. You don't say which JAXB implementation you're using, or its configuration, but the exception is fairly clear.
at public java.util.List testjaxp.ModeleREP.getTimeSeries()
and
at protected java.util.List testjaxp.ModeleREP.timeSeries
You need to configure you JAXB stuff to use annotations (as per your #XmlElement(name="TimeSeries")) and ignore public methods.
If we use the below annotations and remove the "#XmlElement" annotation, code should work properly and resultant XML would have the element names similar to the class member.
#XmlRootElement(name="<RootElementName>")
#XmlAccessorType(XmlAccessType.FIELD)
In case use of "#XmlElement" is really required, please define it as field level and code should work perfectly. Don't define the annotation on the top of getter method.
Had tried both the above approaches mentioned and got to fix the issue.
You need to configure class ModeleREP as well with #XmlAccessorType(XmlAccessType.FIELD) as you did with class TimeSeries.
Have al look at OOXS
"Class has two properties of the same name exception" can happen when you have a class member x with a public access level and a getter/setter for the same member.
As a java rule of thumb, it is not recommended to use a public access level together with getters and setters.
Check this for more details:
Public property VS Private property with getter?
To fix that:
Change your member's access level to private and keep your getter/setter
Remove the member's getter and setter
These are the two properties JAXB is looking at.
public java.util.List testjaxp.ModeleREP.getTimeSeries()
and
protected java.util.List testjaxp.ModeleREP.timeSeries
This can be avoided by using JAXB annotation at get method just like mentioned below.
#XmlElement(name="TimeSeries"))
public java.util.List testjaxp.ModeleREP.getTimeSeries()
Declare the member variables to private in the class you want to convert to XML.
It will work when you put your annotation before the getters, and remove it from the protected attributes:
protected String codingScheme;
#XmlAttribute(name = "codingScheme")
public String getCodingScheme() {
return this.codingScheme;
}
The source of the problem is that you have both XmlAccessType.FIELD and pairs of getters and setters. The solution is to remove setters and add a default constructor and a constructor that takes all fields.
ModeleREP#getTimeSeries() have to be with #Transient annotation. That would help.
I had a service class with a signature as below:
#WebMethod
public FetchIQAStatusResponseVO fetchIQAStatus(FetchIQAStatusRequest fetchIQAStatusRequest) {
On run I got the same error for FetchIQAStatusResponseVO fields. I just added a line on top of FetchIQAStatusResponseVO:
#XmlAccessorType(XmlAccessType.FIELD) //This line added
public class FetchIQAStatusResponseVO {
and this resolved the issue.
Annotating with #XmlTransient resolves that issue
#XmlTransient
public void setTimeSeries(List<TimeSeries> timeSeries) {
this.timeSeries = timeSeries;
}
Look at http://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/XmlTransient.html for more details
Many solutions have been given, and the internals are briefly touched by #Sriram and #ptomli as well. I just want to add a few references to the source code to help understand what is happening under the hood.
By default (i.e. no extra annotations used at all except #XmlRootElement on the root class), JABX tries to marshal things exposed via two ways:
public fields
getter methods that are named following the convention and have a corresponding setter method.
Notice that if a field is (or method returns) null, it will not be written into the output.
Now if #XmlElement is used, non-public things (could be fields or getter methods) can be marshalled as well.
But the two ways, i.e. fields and getter-methods, must not conflict with each other. Otherwise you get the exception.
A quick and simple way to fix this issue is to remove the #XmlElement(name="TimeSeries") from the top of the variable declaration statement protected List<TimeSeries> timeSeries; to the top of its getter, public List<TimeSeries> getTimeSeries().
Thus your ModeleREP class will look like:
#XmlRootElement(name="ModeleREP", namespace="urn:test:mod_rep.xsd")
public class ModeleREP {
protected List<TimeSeries> timeSeries;
#XmlElement(name="TimeSeries")
public List<TimeSeries> getTimeSeries() {
if (this.timeSeries == null) {
this.timeSeries = new ArrayList<TimeSeries>();
}
return this.timeSeries;
}
public void setTimeSeries(List<TimeSeries> timeSeries) {
this.timeSeries = timeSeries;
}
}
I did trial and error and got the conclusion that, you only have to use either of both #XMLElement or #XmlAccessorType(XmlAccessType.FIELD).
When to use which?
case 1 : If your field names and element name you want to use in xml file are different then you have to use #XMLElement(name="elementName"). As this will bind fields with that element name and display in XML file.
case 2 : If fields names and respective element name in xml both are same then you can simply use #XmlAccessorType(XmlAccessType.FIELD)

Java SOJO CSV Serialization

I am trying to use SOJO to serialize a Java object to CSV. The example looks pretty straight forward:
Car car = new Car("My Car");
car.setDescription("This is my car.");
Serializer csvSerializer = new CsvSerializer();
String csvStr = (String) csvSerializer.serialize(car);
System.out.println(csvStr);
// print:
// description,build,properties,name,~unique-id~,class
// This is my car.,,,My Car,0,test.net.sf.sojo.model.Car
I tried implementing my own version of the example. I made a really simple Car class with two String fields (build and description) which implements a setDescription(..) method.
This is what I implemented:
import net.sf.sojo.interchange.csv.CsvSerializer;
public class Main {
private class Car
{
private String build;
private String description;
public Car(String build) {
this.build = build;
this.description = null;
}
public void setDescription(String description) {
this.description = description;
}
}
public static void main(String[] args) {
Main m = new Main();
Car car = m.new Car("My Car");
car.setDescription("This is my car.");
CsvSerializer csvSerializer = new CsvSerializer();
String csvStr = (String) csvSerializer.serialize(car);
System.out.println(csvStr);
}
}
However, when I run my implementation I get the following output:
~unique-id~,class,description
0,Main$Car,
I don't understand why in my implementation neither the build or description fields are serialized, can you help?
Cheers,
Pete
From the SOJO home page: "The intention for this project is a Java framework, that convert JavaBeans in a simplified representation"
The Car object in your example does not qualify. You must have a getter (and, probabaly, a setter as well) for every property that you wish SOJO to write to (or read from) your file. Add getBuild() and getDescription()
I haven't used SOJO, but for private fields you probably need getter methods; or you could try declaring the fields public.

Map from object to a dynamic string

Right now I have about 60 Message types which are passed to a getStuff(Message) method of a class which implements ContainerOfThings. There are multiple variations of an ContainerOfThings such as BoxOfStuff and BagOfTricks both of which realize the getStuff(Message) method which generates a string based on member variables. The result may also have pre-pended or post-pended data such as labels or concatenated data. See code below.
public class BoxOfStuff implements ContainerOfThings
{
private String var1;
private String var2;
private String varN;
public String getStuff(Message message)
{
if (message.equals(Message.GET_STUFF1))
return var1;
else if (message.equals(Message.GET_STUFF2))
return "Var2 is: " + var2;
else if (message.equals(Message.GET_STUFFN))
return varN + "\n";
// Etc. for each Message.GET_*
}
// getters and setters for each var*
}
public class Message
{
private String id = null;
private Message(String id)
{ this.id = id; }
public final String toString()
{ return this.id; }
public static final Message GET_STUFF1 = new Message("V1");
public static final Message GET_STUFF2 = new Message("V2");
public static final Message GET_STUFFN = new Message("VN");
}
I am trying to find a design that meets the following objectives. (1) The string returned from getStuf() needs to reflect the current state of the implementing class's member fields. (2) Also I would prefer to get away from an incredibly long series of if / else if blocks. One concern is ease of potentially changing to a persistent data-driven configurable object approach which a Map lends well towards. (3) Design should allow for simple maintenance and/or edits.
One design that could work but is a little messy is to create a Map with all key/values initialized in the constructor and also reset any key/value pair inside each setter method. In this way, the response to getStuff(Message) is updated to the new content after changes (ie: in a setVar*() method). Any other thoughts?
I think you'll need two maps. One will be a Map<Message, String> where the value will be a format string (i.e. something that will get passed into String.format()). The second map will be a Map<Message, Field> which should be fairly self explanatory once you take a look at the reflection libs. These will need to be setup at init time but after that the getStuff() method should be fairly clean and your setters won't be affected at all.
BTW, Java doesn't generally prefix interfaces with I.
I'm not 100% sure I understand your problem, but it sounds like you want to memoize the result of your getStuff() call.
One easy way to do this is to use the makeComputingMap() method from the MapMaker class in the Google Guava library.
For example, you could do:
Map<Message, String> map = new MapMaker()
.expireAfterWrite(10, TimeUnit.MINUTES)
.makeComputingMap(
new Function<Message, String>() {
public String apply(Message message) {
// Your getStuff() implementation here
}
});
Does that make sense?
How about this:
public abstract class BaseOfBox implements IContainerOfThings {
protected final Map<Message, String> stuffs =
new HashMap<Message, String>();
public final String getStuff(Message message) {
return stuffs.get(message);
}
}
public class BoxOfStuff extends BaseOfBox {
private String var1;
private String var2;
public BoxOfStuff() {
super();
}
public setVar1(String var1) {
this.var1 = var1;
stuffs.put(Message.GET_STUFF1, var1);
}
public setVar2(String var2) {
this.var2 = var2;
stuffs.put(Message.GET_STUFF2, "Var2 is: " + var2);
}
...
}
Frankly, I think this is a pretty ugly solution, but so are the requirements, IMO. I suspect a more elegant solution can only be found if we review the (real) requirements

Categories