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 <strong>properties</strong> = new Properties(); properties.load(new FileInputStream("<font color='blue'>filename.properties</font>"));
|
// 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( "<font color='blue'>config.xsd</font>")); unmarshaller.setSchema(schema);
MyConfig <strong>properties</strong> = (JAXBElement) unmarshaller .unmarshal(new FileInputStream("<font color='blue'>filename.xml</font>")).getValue();
|
| Reading the configuration values: |
// A String: String text = properties.getProperties("<font color='red'>text</font>");
// Other primitive values: int number = Integer.parseInt(properties.getProperties("<font color='red'>primitive</font>"));
// An object: String name = properties.getProperties("<font color='red'>anobject.name</font>"); int integer = properties.getProperties("<font color='red'>anobject.integer</font>"); 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.