Download (direct link):
<member name=”doverly”/><member name=”gwen” /><member name =”heidi ” />
<member name=”holly”/><member name=”jenny”/><member name=” patrice ”/>
<member name=”sandy b.”/><member name=”sandy c.”/><member
<member name=”shelly” /><member name=”suzanne” />
Here is the current schedule:
<member name=”ben” /><member name=”billy” /><member name= "chuck” />
<member name=”dan” /><member name=”keith” /><member name= ”kevin” />
<member name=”matt d.” /><member name=”matt v.” /><member 2
<member name=”todd” />
<member name=”avery” /><member name=”catherine” 2
/><member name=”dawn” />
<member name=”doverly” /><member name=”gwen” 2
/><member name=”heidi” />
<member name=”holly” /><member name=”jenny” 2
/><member name=”patrice” />
Listing 6.3 Output with JDK 1.3 and DOM implementation (continued)
58 Item 6
<member name= sandy b. . "/><member name= "sandy c. . "/><member 2
<member name= </meeting> </day> </meetings> shelly" /><member name=" suzanne" />
Listing 6.3 (continued)
Listing 6.3 has the expected output, and it ran correctly. As you can see, the "Wednesday" and "Thursday" meetings were switched, but when the final schedule was printed, the original DOM tree was printed out. However, when we upgraded our application to JDK 1.4, we ran into problems. The result of running this in JDK 1.4 is shown in Listing 6.4. As you can see, what ran fine in an earlier version of the JDK now throws an exception. When we call cloneNode() on org.w3c.dom.Document on line 27, we get a "HIERARCHY_REQUEST_ERR:" message! Looking into the documentation on the cloneNode() method, it is inherited from org.w3c.dom.Node, and the documentation says that cloning Document, DocumentType, Entity, and Notation nodes is implementation dependent.
C:\pitfalls\week5>java -classpath . ScheduleSwitcher schedule.xml
If you switched the Wed & Thurs meetings, this is what it would look like:
org.apache.crimson.tree.DomEx: HIERARCHY_REQUEST_ERR: This node isn’t allowed there. at
at ScheduleSwitcher.showSwitchedDays(ScheduleSwitcher.java:27) at ScheduleSwitcher.main(ScheduleSwitcher.java:68) Exception in thread "main"
Listing 6.4 Output with JDK 1.4, with built-in DOM
So what should we do in a situation like this? Since there are many implementations of DOM and SAX APIs, we are bound to run into these problems. Added to this dilemma is the fact that standards and new implementations evolve quickly, and we may want to use newer implementations of these standards before they are integrated
My Assertions Are Not Gratuitous! 59
into the JDK. Luckily, with the release of JDK 1.4, there is the Endorsed Standards Override Mechanism (ESOM), which is used to replace implementations of these standard classes. Following is the complete list of the packages that can be overriden:
org.omg.DynamicAny.DynAnyPackage, org.omg.IOP ,
org.omg.PortableServer.POAPackage, org.omg.PortableServer.portable, org.omg.PortableServer.ServantLocatorPackage, org.omg.SendingContext, org.omg.stub.java.rmi, org.w3c.dom, org.xml.sax, org.xml.sax.ext, org.xml.sax.helpers
As you can see, these include standard classes from the Object Management Group (OMG) as well as the W3C. To take advantage of the ESOM, follow these steps:
1. Create a directory called endorsed in the jre/lib directory.
2. Copy your JAR file implementations of your APIs into that directory.
3. Run your application.
In our simple example, we followed these steps, and the application worked perfectly. It is sometimes difficult to stay away from methods that are implementation-specific—as Document.cloneNode() was in this example. Remembering how to override the standards with the use of the ESOM will make your life a lot easier!
Item 7: My Assertions Are Not Gratuitous!
In Java Pitfalls, we finished the book by discussing the emerging JSR concerning a Java Assertion Facility. At the time, we suggested a mechanism that would allow an assertion-like facility. As of JDK 1.4, the language now includes an assertion facility.