I am new to Java and I came across a statement in a Java project which says:
Digester digester = DigesterLoader.createDigester(getClass()
.getClassLoader().getResource("rules.xml"));
rules.xml file contains various patterns and every pattern has different attributes like classname, methodname and some another properties.
i googled about digester but couldn't found anything useful that could help me with the statement above. can anyone just tell me what are the steps followed in executing above statement ? In fact what is the advantage of this XML stuff ?
swapnil, as a user of Digester back in my Struts days I can honestly say it's tricky to learn/debug. It's a tough library to familiarize yourself with, essentially you are setting up event handlers for certain elements kinda like a SAX parser (in fact it's using SAX in behind the scenes). So you feed a rules engine some XPath for nodes you are interested in and setup rules which will instantiate, and set properties on some POJOs with data it finds in the XML file.
Great idea, and once you get used to it it's good, however if you have an xsd for your input xml file I'd sooner recommend you use JAXB.
The one thing that is nice about Digester is it will only do things with elements you are interested in, so memory footprint ends up being nice and low.
This is the method that's getting called here. Xml is used commonly in Java for configurations, since xml files do not need to be compiled. Having the same configuration in a java file would mean you have to compile the file.
I assume you understand how the rules file is being loaded using the class loader? It's basically looking in the same package as the class itself and creating a URL that gives the file's absolute location.
As for the Digester, I've not used it but a quick read of this (http://commons.apache.org/digester/) should explain all.
They used it at my last gig and all I remember is that it was extremely slow.
Related
Is there any way (not from classes/JAXB) to create XSD schemas in Java? I can parse it with the help of some libraries ie XSOM, Jdom etc. But could not find anything to create.
I don't know about any easy to use way.
I considered using dom4j (because I use it for other purposes, but any other generic xml manipulation library is equivalent) and manualy create it (1).
But then I realized I can use JAXB to generate object model of xml schema, populate it with what i wanted (turned out to be much less comfortable than I hoped for) and marshall it(2). Its via JAXB, but without creating classes for your schema, so maybe it can be usefull to you.
via 2 is hard (but not impossible) to create invalid schema, but its sometimes hard to find out how to create schema I wanted. So I ended creating it in editor, then unmarshalling it and exploring its object representation. In the end, creating it via 1) and then validating it (which I had to do anyway) would be less chore.
Take a look at apache xerces
http://xerces.apache.org/xerces2-j/xml-schema.html
still there's no out of the box solution to handle xsd files
You could use the Eclipse XSD project, part of the Eclipse Model Development Tools. It provides a data model and API for programatically creating schemas.
To create XSD is to use java classes/coding (is inevitable):
Just use Java DOM and create a document then the main node and create other nodes to attach to it and voila!
I am writing an application which needs to add nodes to an existing XML file repeatedly, throughout the day. Here is a sample of the list of nodes that I am trying to append:
<gx:Track>
<when>2012-01-21T14:37:18Z</when>
<gx:coord>-0.12345 52.12345 274.700</gx:coord>
<when>2012-01-21T14:38:18Z</when>
<gx:coord>-0.12346 52.12346 274.700</gx:coord>
<when>2012-01-21T14:39:18Z</when>
<gx:coord>-0.12347 52.12347 274.700</gx:coord>
....
This can happen up to several times a second over a long time and I would like to know what the best or most efficient way of doing this is.
Here is what I am doing right now: Use a DocumentBuilderFactory to parse the XML file, look for the container node, append the child nodes and then use the TransformerFactory to write it back to the SD card. However, I have noticed that as the file grows larger, this is taking more and more time.
I have tried to think of a better way and this is the only thing I can think of: Use RandomAccessFile to load the file and use .seek() to a specific position in the file. I would calculate the position based on the file length and subtract what I 'know' is the length of the file after what I'm appending.
I'm pretty sure this method will work but it feels a bit blind as opposed to the ease of using a DocumentBuilderFactory.
Is there a better way of doing this?
You should try using JAXB. It's a Java XML Binding library that comes in most of the Java 1.6 JDKs. JAXB lets you specify an XML Schema Definition file (and has some experimental support for DTD). The library will then compile Java classes for you to use in your code that translate back into an XML Document.
It's very quick and useful with optional support for validation. This would be a good starting point. This would be another good one to look at. Eclipse also has some great tools for generating the Java classes for you, and providing a nice GUI tool for XSD creation. The Eclipse plugins are called Davi I believe.
I am looking for a easy to implement xml to java binding. The problem I am facing that there is more than one xml file, and I need to create one object tree from these files.
JAXB is not helping for two reason : the xmls are not usually have any schema, and second JAXB does not offer any solution for combining them.
I tried smooks too, but it also doesn't offer any multiple XML digestion system.
Does anybody have any idea?
You can do this in JAXB using an initialized XmlAdapter. Below is a link to answer I gave to a similar question:
Using JAXB to cross reference XmlIDs from two XML files
Note:
JAXB implementations (Metro, EclipseLink MOXy, Apache JaxMe) do not require an XML schema:
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/GettingStarted
If you use JAXB, I suggest creating your own XSDs for the XML files your need to use. That'll help you document what you thought the schema was at the time, and help identify any future issues due to change at the source.
Then, create a class or classes that deserialize the individual documents into the JAXB-generated classes and then build the object you want from those objects.
Even if you don't use JAXB, I'd still recommend using this kind of pattern to isolate the transformation from XML to Java and keep the part of your app that knows about XML in one place, away from your business logic.
I've used XMLBeans before. Really easy and flexible to use, should be able to help you a great deal.
I write applications that need alot of options. These options can be handed to the application by a xml file. Theses files are quite big with some levels and a few dependancies not modelable in a schema.
So the file passes the jdom schema check. Now I want to create some config object for the application and set some variables in some classes.
I don't really see any way not hardcoding the names of the elements and attributes and then looping over these elements and creating new objects.
This makes a 20kLoc application have 25 classes only holding configurations for other classes.
Is there some golden hammer rule how to use xml and customize applications. It comes down to putting the information in the file into some lists, hashtables and attributes of objects.
Can that be done easier? Some awesome framework, maybe? Reflection? Beans? Beans is just a hype word for java programming, or am I missing something?
Who controls the schema of the configuration files? If you can change it, you can simplify it enough to limit the number of classes needed.
If they are imposed from the outside, you might get some traction with Apache Commons BeanUtils and Betwixt.
I've used JAXB Marshaller as well as my own marshaller for marshalling pure java bean objects into XML. It has been observed that both of them require almost same time to marshal. The performance is not acceptable and needs to be improved. What are possible ways where we can improve performance of marshaller? Like threading?
Make sure you create the JaxB context instance only once, creating the context takes some time as it uses reflection to parse the object's annotations.
Note that the JAXBContext is thread safe, but the marshallers\unmarshallers aren't, so you still have to create the marshaller for every thread. However I found that creating the marshallers when you already hold a jaxb context is pretty fast.
Seconding the Use of JibX. Like questzen, I found that JibX was 9 times faster than JAXB in my performance tests.
Also, make sure you have woodstox on the classpath when using JibX. I found woodstox's Stax Implementation is roughly 1050% faster than the Java6 implementation of Stax.
Byeond other good suggestions, I suggest there is something wrong with the way you use JAXB -- it is generally reasonably well performing as long as:
You use JAXB version 2 (NEVER ever use obsolete JAXB 1 -- that was horribly slow, useless piece of crap); preferably a recent 2.1.x version from http://jaxb.dev.java.net
Ensure that you use SAX or Stax source/destination; NEVER use DOM unless you absolute must for interoperability: using DOM will make it 3 - 5x slower, without any benefit (it just doubles object model: POJO -> DOM -> XML; DOM part is completely unnecessary)
Ideally use fastest SAX/Stax parser available; Woodstox is faster than Sun's bundled Stax processor (and BEA's ref. impl. is buggy, no faster than Sun's)
If JAXB is still more than 50% slower than manually written variant, I would profile it to see what else is going wrong. It should not work slowly when used properly -- I have measured it, continuously, and found it so fast that hand-writing converters is usually not worth time and effort.
Jibx is a good package too btw, so I have nothing against trying it out. It might still be bit faster than JAXB; just not 5x or 10x, when both are used correctly.
If large XML trees are written, providing a BufferedOutputStream to the
javax.xml.bind.Marshaller.marshal(Object jaxbElement, java.io.OutputStream os) method made a big difference in my case:
The time needed to write a 100MB XML file could be reduced from 130 sec to 7 sec.
In my experience, JIBX http://jibx.sourceforge.net/ was nearly 10X faster then JAXB. Yes, I measured it for a performance spec. We used it to bind java beans with large HL7 xml. That being said, the way to improve performance is not to rely on the schema definition but to write custom bindings.
We have just tracked down a JAXB performance problem related to the default parser configuration used by Xerces. JAXB performance was very slow (30s+) for one data file (<1Mb)
Quoting "How do I change the default parser configuration?" from http://xerces.apache.org/xerces2-j/faq-xni.html
The DOM and SAX parsers decide which parser configuration to use in the following order
The org.apache.xerces.xni.parser.XMLParserConfiguration system property is queried for the class name of the parser configuration.
If a file called xerces.properties exists in the lib subdirectory of the JRE installation and the org.apache.xerces.xni.parser.XMLParserConfiguration property is defined it, then its value will be read from the file.
The org.apache.xerces.xni.parser.XMLParserConfiguration file is requested from the META-INF/services/ directory. This file contains the class name of the parser configuration.
The org.apache.xerces.parsers.XIncludeAwareParserConfiguration is used as the default parser configuration.
Unmarshalling using JAXB results in this algorithm being repeatedly applied. So a huge amount of time can be spent repeatedly scanning the classpath, looking for the configuration file that doesn't exist. The fix is to do option 1, option 2 or option 3 (create the configuration file under META-INF). Anything to prevent the repeated classpath scanning.
Hope this helps someone - it's taken us days to track this down.
We can achieve the performance in Marshalling and unmarshalling by setting the fast booting property at system level. This will give lot of performance improvement.
System.setProperty("com.sun.xml.bind.v2.runtime.JAXBContextImpl.fastBoot","true");