Reputation: 3567
Following on from my recent question regarding parsing XML files in Java I have decided to use the commons-digester library. I am now familiar with this process and now want to create a Java class representing the XML file, so that when a user instantiates a new object of that class, all of the data from the XML file will be available.
To illustrate this I have an XML file, called MyConfig.xml, with the following structure:
<MyConfig>
<ServerName>nile</ServerName>
<ServerPort>8079</ServerPort>
</MyConfig>
I also have a Java class, called MyConfig.java, that represents this XML file. It has a constructor which takes in the location of the XML file and will then parse and output the contents of the XML file. The class is of the following structure:
package com.digestersample;
import java.io.File;
import java.io.IOException;
import org.apache.commons.digester.Digester;
import org.xml.sax.SAXException;
public class MyConfig {
private String serverName;
private String serverPort;
public MyConfig(String configFile) throws IOException, SAXException
{
Digester digester = new Digester();
digester.setValidating(false);
digester.addObjectCreate("MyConfig", MyConfig.class);
digester.addCallMethod("MyConfig/ServerName", "setServerName", 0);
digester.addCallMethod("MyConfig/ServerPort", "setServerPort", 0);
System.out.println("Creating MyConfig...");
MyConfig mc = (MyConfig) digester.parse(new File(configFile));
System.out.println("Done.");
System.out.println("Port: " + mc.getServerName());
System.out.println("Port: " + mc.getServerPort());
}
public String getServerName() {
return serverName;
}
public void setServerName(String serverName) {
this.serverName = serverName;
}
public String getServerPort() {
return serverPort;
}
public void setServerPort(String serverPort) {
this.serverPort = serverPort;
}
}
My question is, how do I change this class so that whenever some other component instantiates a new object of the class, the contents of the XML file will be available in the instance. For example:
package com.digestersample;
import java.io.IOException;
import org.xml.sax.SAXException;
public class MyOtherClass {
public static void main(String[] args) {
MyConfig mc;
try {
mc = new MyConfig("/home/user/MyConfig.xml");
System.out.println( mc.getServerName() );
System.out.println( mc.getServerPort() );
} catch (IOException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
}
}
At the moment, the above instantiation causes a java.lang.InstantiationException.
Thanks.
Upvotes: 0
Views: 2122
Reputation: 7189
I realise this is not a direct answer to your question, but that is a hell of a lot of code for such a simple config, and your encountering problemns. As mentioned in your original post Simple XML http://simple.sourceforge.net does the job much better in my opinion.
@Root
public class MyConfig {
@Element
private String serverName;
@Element
private int serverPort
public MyConfig() {
super();
}
public MyConfig(File file) {
Style style = new CamelCaseStyle();
Persister persister = new Persister(style);
persister.read(this, file);
}
public String getServerName() {
return name;
}
public int getServerPort() {
return port;
}
}
And create it with.
MyConfig mc = new MyConfig("/home/user/MyConfig.xml");
System.out.println("Name: " + mc.getServerName());
System.out.println("Port: " + mc.getServerPort());
Done! and you will see no exceptions. Also, for your digester exception, you are missing the public no argument constructor similar to what I have added to the MyConfig example.
Upvotes: 1
Reputation: 108949
It has been a while since I looked at the commons digester, but I expect the InstantiationException is because the digester expects the MyConfig class to be a JavaBean. One of the defining characteristics of a JavaBean is that it has a public, zero-arg constructor.
You might think about using some other class to create your MyConfig instance:
public class MyConfigFactory
public MyConfig createMyConfig(String configFile) throws IOException, SAXException
{
Digester digester = new Digester();
digester.setValidating(false);
digester.addObjectCreate("MyConfig", MyConfig.class);
digester.addCallMethod("MyConfig/ServerName", "setServerName", 0);
digester.addCallMethod("MyConfig/ServerPort", "setServerPort", 0);
MyConfig mc = (MyConfig) digester.parse(new File(configFile));
return mc;
}
}
Upvotes: 0