Posted by
felipegaucho on October 29, 2007 at 12:23 PM PDT
My last
blog about using JAXB instead of Properties for loading configuration of
Java applications was a bit verbose - so, I decided to print a summary
in order to facilitate the comprehension about the original proposal. I
will not expose the discussion again, just present the below comparison
sheet:
| java.util.Properties |
JAXB |
| The configuration files: |
text=word
primitive=2
anobj.name=test
anobj.integer=3 |
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<myConfig text="word" primitive="2"
>
<my.obj name="test" integer="3"/>
</myConfig>
|
| The code required for loading the
configuration in the memory: |
// Read properties file.
Properties properties = new Properties();
properties.load(new FileInputStream("filename.properties"));
|
// Unmarshal the properties XML file into a Java Object
JAXBContext jc = JAXBContext.newInstance(
AbstractJaxbFootprintStream.FOOTPRINT_CONTEXT, this.getClass()
.getClassLoader());
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setEventHandler(new FootprintConfigValidationHandler());
unmarshaller.setListener(listener);
SchemaFactory sf = SchemaFactory
.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(getClass().getClassLoader().getResource(
"config.xsd"));
unmarshaller.setSchema(schema);
MyConfig properties = (JAXBElement) unmarshaller
.unmarshal(new FileInputStream("filename.xml")).getValue();
|
| Reading the configuration values: |
// A String:
String text = properties.getProperties("text");
// Other primitive values:
int number = Integer.parseInt(properties.getProperties("primitive"));
// An object:
String name = properties.getProperties("anobject.name");
int integer = properties.getProperties("anobject.integer");
Object yourObj = new YourObj(name, integer); |
// A String:
String text = properties.getText();
// Other primitive values:
int number = properties.getPrimitive();
// An object:
Object yourObj = properties.getMyObject(); |
| My arguments for adopting JAXB instead of
java.util.Properties: |
- The red text are hard-codes
occurrences. Even if you create constants, you continue with the
issue to remembers its names, and if you commit a typo or other minor
mistake, nor the IDE neither the compiler will help you to avoid
problems under production.
- Other issue is about creating complex types: you are
responsible for converting the key/values pairs in Java Objects in
case of complex types. You need to check if the attributes required
for creating the object are present and also its types and/or if the
value associated to the key is not null.
- Property files cannot be checked against its syntax or
contents, since it is just a plain text file.
- Complex types should be simulated by a set of key/value
pairs and later converted in a non-bullet-proof code.
- If the application requires different set of properties, it
should rely on several different files. These files are independent
and you must create a custom code to manage it in your application.
|
- No hard-codes, you don't need to check which string map to a
certain object.
- No types conversion by code - the methods you use to
retrieve the values from the Configuration Object are defined with
the correct type.
- There is no risk of deploying typos or minor mistakes since
the compiler and the IDE will notify your mstakes on the fly.
- XML Property files can be verified against its Schema
definition.
- Support for complex types.
- Different set of properties can be modeled in a unique file,
using nested elements. Even if you need to use different XML
properties files, you can import files in a master definition,
creating a formal relationship between them.
|
* The title of this blog is an intentional
reference to this 4
years old article.