<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/atom10full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
    <title type="html">Core Java Technologies Tech Tips</title>
    <subtitle type="html">Tips for using core Java SE APIs</subtitle>
    <id>http://blogs.sun.com/CoreJavaTechTips/feed/entries/atom</id>
            
        <link rel="alternate" type="text/html" href="http://blogs.sun.com/CoreJavaTechTips/" />
        <updated>2008-10-09T04:41:10-07:00</updated>
    <generator uri="http://roller.apache.org" version="4.0.0.13 (BSC) (20080828032017)">Apache Roller Weblogger</generator>
        <link rel="self" href="http://feeds.feedburner.com/corejavatechtips" type="application/atom+xml" /><entry>
        <id>http://blogs.sun.com/CoreJavaTechTips/entry/exchanging_data_with_xml_and1</id>
        <title type="html">Exchanging Data With XML and JAXB, Part 2</title>
        <author><name>dananourie</name></author>
        <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/corejavatechtips/~3/393370150/exchanging_data_with_xml_and1" />
        <published>2008-09-15T09:57:04-07:00</published>
        <updated>2008-09-15T17:02:24-07:00</updated> 
        <category term="/TechTip" label="TechTip" />
        <category term="binding" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="data" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="java" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="jaxb" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="xml" scheme="http://rollerweblogger.org/ns/tags/" />
        <summary type="html">In this tip, you'll learn how JAXB's binding customization
features can facilitate XML processing for the recipient of data as
well as for the sender.</summary>
        <content type="html">&lt;p&gt;by Jennie Hall&lt;/p&gt; 
  &lt;p&gt;In &lt;a href="/CoreJavaTechTips/entry/exchanging_data_with_xml_and"&gt;Exchanging Data With XML and JAXB, Part 1&lt;/a&gt;, we saw
how the Java Architecture for XML Binding (&lt;a href="https://jaxb.dev.java.net/" target="_blank"&gt;JAXB&lt;/a&gt;) expedites
the exchange of data between systems. With JAXB 2.0's annotation
support, generating XML data for a business partner is as easy as
annotating your existing object model.&amp;nbsp;&lt;/p&gt; 
  &lt;p&gt;In this tip, you'll learn how JAXB's binding customization
features can facilitate XML processing for the recipient of data as
well as for the sender. Binding customization offers a level of
control over the characteristics of the Java classes generated by
the JAXB schema compiler. This allows you to work with an object
model that makes sense for your business domain even when processing
XML instance documents based on a schema that is not of your own
design.&lt;/p&gt; 
  &lt;p&gt;For a brief overview of the Java Architecture for XML Binding
(JAXB), see the &amp;quot;What's JAXB?&amp;quot; section of &lt;a href="/CoreJavaTechTips/entry/exchanging_data_with_xml_and"&gt;Exchanging Data With XML and JAXB, Part
1&lt;/a&gt;.&lt;/p&gt; 
  &lt;h2&gt;The Sample Application&lt;/h2&gt; 
  &lt;p&gt;Let's continue with our scenario from Part 1.A veterinary office, NiceVet, wants to send upcoming
appointment reminders and pet birthday cards to its clients. NiceVet
contracts with a service provider, WePrintStuff, to do the printing
and mailing.&lt;b&gt; &lt;/b&gt;In
Part 1, we assembled some data for WePrintStuff by annotating
NiceVet's existing object model and then using JAXB to marshal
application data from Java objects to an XML instance document. We
also used JAXB's schema generator to produce a corresponding schema
from the annotated Java classes.&lt;/p&gt; 
  &lt;p&gt;On the receiving end, WePrintStuff will run the JAXB schema
compiler against the source schema to generate the schema-derived
classes. JAXB will create instances of these classes as it
unmarshals NiceVet's data from the XML instance document and binds
it into a Java content tree. In some cases, however, the default
manner in which JAXB generates the schema-derived classes and binds
the data is not exactly what is needed. JAXB's binding customization
features provide us with some nice ways to handle many of these
cases. We'll take a look at some of them in the next section.&lt;/p&gt; 
  &lt;h2&gt;Customizing the Source Schema&lt;/h2&gt; 
  &lt;p&gt;We can make some customizations right away to make life easier at
WePrintStuff. For example, we would like to work
with meaningful package and class names and avoid any naming
collisions. To accomplish this, we can add custom binding
declarations to the source schema itself -- this is known as inline
customization.
&lt;/p&gt; 
  &lt;p&gt;Here are the first few lines of the annotated schema:&lt;/p&gt; 
  &lt;pre&gt;	&amp;lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&amp;gt;
	&amp;lt;xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
				 &amp;lt;!-- JAXB namespace declaration required for inline customization --&amp;gt;
	                         xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
	                         xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
	                         jxb:extensionBindingPrefixes="xjc"
				 &amp;lt;!-- JAXB version number required for inline customization --&amp;gt;
	                         jxb:version="2.0"&amp;gt;
	    &amp;lt;xs:annotation&amp;gt;
	        &amp;lt;xs:appinfo&amp;gt;
                    &amp;lt;!-- All collections in this schema will use implementation class java.util.ArrayList. --&amp;gt;
	            &amp;lt;jxb:globalBindings collectionType="java.util.ArrayList"/&amp;gt;
	            &amp;lt;jxb:schemaBindings&amp;gt;
                        &amp;lt;!-- Specify the package for the generated classes; avoid naming collisions. --&amp;gt;
	                &amp;lt;jxb:package name="weprintstuff.generated"&amp;gt;
                            &amp;lt;!-- Specify some Javadoc that describes our package and its uses. --&amp;gt;
	                    &amp;lt;jxb:javadoc&amp;gt;&amp;lt;![CDATA[&amp;lt;body&amp;gt; The package weprintstuff.generated contains the
                                 schema-derived classes that make up the object model used to process
                                 print client orders.&amp;lt;/body&amp;gt;]]&amp;gt;
	                    &amp;lt;/jxb:javadoc&amp;gt;
	                &amp;lt;/jxb:package&amp;gt;
	            &amp;lt;/jxb:schemaBindings&amp;gt;
	        &amp;lt;/xs:appinfo&amp;gt;
	    &amp;lt;/xs:annotation&amp;gt;
&lt;/pre&gt; 
  &lt;p&gt;To enable inline customization, we must include a JAXB namespace
declaration and the JAXB version number. The JAXB namespace prefix
we'll use in our sample application is &lt;code&gt;jxb:&lt;/code&gt;. We can
override the default JAXB bindings at different scopes. Lower-level,
more fine-grained scopes inherit declarations made at higher-level
scopes, but binding declarations made at lower-level scopes can
override these inherited declarations. The scopes in order from
highest to lowest level are global, schema, definition, and component.

&lt;/p&gt; 
  &lt;p&gt;In the preceding example, we've made a declaration at global
scope that specifies that all collections in this schema will use
the implementation class &lt;code&gt;java.util.ArrayList&lt;/code&gt;. If our
source schema imported another schema, this declaration would apply
to the second schema as well. There can be only one
&lt;code&gt;&amp;lt;globalBindings&amp;gt;&lt;/code&gt; declaration per schema. This
declaration is valid in the top-level schema only.&lt;/p&gt; 
  &lt;p&gt;At schema scope, we've specified the package into which the JAXB
schema compiler will generate the schema-derived classes. We've also
included some package-level Javadoc that describes our package and
its uses. Note that we've wrapped our custom binding declarations in
&lt;code&gt;&amp;lt;annotation&amp;gt;&amp;lt;appinfo&amp;gt;&lt;/code&gt; tags.&lt;/p&gt; 
  &lt;p&gt;Now that we have the package we want, let's see if we can get
some class names that better reflect Java naming conventions and
WePrintStuff's business domain. The default bindings for the
original schema would generate classes with names like
&lt;code&gt;ClassAType&lt;/code&gt;, &lt;code&gt;ClassBType&lt;/code&gt;, and so
on.This is not how we typically name classes in the
Java programming language, so let's fix it:&lt;/p&gt; 
  &lt;pre&gt;    &amp;lt;xs:element name="printOrder" type="PrintOrderType"/&amp;gt;
    &amp;lt;xs:complexType name="PrintOrderType"&amp;gt;
        &amp;lt;xs:annotation&amp;gt;
            &amp;lt;xs:appinfo&amp;gt;
                &amp;lt;!-- Name the generated class PrintOrder rather than PrintOrderType. --&amp;gt;
                &amp;lt;jxb:class name="PrintOrder"&amp;gt;
                    &amp;lt;!-- Provide some Javadoc for PrintOrder. --&amp;gt;
                    &amp;lt;jxb:javadoc&amp;gt;&amp;lt;![CDATA[&amp;lt;code&amp;gt;PrintOrder&amp;lt;/code&amp;gt; javadoc goes here]]&amp;gt;
                    &amp;lt;/jxb:javadoc&amp;gt;
                &amp;lt;/jxb:class&amp;gt;
            &amp;lt;/xs:appinfo&amp;gt;
        &amp;lt;/xs:annotation&amp;gt;
        &amp;lt;xs:sequence&amp;gt;
            &amp;lt;xs:element name="notifications" type="notificationsType" minOccurs="0"&amp;gt;
                &amp;lt;xs:annotation&amp;gt;
                    &amp;lt;xs:appinfo&amp;gt;
                        &amp;lt;!-- PrintOrder's notifications property becomes printItems. --&amp;gt;
                        &amp;lt;jxb:property name="printItems"/&amp;gt;
                    &amp;lt;/xs:appinfo&amp;gt;
                &amp;lt;/xs:annotation&amp;gt;
            &amp;lt;/xs:element&amp;gt;
        &amp;lt;/xs:sequence&amp;gt;
		...
    &amp;lt;/xs:complexType&amp;gt;
    &amp;lt;xs:complexType name="notificationsType"&amp;gt;
        &amp;lt;xs:annotation&amp;gt;
            &amp;lt;xs:appinfo&amp;gt;
                &amp;lt;!-- Name the generated class PrintItems rather than NotificationsType. --&amp;gt;
                &amp;lt;jxb:class name="printItems" /&amp;gt;
            &amp;lt;/xs:appinfo&amp;gt;
        &amp;lt;/xs:annotation&amp;gt;
			...
    &amp;lt;/xs:complexType&amp;gt;
		&lt;b&gt;&lt;/b&gt;
&lt;/pre&gt; 
  &lt;p&gt;&lt;code&gt;PrintOrderType&lt;/code&gt; becomes &lt;code&gt;PrintOrder&lt;/code&gt;,
&lt;code&gt;NotificationsType&lt;/code&gt; becomes &lt;code&gt;PrintItems&lt;/code&gt;, and
so on. Dealing with class names is straightforward, but
unfortunately we're stuck with a class structure that is less than
ideal. There are too many wrappers around the data, which results in
a long chain of method calls. Here's what the calls would have looked
like with classes derived from the original schema. As you can see,
methods with singular method names return collections, which is misleading.&lt;/p&gt; 
  &lt;pre&gt;	List&amp;lt;AppointmentType&amp;gt; appointments = printOrder.getNotifications().getAppointments().getAppointment();
	List&amp;lt;BirthdayType&amp;gt; birthdays = printOrder.getNotifications().getBirthdays().getBirthday();
&lt;/pre&gt; 
  &lt;p&gt;The following improved calls show the new names, which say what they
mean and are more relevant to WePrintStuff's business domain.&lt;/p&gt; 
  &lt;pre&gt;	List&amp;lt;Appointment&amp;gt; appointments = printOrder.getPrintItems().getAppointmentHolder().getAppointments();
	List&amp;lt;Birthday&amp;gt; birthdays = printOrder.getPrintItem().getBirthdayHolder().getBirthdays();
&lt;/pre&gt; 
  &lt;p&gt;I tried to solve some of the class structure issues by using the
enhanced &lt;code&gt;&amp;lt;jxb:javaType&amp;gt;&lt;/code&gt; customization
(&lt;code&gt;&amp;lt;xjc:javaType&amp;gt;&lt;/code&gt;) and an adapter class derived
from &lt;code&gt;XmlAdapter&lt;/code&gt;, but JAXB currently does not support
this customization for XML complex types. This issue is documented
in the &lt;a href="https://jaxb.dev.java.net/issues" target="_blank"&gt;JAXB issue tracker&lt;/a&gt; as issue number 209.
Meanwhile, we'll look at an example of the enhanced
&lt;code&gt;&amp;lt;jxb:javaType&amp;gt;&lt;/code&gt; customization used with an XML
simple type in the upcoming paragraphs.&lt;/p&gt; 
  &lt;p&gt;Moving down the source schema, we see that each print order
received will have an ID of type &lt;code&gt;long&lt;/code&gt;. We know,
however, that WePrintStuff employs a natural key
strategy in its persistent store. For print-order records, the key
consists of a client name and an order ID. WePrintStuff uses the
class &lt;code&gt;PrintOrderKey&lt;/code&gt; to encapsulate this key
information. We'll apply a binding customization that causes the
JAXB schema compiler to use an adapter class,
&lt;code&gt;IdAdapter&lt;/code&gt;, to replace the original print-order ID with
WePrintStuff's &lt;code&gt;PrintOrderKey&lt;/code&gt; class. Take a
look:&lt;/p&gt; 
  &lt;pre&gt;   &amp;lt;xs:element name="printOrder" type="PrintOrderType"/&amp;gt;
    &amp;lt;xs:complexType name="PrintOrderType"&amp;gt;
        &amp;lt;xs:sequence&amp;gt;
            &amp;lt;xs:element name="notifications" type="notificationsType" minOccurs="0"/&amp;gt;
        &amp;lt;/xs:sequence&amp;gt;
        &amp;lt;xs:attribute name="id" type="xs:long" use="required"&amp;gt;
            &amp;lt;xs:annotation&amp;gt;
                &amp;lt;xs:appinfo&amp;gt;
                    &amp;lt;!-- Use an XmlAdapter-based adapter to create WePrintStuff's PrintOrderKey class. --&amp;gt;
                    &amp;lt;!-- Specify the name orderKey for this property. --&amp;gt;
                    &amp;lt;jxb:property name="orderKey"&amp;gt;
                        &amp;lt;jxb:baseType&amp;gt;
                            &amp;lt;!-- Specify weprintstuff.print.PrintOrderKey as the type of the orderKey property. --&amp;gt;
                            &amp;lt;!-- Specify the adapter class that will map the schema type to the Java type. --&amp;gt;
                            &amp;lt;xjc:javaType name="weprintstuff.print.PrintOrderKey"
                              adapter="weprintstuff.print.IdAdapter"/&amp;gt;
                        &amp;lt;/jxb:baseType&amp;gt;
                    &amp;lt;/jxb:property&amp;gt;
                &amp;lt;/xs:appinfo&amp;gt;
            &amp;lt;/xs:annotation&amp;gt;
        &amp;lt;/xs:attribute&amp;gt;
    &amp;lt;/xs:complexType&amp;gt;
&lt;/pre&gt; 
  &lt;p&gt;We've changed the name of the print-order property to
&lt;code&gt;orderKey&lt;/code&gt; and specified the types of the adapter and the
order key. During the unmarshalling process, JAXB calls
&lt;code&gt;IdAdapter&lt;/code&gt;'s &lt;code&gt;unmarshal()&lt;/code&gt; method, which
receives the value of &lt;code&gt;id&lt;/code&gt; and incorporates it into a new
&lt;code&gt;PrintOrderKey&lt;/code&gt; containing the order ID and client name.
Here's the code for &lt;code&gt;IdAdapter&lt;/code&gt;:&lt;/p&gt; 
  &lt;pre&gt;	public class IdAdapter extends XmlAdapter&amp;lt;String, PrintOrderKey&amp;gt; {

	    // When marshalling a Java content tree to an XML instance document,
	    // move from the type that we work with in Java (PrintOrderKey)
	    // to the type that JAXB understands.
	    public String marshal(PrintOrderKey key) throws Exception {
	        return key.getOrderId().toString();
	    }

	    // When unmarshalling an XML instance document to a Java content tree,
	    // move from the type that JAXB understands (String) to the type
	    // we want to work with in Java technology.
	    public PrintOrderKey unmarshal(String id) throws Exception {
	        // WePrintStuff uses natural keys. Add client name and
	        // convert String ID to required Long.
	        return new PrintOrderKey("NICEVET", new Long(id));
	    }
	}
&lt;/pre&gt; 
  &lt;p&gt;The &lt;code&gt;&amp;lt;xjc:javaType&amp;gt;&lt;/code&gt; customization we've just
discussed is an example of a vendor extension. The JAXB reference
implementation (RI) offers additional customizations that are not part of
the JAXB specification. To use these extensions, we must include a
declaration for the JAXB RI vendor extension namespace and specify a
namespace prefix:&lt;/p&gt; 
  &lt;pre&gt;	&amp;lt;xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
	                         xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
                                 &amp;lt;!-- JAXB RI vendor extension namespace declaration is required. --&amp;gt;
	                         xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
                                 &amp;lt;!-- JAXB RI vendor extension namespace prefix is required. --&amp;gt;
                                 jxb:extensionBindingPrefixes="xjc"
	                         jxb:version="2.0"&amp;gt;
&lt;/pre&gt; 
  &lt;p&gt;Finally, vendor extensions require that we run the schema
compiler with the &lt;code&gt;-extension&lt;/code&gt; switch. For an example of
the standard &lt;code&gt;&amp;lt;jxb:javaType&amp;gt;&lt;/code&gt; customization, which
is not a vendor extension, check out &lt;code&gt;niceVet.xsd&lt;/code&gt; and
&lt;code&gt;weprintstuff.print.CustomDataTypeConverter&lt;/code&gt;. These files
are included with the &lt;a href="/CoreJavaTechTips/resource/schema-to-java.zip"&gt;sample code&lt;/a&gt; that comes with this tech
tip. In our example, we've used the
&lt;code&gt;&amp;lt;jxb:javaType&amp;gt;&lt;/code&gt; customization to convert XML &lt;code&gt;dateTime&lt;/code&gt;
types to nicely formatted &lt;code&gt;String&lt;/code&gt; dates ready for output.&lt;/p&gt; 
  &lt;p&gt;Things are looking better, but we'd also like to handle the
printing of appointment reminders and birthday cards as
polymorphically as we can.&lt;b&gt; &lt;/b&gt;Take a look at the following:&lt;/p&gt; 
  &lt;pre&gt;   &amp;lt;xs:complexType name="AppointmentType"&amp;gt;
        &amp;lt;xs:annotation&amp;gt;
            &amp;lt;xs:appinfo&amp;gt;
                &amp;lt;!-- Name has generated class Appointment rather than AppointmentType. --&amp;gt;
                &amp;lt;jxb:class name="Appointment"&amp;gt;
                    &amp;lt;jxb:javadoc&amp;gt;&amp;lt;![CDATA[&amp;lt;code&amp;gt;Appointment&amp;lt;/code&amp;gt; javadoc goes here]]&amp;gt;
                    &amp;lt;/jxb:javadoc&amp;gt;
                &amp;lt;/jxb:class&amp;gt;
            &amp;lt;/xs:appinfo&amp;gt;
        &amp;lt;/xs:annotation&amp;gt;
        &amp;lt;xs:complexContent&amp;gt;
            &amp;lt;!-- XML Schema extension element causes AppointmentType to derive from printItemType, a type we've added to the schema. --&amp;gt;
            &amp;lt;xs:extension base="printItemType"&amp;gt;
                &amp;lt;xs:sequence&amp;gt;
                   ...
                &amp;lt;/xs:sequence&amp;gt;
            &amp;lt;/xs:extension&amp;gt;
        &amp;lt;/xs:complexContent&amp;gt;
    &amp;lt;/xs:complexType&amp;gt;
        ...
    &amp;lt;!-- Add this complex type to the schema so that Appointment class now derives from PrintItem, a base class that we've implemented. --&amp;gt;
    &amp;lt;xs:complexType name="printItemType"&amp;gt;
        &amp;lt;xs:annotation&amp;gt;
            &amp;lt;xs:appinfo&amp;gt;
                &amp;lt;!-- Due to this customization, JAXB will not generate a class for printItemType; it will use the PrintItem class that we've written. --&amp;gt;
                &amp;lt;jxb:class ref="weprintstuff.print.PrintItem"/&amp;gt;
            &amp;lt;/xs:appinfo&amp;gt;
        &amp;lt;/xs:annotation&amp;gt;
    &amp;lt;/xs:complexType&amp;gt;
&lt;/pre&gt; 
  &lt;p&gt;Fortunately for us, we can modify the structure of the source
schema somewhat while retaining the schema's ability to validate the
same set of XML instance documents. In this case, we have added a
totally new complex type, &lt;code&gt;printItemType&lt;/code&gt;, to the schema.
Then we modified the complex type &lt;code&gt;AppointmentType&lt;/code&gt; with
the XML Schema extension element, causing
&lt;code&gt;AppointmentType&lt;/code&gt; to derive from
&lt;code&gt;printItemType&lt;/code&gt;.

&lt;/p&gt; 
  &lt;p&gt;At this point, we applied a JAXB customization to
&lt;code&gt;printItemType&lt;/code&gt; that directs the schema compiler to use
the specified class that we've written rather than generating one.
Because we've implemented &lt;code&gt;PrintItem&lt;/code&gt; ourselves, we can
include behavior: specifically, a &lt;code&gt;print()&lt;/code&gt; method that
allows us to handle subclasses, such as &lt;code&gt;Appointment&lt;/code&gt; and
&lt;code&gt;Birthday&lt;/code&gt;, in a more polymorphic manner. Here's the code
for &lt;code&gt;PrintItem&lt;/code&gt;:&lt;/p&gt; 
  &lt;pre&gt;	package weprintstuff.print;

	import java.util.*;

	public abstract class PrintItem {

	    private static final Map&amp;lt;String,Printer&amp;gt; printers;

	    static {
	        printers = new HashMap&amp;lt;String,Printer&amp;gt;();
	        printers.put("weprintstuff.generated.Birthday", new BirthdayPrinter());
	        printers.put("weprintstuff.generated.Appointment", new AppointmentPrinter());
	    }

	    public void print() {
	        Printer p = this.getPrinter();
	        p.print(this);
	    }

	    private Printer getPrinter() {
	        return printers.get(this.getClass().getName());
	    }
	}
&lt;/pre&gt; 
  &lt;p&gt;The &lt;code&gt;Printer&lt;/code&gt; interface has a single method:

&lt;/p&gt; 
  &lt;pre&gt;    public void print(PrintItem item);
&lt;/pre&gt; 
  &lt;p&gt;Although we're still hampered by the structure of the
schema-derived classes as discussed earlier, the code to print the
items in the print order is now pretty clean. Here's an excerpt from
our &lt;code&gt;main()&lt;/code&gt; method:&lt;/p&gt; 
  &lt;pre&gt;	// Unmarshal the data in the XML instance document to a Java content tree
	// made up of instances of the schema-derived classes.
	JAXBElement printOrderElement = (JAXBElement)unmarshaller.unmarshal(new FileInputStream(input));
	PrintOrder printOrder = (PrintOrder)printOrderElement.getValue();

	List&amp;lt;Appointment&amp;gt; appointments = printOrder.getPrintItems().getAppointmentHolder().getAppointments();
	for (Appointment a : appointments) {
		a.print();
	}

	List&amp;lt;Birthday&amp;gt; birthdays = printOrder.getPrintItems().getBirthdayHolder().getBirthdays();
	for (Birthday b : birthdays) {
		b.print();
	}
&lt;/pre&gt; 
  &lt;p&gt;Another nice customization feature that JAXB provides is the
ability to map XML simple types to typesafe enumerations. This is
convenient because WePrintStuff currently has printing templates for
certain types of appointments only. We'll modify the schema to
include the supported appointment types and add a customization that
causes the schema compiler to map the elements of
&lt;code&gt;ApptType&lt;/code&gt; to a Java typesafe enum class. XML instance
documents with appointment types that WePrintStuff does not support
will be rejected:&lt;/p&gt; 
  &lt;pre&gt;    &amp;lt;xs:simpleType name="ApptType"&amp;gt;
        &amp;lt;xs:annotation&amp;gt;
            &amp;lt;xs:appinfo&amp;gt;
                &amp;lt;!-- Map the elements of this simple type to a Java typesafe enum class. --&amp;gt;
                &amp;lt;jxb:typesafeEnumClass/&amp;gt;
            &amp;lt;/xs:appinfo&amp;gt;
        &amp;lt;/xs:annotation&amp;gt;
        &amp;lt;!-- Use XML Schema elements restriction and enumeration to define the supported appointment types. --&amp;gt;
        &amp;lt;xs:restriction base="xs:string"&amp;gt;
            &amp;lt;xs:enumeration value="Yearly Checkup"/&amp;gt;
            &amp;lt;xs:enumeration value="Well Mom Exam"/&amp;gt;
            &amp;lt;xs:enumeration value="Teeth Cleaning"/&amp;gt;
            &amp;lt;xs:enumeration value="Vaccination"/&amp;gt;
            &amp;lt;xs:enumeration value="Senior Pet Checkup"/&amp;gt;
        &amp;lt;/xs:restriction&amp;gt;
    &amp;lt;/xs:simpleType&amp;gt;
&lt;/pre&gt; 
  &lt;p&gt;Here is the resultant typesafe enum class, &lt;code&gt;ApptType&lt;/code&gt;:&lt;/p&gt; 
  &lt;pre&gt;	package weprintstuff.generated;

	import javax.xml.bind.annotation.XmlEnum;
	import javax.xml.bind.annotation.XmlEnumValue;
	import javax.xml.bind.annotation.XmlType;

	@XmlType(name = "ApptType")
	@XmlEnum
	public enum ApptType {

	    @XmlEnumValue("Yearly Checkup")
	    YEARLY_CHECKUP("Yearly Checkup"),
	    @XmlEnumValue("Well Mom Exam")
	    WELL_MOM_EXAM("Well Mom Exam"),
	    @XmlEnumValue("Teeth Cleaning")
	    TEETH_CLEANING("Teeth Cleaning"),
	    @XmlEnumValue("Vaccination")
	    VACCINATION("Vaccination"),
	    @XmlEnumValue("Senior Pet Checkup")
	    SENIOR_PET_CHECKUP("Senior Pet Checkup");
	    private final String value;

	    ApptType(String v) {
	        value = v;
	    }

	    public String value() {
	        return value;
	    }

	    public static ApptType fromValue(String v) {
	        for (ApptType c: ApptType.values()) {
	            if (c.value.equals(v)) {
	                return c;
	            }
	        }
	        throw new IllegalArgumentException(v);
	    }

	}
&lt;/pre&gt; 
  &lt;p&gt;So far we've made what are known as inline binding
customizations, but JAXB also accepts customizations in the form of
one or more external binding customization files. Inline and external
customizations can be used in combination, but they cannot be used
together on the same element. External binding files&lt;b&gt; &lt;/b&gt;are useful when
you cannot modify a given schema or when you want to reuse
customizations across schemas. For example, WePrintStuff has its own
class for U.S. addresses, &lt;code&gt;DomesticAddress&lt;/code&gt;, and WePrintStuff
would like to use this class to represent the concept of an address throughout the system.
&lt;/p&gt; 
  &lt;p&gt;Here's the external binding file, &lt;code&gt;binding.xjb&lt;/code&gt;:&lt;/p&gt; 
  &lt;pre&gt;	&amp;lt;!-- XML Schema namespace is required, as are the JAXB namespace and version. --&amp;gt;
	&amp;lt;jxb:bindings version="2.0"
	               xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
	               xmlns:xs="http://www.w3.org/2001/XMLSchema"&amp;gt;

	  &amp;lt;!-- Specify the schema name and root schema node. --&amp;gt;
	  &amp;lt;jxb:bindings schemaLocation="niceVet.xsd" node="/xs:schema"&amp;gt;

	    &amp;lt;!-- Specify the schema node to which this customization should apply with an XPath expression. --&amp;gt;
	    &amp;lt;jxb:bindings node="//xs:complexType[@name='AddressType']"&amp;gt;
                &amp;lt;!-- Direct the schema compiler to use the DomesticAddress class rather than generating a class for complex type AddressType. --&amp;gt;
	        &amp;lt;jxb:class ref="weprintstuff.print.DomesticAddress"/&amp;gt;
	    &amp;lt;/jxb:bindings&amp;gt; &amp;lt;!-- node="//xs:complexType[@name='AddressType']" --&amp;gt;

	  &amp;lt;/jxb:bindings&amp;gt; &amp;lt;!-- schemaLocation="niceVet.xsd" node="/xs:schema" --&amp;gt;
	&amp;lt;/jxb:bindings&amp;gt;
&lt;/pre&gt; 
  &lt;p&gt;The binding customization file&lt;b&gt; &lt;/b&gt;is
just an ASCII text file. A valid binding file must specify the
schema name and node. We identify nodes using XPath expressions.
In the previous listing, we've applied a customization that directs
the schema compiler to use WePrintStuff's
&lt;code&gt;DomesticAddress&lt;/code&gt; class rather than generating a class
for the complex type &lt;code&gt;AddressType&lt;/code&gt;. This is the same
customization illustrated earlier in our &lt;code&gt;PrintItem&lt;/code&gt; base
class example, although in that situation, we declared the
customization inline. The syntax for supplying a binding
customization file&lt;b&gt; &lt;/b&gt;to the schema compiler is the following:&lt;/p&gt; 
  &lt;pre&gt;	xjc -b bindings schema
&lt;/pre&gt; 
  &lt;p&gt;We can apply multiple binding files to one schema, one binding
file to multiple schemas, or multiple binding files to multiple
schemas. Each binding file must have its own &lt;code&gt;-b&lt;/code&gt; switch.&lt;/p&gt; 
  &lt;h2&gt;Generating the Schema-Derived Classes&lt;/h2&gt; 
  &lt;p&gt;We generate our schema-derived classes at the command line with
the following command to the schema compiler, &lt;code&gt;xjc&lt;/code&gt;:&lt;/p&gt; 
  &lt;pre&gt;	xjc -d ./src -b binding.xjb -extension niceVet.xsd
&lt;/pre&gt; 
  &lt;p&gt;The schema compiler informs us that it has generated our classes
with the following output:&lt;/p&gt; 
  &lt;pre&gt;	parsing a schema...
	compiling a schema...
	weprintstuff\generated\Adapter1.java
	weprintstuff\generated\Adapter2.java
	weprintstuff\generated\Appointment.java
	weprintstuff\generated\ApptType.java
	weprintstuff\generated\Birthday.java
	weprintstuff\generated\ObjectFactory.java
	weprintstuff\generated\Owner.java
	weprintstuff\generated\Pet.java
	weprintstuff\generated\PrintItems.java
	weprintstuff\generated\PrintOrder.java
	weprintstuff\generated\package.html
&lt;/pre&gt; 
  &lt;p&gt;The JAXB schema compiler has a number of options. For example, it
will mark generated classes as &lt;code&gt;read only&lt;/code&gt; in response to
the &lt;code&gt;-readOnly&lt;/code&gt; switch. Invoke &lt;code&gt;xjc&lt;/code&gt; with no
options or with the &lt;code&gt;-help&lt;/code&gt; switch for more
information.&lt;/p&gt; 
  &lt;h2&gt;The Payoff&lt;/h2&gt; 
  &lt;p&gt;We've modified our source schema, made our customizations, and
generated our schema-derived classes. All that's left to do is run
our printing program, let JAXB bind the XML data supplied by
NiceVet, and print out the appointment reminders and birthday cards.
We'll take a look at our XML instance document:&lt;/p&gt; 
  &lt;pre&gt;&amp;lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&amp;gt;
&amp;lt;printOrder id="1219271208522"&amp;gt;
    &amp;lt;notifications&amp;gt;
        &amp;lt;appointments&amp;gt;
            &amp;lt;appointment&amp;gt;
                &amp;lt;apptType&amp;gt;Yearly Checkup&amp;lt;/apptType&amp;gt;
                &amp;lt;apptDate&amp;gt;2008-09-15T00:00:00-07:00&amp;lt;/apptDate&amp;gt;
                &amp;lt;owner&amp;gt;
                    &amp;lt;firstName&amp;gt;Joe&amp;lt;/firstName&amp;gt;
                    &amp;lt;lastName&amp;gt;Outdoors&amp;lt;/lastName&amp;gt;
                    &amp;lt;address&amp;gt;
                        &amp;lt;addressLine1&amp;gt;123 Whitewater Street&amp;lt;/addressLine1&amp;gt;
                        &amp;lt;city&amp;gt;OurTown&amp;lt;/city&amp;gt;
                        &amp;lt;state&amp;gt;CA&amp;lt;/state&amp;gt;
                        &amp;lt;zip&amp;gt;90347&amp;lt;/zip&amp;gt;
                        &amp;lt;zipExt&amp;gt;1234&amp;lt;/zipExt&amp;gt;
                    &amp;lt;/address&amp;gt;
                &amp;lt;/owner&amp;gt;
                &amp;lt;pet&amp;gt;
                    &amp;lt;name&amp;gt;Honcho&amp;lt;/name&amp;gt;
                    &amp;lt;species&amp;gt;Dog&amp;lt;/species&amp;gt;
                &amp;lt;/pet&amp;gt;
            &amp;lt;/appointment&amp;gt;
            &amp;lt;appointment&amp;gt;
                &amp;lt;apptType&amp;gt;Well Mom Exam&amp;lt;/apptType&amp;gt;
                &amp;lt;apptDate&amp;gt;2008-09-12T00:00:00-07:00&amp;lt;/apptDate&amp;gt;
                &amp;lt;owner&amp;gt;
                    &amp;lt;firstName&amp;gt;Missy&amp;lt;/firstName&amp;gt;
                    &amp;lt;lastName&amp;gt;Fairchild&amp;lt;/lastName&amp;gt;
                    &amp;lt;address&amp;gt;
                        &amp;lt;addressLine1&amp;gt;456 Scenic Drive&amp;lt;/addressLine1&amp;gt;
                        &amp;lt;city&amp;gt;West OurTown&amp;lt;/city&amp;gt;
                        &amp;lt;state&amp;gt;CA&amp;lt;/state&amp;gt;
                        &amp;lt;zip&amp;gt;90349&amp;lt;/zip&amp;gt;
                        &amp;lt;zipExt&amp;gt;6789&amp;lt;/zipExt&amp;gt;
                    &amp;lt;/address&amp;gt;
                &amp;lt;/owner&amp;gt;
                &amp;lt;pet&amp;gt;
                    &amp;lt;name&amp;gt;Miss Kitty&amp;lt;/name&amp;gt;
                    &amp;lt;species&amp;gt;Cat&amp;lt;/species&amp;gt;
                &amp;lt;/pet&amp;gt;
            &amp;lt;/appointment&amp;gt;
        &amp;lt;/appointments&amp;gt;
        &amp;lt;birthdays&amp;gt;
            &amp;lt;birthday&amp;gt;
                &amp;lt;age&amp;gt;7&amp;lt;/age&amp;gt;
                &amp;lt;birthday&amp;gt;2000-09-07T00:00:00-07:00&amp;lt;/birthday&amp;gt;
                &amp;lt;owner&amp;gt;
                    &amp;lt;firstName&amp;gt;Violet&amp;lt;/firstName&amp;gt;
                    &amp;lt;lastName&amp;gt;Flowers&amp;lt;/lastName&amp;gt;
                    &amp;lt;address&amp;gt;
                        &amp;lt;addressLine1&amp;gt;22375 Willow Court&amp;lt;/addressLine1&amp;gt;
                        &amp;lt;city&amp;gt;West OurTown&amp;lt;/city&amp;gt;
                        &amp;lt;state&amp;gt;CA&amp;lt;/state&amp;gt;
                        &amp;lt;zip&amp;gt;90349&amp;lt;/zip&amp;gt;
                        &amp;lt;zipExt&amp;gt;6789&amp;lt;/zipExt&amp;gt;
                    &amp;lt;/address&amp;gt;
                &amp;lt;/owner&amp;gt;
                &amp;lt;pet&amp;gt;
                    &amp;lt;name&amp;gt;Tom&amp;lt;/name&amp;gt;
                    &amp;lt;species&amp;gt;Cat&amp;lt;/species&amp;gt;
                &amp;lt;/pet&amp;gt;
            &amp;lt;/birthday&amp;gt;
        &amp;lt;/birthdays&amp;gt;
    &amp;lt;/notifications&amp;gt;
&amp;lt;/printOrder&amp;gt;
&lt;/pre&gt; 
  &lt;p&gt;And here's another look at the &lt;code&gt;main()&lt;/code&gt; method:&lt;/p&gt; 
  &lt;pre&gt;	// The XML instance document received from NiceVet contains NiceVet's print order.
	File input = new File("niceVet.xml");

	// Create a JAXBContext for the weprintstuff.generated package.
	JAXBContext ctx = JAXBContext.newInstance("weprintstuff.generated");

	// Create an unmarshaller.
	Unmarshaller unmarshaller = ctx.createUnmarshaller();

	// Unmarshal the data in the XML instance document to a Java content tree made up of instances of the schema-derived classes.

	JAXBElement printOrderElement = (JAXBElement)unmarshaller.unmarshal(new FileInputStream(input));
	PrintOrder printOrder = (PrintOrder)printOrderElement.getValue();

	// Print out the print items.&lt;b&gt;&lt;/b&gt;	
        List&amp;lt;Appointment&amp;gt; appointments = printOrder.getPrintItems().getAppointmentHolder().getAppointments();
	for (Appointment a : appointments) {
		a.print();
	}

	List&amp;lt;Birthday&amp;gt; birthdays = printOrder.getPrintItems().getBirthdayHolder().getBirthdays();
	for (Birthday b : birthdays) {
		b.print();
	}
&lt;/pre&gt; 
  &lt;p&gt;Check out our results: No one will ever miss an appointment or a
birthday again.&lt;/p&gt; 
  &lt;pre&gt;	Hi Joe!
	Our records show that your dog Honcho has a Yearly Checkup appointment scheduled on 09/15/2008.
	Please call us 24 hours prior to your appointment if you need to reschedule.
	Sincerely, NiceVet

	Hi Missy!&lt;b&gt;&lt;/b&gt; Our records show that your cat Miss Kitty has a Well Mom Exam appointment scheduled on 09/12/2008.
	Please call us 24 hours prior to your appointment if you need to reschedule.
	Sincerely, NiceVet

	Hi Violet!
	Our records show that your cat Tom will turn 7 years old on 09/07.
	Happy Birthday, Tom, from all of us at NiceVet!
&lt;/pre&gt; 
  &lt;h2&gt;Running the Sample Application&lt;/h2&gt; 
  &lt;p&gt;To run the sample application, download the &lt;a href="/CoreJavaTechTips/resource/schema-to-java.zip"&gt;sample code&lt;/a&gt; and unzip
it. Navigate
to the directory
&lt;code&gt;&amp;lt;sample-install-dir&amp;gt;/schema-to-java&lt;/code&gt; and generate
the schema-derived classes as described in the section &amp;quot;Generating
the Schema-Derived Classes.&amp;quot;

&lt;/p&gt; 
  &lt;p&gt;Launch the &lt;a href="http://www.netbeans.org/" target="_blank"&gt;NetBeans IDE&lt;/a&gt; and select File &amp;gt; Open Project.
In the Open Project dialog box, navigate to the directory where you
unzipped the sample code and select the folder &lt;code&gt;schema-to-java&lt;/code&gt;.
Select the Open as Main Project check box. Click Open Project
Folder. Right-click the &lt;code&gt;schema-to-java&lt;/code&gt; project and select Run
Project.&lt;/p&gt; 
  &lt;h2&gt;Conclusion&lt;/h2&gt; 
  &lt;p&gt;In Exchanging Data With XML and JAXB, Parts &lt;a href="/CoreJavaTechTips/entry/exchanging_data_with_xml_and"&gt;1&lt;/a&gt; and 2, we've learned how JAXB can facilitate the flow of data between
business partners. With features that expedite XML processing on
both ends of the exchange, JAXB can enable simpler, more productive
integration between systems.&lt;/p&gt; 
  &lt;h2&gt;References and Resources&lt;/h2&gt; 
  &lt;p&gt;&lt;a href="/CoreJavaTechTips/resource/schema-to-java.zip"&gt;Sample code for this tip&lt;/a&gt;&lt;br /&gt; &lt;a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnazf.html"&gt;Java EE 5 Tutorial&lt;/a&gt; &lt;br /&gt; &lt;a href="http://weblogs.java.net/blog/kohsuke/" target="_blank"&gt;Kohsuke Kawaguchi's Blog&lt;/a&gt; - Kohsuke Kawaguchi is a staff engineer at Sun Microsystems, where he works on JAXB, among other projects.&lt;br /&gt; &lt;a href="http://jcp.org/en/jsr/detail?id=222" target="_blank"&gt;JSR 222: JAXB Specification&lt;/a&gt;&lt;/p&gt; 
  &lt;h3&gt;About the Author&lt;/h3&gt; 
  &lt;p&gt;&lt;b&gt;Jennie Hall&lt;/b&gt; is a lead developer working in the financial sector.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/corejavatechtips/~4/393370150" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://blogs.sun.com/CoreJavaTechTips/entry/exchanging_data_with_xml_and1</feedburner:origLink></entry>
    <entry>
        <id>http://blogs.sun.com/CoreJavaTechTips/entry/exchanging_data_with_xml_and</id>
        <title type="html">Exchanging Data with XML and JAXB, Part 1</title>
        <author><name>dananourie</name></author>
        <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/corejavatechtips/~3/363387193/exchanging_data_with_xml_and" />
        <published>2008-08-12T16:35:28-07:00</published>
        <updated>2008-09-11T13:13:26-07:00</updated> 
        <category term="/TechTip" label="TechTip" />
        <category term="data" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="java" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="java-se" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="jaxb" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="xml" scheme="http://rollerweblogger.org/ns/tags/" />
        <summary type="html">In this tip, you'll learn how to to use the Java Architecture for XML Binding (JAXB) in Java SE 6 to exchange XML data between systems without having to delve into the specifics of XML processing.&amp;nbsp;</summary>
        <content type="html">by Jennie Hall 
  
  
  
  
  
  
  
  
  
  
  
  
  &lt;p&gt;In this tip, you'll learn how to to use the &lt;a href="https://jaxb.dev.java.net/"&gt;Java Architecture for XML Binding (JAXB)&lt;/a&gt; in &lt;a href="http://java.sun.com/javase/downloads/?intcmp=1281"&gt;Java SE 6&lt;/a&gt; to exchange XML data between systems without having to delve into the specifics of XML processing. Among other key improvements, JAXB 2.0 offers support for binding Java objects to XML via the use of annotations. This feature allows you to generate XML data from your application simply by annotating your existing object model.&lt;/p&gt; 
  &lt;h2&gt;What's JAXB?&lt;/h2&gt; 
  &lt;p&gt;  JAXB simplifies the use of XML data in Java applications by shielding you and your code from the low-level details of working with XML. Essentially, JAXB allows you to move easily back-and-forth between XML and Java. A JAXB implementation supplies a schema compiler, which takes in an XML schema and generates Java classes which map to that schema. Data from XML documents which are instances of the schema can be bound automatically to the generated classes by JAXB's binding runtime framework. This is called unmarshalling. Once unmarshalled, content can be manipulated or modified in Java as needed. JAXB can also write (marshal) data from Java objects to an XML instance document. JAXB optionally performs validation of content as part of these operations.&lt;/p&gt; 
  &lt;p&gt;In addition to the schema compiler, a JAXB implementation also provides a schema generator, which looks at annotations on Java classes and generates a corresponding XML schema. This feature is new to JAXB 2.0.&lt;/p&gt; 
  &lt;h2&gt;The Sample Application&lt;/h2&gt; 
  &lt;p&gt;
  A veterinary office wants to send notices to its clients reminding them of their pets' upcoming appointments. Because they are nice folks, they also like to send a birthday card to an owner on the pet's birthday. The veterinary office, NiceVet, contracts with a service provider, WePrintStuff, to do their printing and mailing for them.
&lt;/p&gt; 
  &lt;p&gt;NiceVet already has an application which maintains information about the animals under NiceVet's care and their owners. Here's a diagram of NiceVet's existing object model:&lt;/p&gt; 
  &lt;p&gt;&lt;img src="/CoreJavaTechTips/resource/NiceVetObjectModel.gif" /&gt;&lt;br /&gt;&lt;/p&gt; 
  &lt;p&gt;NiceVet needs a way to get the necessary notification data to WePrintStuff for processing without spending a lot of time and money modifying their current application.&lt;/p&gt; 
  &lt;h2&gt;Generating the XML&lt;/h2&gt; 
  &lt;p&gt;  It's time to annotate our object model so we can generate some XML data for the printing and mailing service. Looking at NiceVet's object model, we see that the &lt;code&gt;PrintOrder&lt;/code&gt; class holds the information about upcoming events, and thus makes sense as the root element of the data we want to send. Let's add the &lt;code&gt;@XmlRootElement &lt;/code&gt;annotation to the &lt;code&gt;PrintOrder&lt;/code&gt; class. This will establish &lt;code&gt;printOrder&lt;/code&gt; as the root element of our generated XML.&lt;/p&gt; 
  &lt;pre&gt;	import javax.xml.bind.annotation.XmlRootElement;

	// the root element of our generated XML
	@XmlRootElement(name = "printOrder")
	public class PrintOrder {

	    private long id;
	    private List&amp;lt;Event&amp;gt; events;&lt;/pre&gt; 
  &lt;p&gt;Let's add some more annotations:&lt;/p&gt; 
  &lt;pre&gt;	import javax.xml.bind.annotation.XmlRootElement;
	import javax.xml.bind.annotation.XmlType;
	import javax.xml.bind.annotation.XmlAccessorType;
	import javax.xml.bind.annotation.XmlAccessType;
	import javax.xml.bind.annotation.XmlAttribute;
	import javax.xml.bind.annotation.XmlElement;
	import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

	// the root element of our generated XML
	@XmlRootElement(name = "printOrder")
	// maps this class to a generated schema type
	@XmlType(name = "PrintOrderType", propOrder = {"events"})
	// bind all non-static, non-transient fields
	// to XML unless annotated with @XmlTransient
	@XmlAccessorType(XmlAccessType.FIELD)
	public class PrintOrder {

	    // maps this field to an XML attribute
	    @XmlAttribute(required = true)
	    private long id;
	    // custom adapter maps this field to a type,

	    // NotificationsType, which makes it easy to
	    // generate the desired XML
	    @XmlJavaTypeAdapter(value=EventAdapter.class)   
	    @XmlElement(name = "notifications")
	    private List&amp;lt;Event&amp;gt; events;&lt;/pre&gt; 
  &lt;p&gt;&lt;code&gt;@XmlType&lt;/code&gt; maps the &lt;code&gt;PrintOrder&lt;/code&gt; class to a generated schema type named &lt;code&gt;PrintOrderType&lt;/code&gt;. The &lt;code&gt;@XmlAccessorType(XmlAccessType.FIELD) &lt;/code&gt;annotation tells JAXB to bind all non-static, non-transient fields to XML unless annotated with &lt;code&gt;@XmlTransient&lt;/code&gt;, which prevents the mapping of a field or property. With the &lt;code&gt;XmlAccessType.FIELD &lt;/code&gt;setting, getter/setter pairs are not bound to XML unless explicitly annotated. The default setting is &lt;code&gt;XmlAccessType.PUBLIC_MEMBER&lt;/code&gt; (all public fields and getter/setter pairs are bound unless otherwise annotated); other settings are&lt;code&gt; XmlAccessType.PROPERTY&lt;/code&gt; and &lt;code&gt;XmlAccessType.NONE&lt;/code&gt;.&lt;/p&gt; 
  &lt;p&gt;Moving down the code listing, we see that the field id maps to an XML attribute on the &lt;code&gt;PrintOrderType &lt;/code&gt;element. Some kind of identifier on the print order is required, and we've annotated the id field accordingly.&lt;/p&gt; 
  &lt;p&gt;The &lt;code&gt;PrintOrder&lt;/code&gt; class has a list of events which contains both appointments and birthdays. The annotation &lt;code&gt;@XmlJavaTypeAdapter&lt;/code&gt; tells JAXB that we are going to use a custom adapter, &lt;code&gt;EventAdapter&lt;/code&gt;, to help us map this Java construct to XML. To support this annotation, we need to write an adapter class which extends &lt;code&gt;XmlAdapter&lt;/code&gt; and overrides its abstract marshal and unmarshal methods.&lt;/p&gt; 
  &lt;pre&gt;	public class EventAdapter extends XmlAdapter&lt;strong&gt;&amp;lt;NotificationsType, List&amp;lt;Event&amp;gt;&amp;gt;&lt;/strong&gt; {

	    // adapt original Java construct to a type, NotificationsType,
	    // which we can easily map to the XML output we want
	    public NotificationsType marshal(List&amp;lt;Event&amp;gt; events) throws Exception {
	        List&amp;lt;Appointment&amp;gt; appointments = new ArrayList&amp;lt;Appointment&amp;gt;();
	        List&amp;lt;Birthday&amp;gt; birthdays = new ArrayList&amp;lt;Birthday&amp;gt;();
	        
	        for (Event e : events) {
	            if (e instanceof Appointment) {
	                appointments.add((Appointment)e);
	            } else {
	                birthdays.add((Birthday)e);              
	            }
	        }        
	        return new NotificationsType(appointments, birthdays);
	    }

	    // reverse operation: map XML type to Java
	    public List&amp;lt;Event&amp;gt; unmarshal(NotificationsType notifications) throws Exception { ... }
        &lt;/pre&gt; 
  &lt;p&gt;EventAdapter's marshal method takes the original Java construct, &lt;code&gt;List&amp;lt;Event&amp;gt;&lt;/code&gt; events, and converts it to a type which maps more easily to the XML output we want. Let's take a look at &lt;code&gt;NotificationsType&lt;/code&gt;: &lt;/p&gt; 
  &lt;pre&gt;	import javax.xml.bind.annotation.XmlElementWrapper;
	import javax.xml.bind.annotation.XmlElement;
	import java.util.List;

	public class NotificationsType {
	    
	    // produce a wrapper XML element around this collection
	    @XmlElementWrapper(name = "appointments")
	    // maps each member of this list to an XML element named appointment
	    @XmlElement(name = "appointment")
	    //private List&amp;lt;Appointment&amp;gt; appointments;
	    private List&amp;lt;Appointment&amp;gt; appointments;
	    // produce a wrapper XML element around this collection
	    @XmlElementWrapper(name = "birthdays")
	    // maps each member of this list to an XML element named birthday
	    @XmlElement(name = "birthday")
	    //private List&amp;lt;Birthday&amp;gt; birthdays;
	    private List&amp;lt;Birthday&amp;gt; birthdays;
	    
	    public NotificationsType() {}
	    
	    public NotificationsType(List&amp;lt;Appointment&amp;gt; appointments, List&amp;lt;Birthday&amp;gt; birthdays) {
	        this.appointments = appointments;
	        this.birthdays = birthdays;
	    }		
&lt;/pre&gt; 
  &lt;p&gt;The &lt;code&gt;@XmlElementWrapper&lt;/code&gt; annotation creates a wrapper XML element around each collection, and the &lt;code&gt;@XmlElement &lt;/code&gt;annotation maps each member of the collection to an XML element of the appropriate type. Combined with the &lt;code&gt;@XmlElement(name = &amp;quot;notifications&amp;quot;)&lt;/code&gt; annotation on &lt;code&gt;PrintOrder.events&lt;/code&gt;, what we end up with will look something like this: &lt;/p&gt; 
  &lt;pre&gt;	&amp;lt;printOrder&amp;gt;
		&amp;lt;notifications&amp;gt;
			&amp;lt;appointments&amp;gt;
				&amp;lt;appointment&amp;gt;
					...
				&amp;lt;/appointment&amp;gt;
			&amp;lt;/appointments&amp;gt;
			&amp;lt;birthdays&amp;gt;
				&amp;lt;birthday&amp;gt;
					...
				&amp;lt;/birthday&amp;gt;
			&amp;lt;/birthdays&amp;gt;
		&amp;lt;/notifications&amp;gt;
	&amp;lt;/printOrder&amp;gt;
&lt;/pre&gt; 
  &lt;p&gt;Another annotation worth mentioning lies in the abstract base class Event (listing below), from which subclasses Appointment and Birthday inherit. This inheritance hierarchy won't hold much meaning for our service provider, WePrintStuff, so we'll eliminate it with the &lt;code&gt;@XmlTransient &lt;/code&gt;annotation on &lt;code&gt;Event&lt;/code&gt;. We still need fields owner and pet, however, so we annotate them with &lt;code&gt;@XmlElement(required = true)&lt;/code&gt;.&lt;/p&gt; 
  &lt;pre&gt;	import javax.xml.bind.annotation.XmlElement;
	import javax.xml.bind.annotation.XmlTransient;

	// no need to capture this inheritance hierarchy in XML
	@XmlTransient
	public abstract class Event {

	    @XmlElement(required = true)
	    private Owner owner;
	    @XmlElement(required = true)
	    private Pet pet;

	    public Event() {}
	            
	    public Event(Owner owner, Pet pet) {
	       this.owner = owner;
	       this.pet = pet;
	    }
&lt;/pre&gt; 
  &lt;p&gt;
When objects of type Birthday and Appointment are marshalled to XML, they will include all the relevant data from their supertype, &lt;code&gt;Event&lt;/code&gt;. Take a look at the listing below for the &lt;code&gt;Birthday&lt;/code&gt; class:&lt;/p&gt; 
  &lt;pre&gt;	@XmlType(name = "BirthdayType", propOrder = {"age", "birthday", "owner", "pet"})
	@XmlAccessorType(XmlAccessType.FIELD)
	public class Birthday extends Event {

	    @XmlElement(required = true)
	    private int age;
	    
	    public Birthday() {}
	    
	    public Birthday(Owner owner, Pet pet) {
	        super(owner, pet);
	        this.age = this.calculateAge();
	    }

	    @XmlElement(name = "birthday", required = true)
	    public Date getBirthday() {
	        return this.getPet().getDateOfBirth();
	    }
&lt;/pre&gt; 
  &lt;p&gt;&lt;code&gt;@XmlType.propOrder&lt;/code&gt; specifies the order in which content is marshalled and unmarshalled. This order would otherwise be unspecified due to the nature of Java reflection. Alternatively, you can impose an order with the &lt;code&gt;@XmlAccessorOrder&lt;/code&gt; annotation. As mentioned in the Java Tutorial, imposing an order improves application portability across JAXB implementations.&lt;br /&gt; &lt;br /&gt;
Although the field &lt;code&gt;dateOfBirth&lt;/code&gt; is actually on the &lt;code&gt;Pet&lt;/code&gt; class, it makes more sense in terms of our XML representation if this data is organized as an element under the birthday element. We can achieve this without a &lt;code&gt;dateOfBirth&lt;/code&gt; field on the &lt;code&gt;Birthday&lt;/code&gt; class by annotating the &lt;code&gt;getBirthday()&lt;/code&gt; method, which delegates to &lt;code&gt;Pet&lt;/code&gt;.&lt;/p&gt; 
  &lt;p&gt;On a related note, WePrintStuff doesn't need to do any additional processing with the dates NiceVet sends them; they just need to locate the correct notification template and print the information out. As we saw earlier with the events list on the &lt;code&gt;PrintOrder&lt;/code&gt; class, we can supply a custom adapter to get the desired XML output. This time, however, we'll specify the adapter through a package-level annotation. The adapter will take in all &lt;code&gt;java.util.Date&lt;/code&gt; instances and output nicely formatted &lt;code&gt;Strings&lt;/code&gt;. The package-level annotation goes in the &lt;code&gt;package-info.java&lt;/code&gt; file (located in the vet package):&lt;/p&gt; 
  &lt;pre&gt;	// every java.util.Date class in the vet package should be
	// processed by DateAdapter
	@XmlJavaTypeAdapter(value=DateAdapter.class, type=Date.class)
	package vet;

	import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
	import java.util.Date;
    &lt;/pre&gt; 
  &lt;p&gt;Although JAXB can handle marshalling java.util.Date to XML in a default manner on its own, we're telling JAXB to use an alternative, customized mapping which better suits our purposes. We implement the adapter in much the same way as above:&lt;/p&gt; 
  &lt;pre&gt;	import java.util.Date;
	import java.text.SimpleDateFormat;
	import javax.xml.bind.annotation.adapters.XmlAdapter;

	public class DateAdapter extends XmlAdapter&lt;strong&gt;&amp;lt;String, Date&amp;gt;&lt;/strong&gt; {

		// the desired format
	    private String pattern = "MM/dd/yyyy";
	    
	    public String marshal(Date date) throws Exception {
	        return new SimpleDateFormat(pattern).format(date);
	    }
	    
	    public Date unmarshal(String dateString) throws Exception {
	        return new SimpleDateFormat(pattern).parse(dateString);
	    }	
	
  &lt;/pre&gt; 
  &lt;p&gt;The annotations on the other classes in the object model are similar to what we've seen so far; take a peek at the sample code included with this tip to see exactly what's going on in the other classes.&lt;br /&gt; &lt;br /&gt;
We've finished annotating NiceVet's object model and we're ready to generate some XML. If we run the sample application, we should see an XML instance document something like the following listing. The document, niceVet.xml, is located in the root directory of the java-to-schema project.&lt;/p&gt; 
  &lt;pre&gt;	&amp;lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&amp;gt;
	&amp;lt;printOrder id="1218226109781"&amp;gt;
	    &amp;lt;notifications&amp;gt;
	        &amp;lt;appointments&amp;gt;
	            &amp;lt;appointment&amp;gt;
	                &amp;lt;apptType&amp;gt;Yearly Checkup&amp;lt;/apptType&amp;gt;
	                &amp;lt;apptDate&amp;gt;09/15/2008&amp;lt;/apptDate&amp;gt;
	                &amp;lt;owner&amp;gt;
	                    &amp;lt;firstName&amp;gt;Joe&amp;lt;/firstName&amp;gt;
	                    &amp;lt;lastName&amp;gt;Outdoors&amp;lt;/lastName&amp;gt;
	                    &amp;lt;address&amp;gt;
	                        &amp;lt;addressLine1&amp;gt;123 Whitewater Street&amp;lt;/addressLine1&amp;gt;
	                        &amp;lt;city&amp;gt;OurTown&amp;lt;/city&amp;gt;
	                        &amp;lt;state&amp;gt;CA&amp;lt;/state&amp;gt;
	                        &amp;lt;zip&amp;gt;90347&amp;lt;/zip&amp;gt;
	                        &amp;lt;zipExt&amp;gt;1234&amp;lt;/zipExt&amp;gt;
	                    &amp;lt;/address&amp;gt;
	                &amp;lt;/owner&amp;gt;
	                &amp;lt;pet&amp;gt;
	                    &amp;lt;name&amp;gt;Honcho&amp;lt;/name&amp;gt;
	                    &amp;lt;species&amp;gt;Dog&amp;lt;/species&amp;gt;
	                &amp;lt;/pet&amp;gt;
	            &amp;lt;/appointment&amp;gt;
	            &amp;lt;appointment&amp;gt;
	                &amp;lt;apptType&amp;gt;Well Mom Exam&amp;lt;/apptType&amp;gt;
	                &amp;lt;apptDate&amp;gt;09/12/2008&amp;lt;/apptDate&amp;gt;
	                &amp;lt;owner&amp;gt;
	                    &amp;lt;firstName&amp;gt;Missy&amp;lt;/firstName&amp;gt;
	                    &amp;lt;lastName&amp;gt;Fairchild&amp;lt;/lastName&amp;gt;
	                    &amp;lt;address&amp;gt;
	                        &amp;lt;addressLine1&amp;gt;456 Scenic Drive&amp;lt;/addressLine1&amp;gt;
	                        &amp;lt;city&amp;gt;West OurTown&amp;lt;/city&amp;gt;
	                        &amp;lt;state&amp;gt;CA&amp;lt;/state&amp;gt;
	                        &amp;lt;zip&amp;gt;90349&amp;lt;/zip&amp;gt;
	                        &amp;lt;zipExt&amp;gt;6789&amp;lt;/zipExt&amp;gt;
	                    &amp;lt;/address&amp;gt;
	                &amp;lt;/owner&amp;gt;
	                &amp;lt;pet&amp;gt;
	                    &amp;lt;name&amp;gt;Miss Kitty&amp;lt;/name&amp;gt;
	                    &amp;lt;species&amp;gt;Cat&amp;lt;/species&amp;gt;
	                &amp;lt;/pet&amp;gt;
	            &amp;lt;/appointment&amp;gt;
	        &amp;lt;/appointments&amp;gt;
	        &amp;lt;birthdays&amp;gt;
	            &amp;lt;birthday&amp;gt;
	                &amp;lt;age&amp;gt;7&amp;lt;/age&amp;gt;
	                &amp;lt;birthday&amp;gt;09/07/2000&amp;lt;/birthday&amp;gt;
	                &amp;lt;owner&amp;gt;
	                    &amp;lt;firstName&amp;gt;Violet&amp;lt;/firstName&amp;gt;
	                    &amp;lt;lastName&amp;gt;Flowers&amp;lt;/lastName&amp;gt;
	                    &amp;lt;address&amp;gt;
	                        &amp;lt;addressLine1&amp;gt;22375 Willow Court&amp;lt;/addressLine1&amp;gt;
	                        &amp;lt;city&amp;gt;West OurTown&amp;lt;/city&amp;gt;
	                        &amp;lt;state&amp;gt;CA&amp;lt;/state&amp;gt;
	                        &amp;lt;zip&amp;gt;90349&amp;lt;/zip&amp;gt;
	                        &amp;lt;zipExt&amp;gt;6789&amp;lt;/zipExt&amp;gt;
	                    &amp;lt;/address&amp;gt;
	                &amp;lt;/owner&amp;gt;
	                &amp;lt;pet&amp;gt;
	                    &amp;lt;name&amp;gt;Tom&amp;lt;/name&amp;gt;
	                    &amp;lt;species&amp;gt;Cat&amp;lt;/species&amp;gt;
	                &amp;lt;/pet&amp;gt;
	            &amp;lt;/birthday&amp;gt;
	        &amp;lt;/birthdays&amp;gt;
	    &amp;lt;/notifications&amp;gt;
	&amp;lt;/printOrder&amp;gt;

&lt;/pre&gt; 
  &lt;p&gt;The generated schema for the XML instance document above is named &lt;code&gt;schema1.xsd&lt;/code&gt;, and it lives in &lt;code&gt;/generated/schema&lt;/code&gt; under the root directory of the java-to-schema project. It looks like this:&lt;/p&gt; 
  &lt;pre&gt;	&amp;lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&amp;gt;
	&amp;lt;xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"&amp;gt;

	  &amp;lt;xs:element name="printOrder" type="PrintOrderType"/&amp;gt;

	  &amp;lt;xs:complexType name="PrintOrderType"&amp;gt;
	    &amp;lt;xs:sequence&amp;gt;
	      &amp;lt;xs:element name="notifications" type="notificationsType" minOccurs="0"/&amp;gt;
	    &amp;lt;/xs:sequence&amp;gt;
	    &amp;lt;xs:attribute name="id" type="xs:long" use="required"/&amp;gt;
	  &amp;lt;/xs:complexType&amp;gt;

	  &amp;lt;xs:complexType name="notificationsType"&amp;gt;
	    &amp;lt;xs:sequence&amp;gt;
	      &amp;lt;xs:element name="appointments" minOccurs="0"&amp;gt;
	        &amp;lt;xs:complexType&amp;gt;
	          &amp;lt;xs:sequence&amp;gt;
	            &amp;lt;xs:element name="appointment" type="AppointmentType" minOccurs="0" maxOccurs="unbounded"/&amp;gt;
	          &amp;lt;/xs:sequence&amp;gt;
	        &amp;lt;/xs:complexType&amp;gt;
	      &amp;lt;/xs:element&amp;gt;
	      &amp;lt;xs:element name="birthdays" minOccurs="0"&amp;gt;
	        &amp;lt;xs:complexType&amp;gt;
	          &amp;lt;xs:sequence&amp;gt;
	            &amp;lt;xs:element name="birthday" type="BirthdayType" minOccurs="0" maxOccurs="unbounded"/&amp;gt;
	          &amp;lt;/xs:sequence&amp;gt;
	        &amp;lt;/xs:complexType&amp;gt;
	      &amp;lt;/xs:element&amp;gt;
	    &amp;lt;/xs:sequence&amp;gt;
	  &amp;lt;/xs:complexType&amp;gt;

	  &amp;lt;xs:complexType name="AppointmentType"&amp;gt;
	    &amp;lt;xs:sequence&amp;gt;
	      &amp;lt;xs:element name="apptType" type="xs:string"/&amp;gt;
	      &amp;lt;xs:element name="apptDate" type="xs:string"/&amp;gt;
	      &amp;lt;xs:element name="owner" type="OwnerType"/&amp;gt;
	      &amp;lt;xs:element name="pet" type="PetType"/&amp;gt;
	    &amp;lt;/xs:sequence&amp;gt;
	  &amp;lt;/xs:complexType&amp;gt;

	  &amp;lt;xs:complexType name="OwnerType"&amp;gt;
	    &amp;lt;xs:sequence&amp;gt;
	      &amp;lt;xs:element name="firstName" type="xs:string"/&amp;gt;
	      &amp;lt;xs:element name="lastName" type="xs:string"/&amp;gt;
	      &amp;lt;xs:element name="address" type="AddressType"/&amp;gt;
	    &amp;lt;/xs:sequence&amp;gt;
	  &amp;lt;/xs:complexType&amp;gt;

	  &amp;lt;xs:complexType name="AddressType"&amp;gt;
	    &amp;lt;xs:sequence&amp;gt;
	      &amp;lt;xs:element name="addressLine1" type="xs:string"/&amp;gt;
	      &amp;lt;xs:element name="addressLine2" type="xs:string" minOccurs="0"/&amp;gt;
	      &amp;lt;xs:element name="city" type="xs:string"/&amp;gt;
	      &amp;lt;xs:element name="state" type="xs:string"/&amp;gt;
	      &amp;lt;xs:element name="zip" type="xs:string"/&amp;gt;
	      &amp;lt;xs:element name="zipExt" type="xs:string" minOccurs="0"/&amp;gt;
	    &amp;lt;/xs:sequence&amp;gt;
	  &amp;lt;/xs:complexType&amp;gt;

	  &amp;lt;xs:complexType name="PetType"&amp;gt;
	    &amp;lt;xs:sequence&amp;gt;
	      &amp;lt;xs:element name="name" type="xs:string"/&amp;gt;
	      &amp;lt;xs:element name="species" type="xs:string" minOccurs="0"/&amp;gt;
	    &amp;lt;/xs:sequence&amp;gt;
	  &amp;lt;/xs:complexType&amp;gt;

	  &amp;lt;xs:complexType name="BirthdayType"&amp;gt;
	    &amp;lt;xs:sequence&amp;gt;
	      &amp;lt;xs:element name="age" type="xs:int"/&amp;gt;
	      &amp;lt;xs:element name="birthday" type="xs:string"/&amp;gt;
	      &amp;lt;xs:element name="owner" type="OwnerType"/&amp;gt;
	      &amp;lt;xs:element name="pet" type="PetType"/&amp;gt;
	    &amp;lt;/xs:sequence&amp;gt;
	  &amp;lt;/xs:complexType&amp;gt;
	&amp;lt;/xs:schema&amp;gt;

  &lt;/pre&gt; 
  &lt;p&gt;
If we take a quick peek at the &lt;code&gt;main() &lt;/code&gt;method, we can see that we are generating the schema as follows:&lt;/p&gt; 
  &lt;pre&gt;	// specify where the generated XML schema will be created
	final File dir = new File("generated" + File.separator + &lt;strong&gt;"schema");&lt;/strong&gt;
	// specify a name for the generated XML instance document
	OutputStream os = new FileOutputStream("niceVet.xml");

	// create a JAXBContext for the PrintOrder class
	JAXBContext ctx = JAXBContext.newInstance(PrintOrder.class);
	// generate an XML schema from the annotated object model; create it
	// in the dir specified earlier under the default name, schema1.xsd
	ctx.generateSchema(new SchemaOutputResolver() {
		   @Override
		   public Result createOutput(String namespaceUri, String schemaName) throws IOException {
				return new StreamResult(new File(dir, schemaName));
		   }
	   });
&lt;/pre&gt; 
  &lt;p&gt;
To get the XML instance document, we first create some data, then we obtain a Marshaller from the &lt;code&gt;JAXBContext&lt;/code&gt; and marshal the Java content tree to XML:
&lt;/p&gt; 
  &lt;pre&gt;	// create some data
	PrintOrder order = new PrintOrder(EventUtil.getEvents());

		...
		
	// create a marshaller   
	Marshaller marshaller = ctx.createMarshaller();
	// the property JAXB_FORMATTED_OUTPUT specifies whether or not the
	// marshalled XML data is formatted with linefeeds and indentation
	marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
	// marshal the data in the Java content tree 
	// to the XML instance document niceVet.xml
	marshaller.marshal(order, os);		
&lt;/pre&gt; 
  &lt;h2&gt;Running the Sample Application&lt;/h2&gt; 
  &lt;p&gt;&lt;br /&gt;
  To run the sample application, &lt;a href="/CoreJavaTechTips/resource/java-to-schema.zip"&gt;download&lt;/a&gt; the sample code and unzip it. Launch NetBeans and select File -&amp;gt; Open Project. In the Open Project dialog box, navigate to the directory where you unzipped the sample code and select the folder java-to-schema. Select the Open as Main Project check box. Click Open Project Folder. Right-click the java-to-schema project and select Run Project. 
&lt;/p&gt; 
  &lt;h2&gt;Conclusion&lt;/h2&gt; 
  &lt;p&gt;  In this tip, you've seen how JAXB makes it easy to generate XML data to exchange with a business partner. The XML data your partner receives, however, may need a little tweaking in order to mesh with their system. In a future tip, you'll learn how to apply customizations to a supplied schema to get the Java object model - and content tree - you want.&lt;/p&gt; 
  &lt;h2&gt;References and Resources&lt;/h2&gt; 
  &lt;li&gt;&lt;a href="/CoreJavaTechTips/resource/java-to-schema.zip"&gt;Sample code&lt;/a&gt; for this tip&lt;/li&gt; 
  &lt;li&gt;&lt;a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnazf.html"&gt;The Java Tutorial&lt;/a&gt;.&lt;/li&gt; 
  &lt;li&gt;&lt;a href="http://weblogs.java.net/blog/kohsuke/"&gt;Kohsuke Kawaguchi's Blog&lt;/a&gt;. Kohsuke Kawaguchi is a staff engineer at Sun Microsystems, where among other projects he works on JAXB.&lt;/li&gt; 
  &lt;p&gt;Jennie Hall is a lead developer working in the financial sector.&lt;br /&gt; &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/corejavatechtips/~4/363387193" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://blogs.sun.com/CoreJavaTechTips/entry/exchanging_data_with_xml_and</feedburner:origLink></entry>
    <entry>
        <id>http://blogs.sun.com/CoreJavaTechTips/entry/where_s_the_state</id>
        <title type="html">Where's the State?</title>
        <author><name>dananourie</name></author>
        <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/corejavatechtips/~3/359582374/where_s_the_state" />
        <published>2008-08-08T09:52:57-07:00</published>
        <updated>2008-08-08T09:52:57-07:00</updated> 
        <category term="/Sun" label="Sun" />
        <category term="beans" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="java-se" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="learning" scheme="http://rollerweblogger.org/ns/tags/" />
        <summary type="html">What things have state? What things have values that
            can change? When and how can they change? Can the changes be
            observed? Who needs to observe changes in state? Read about these questions in this blog.</summary>
        <content type="html">&lt;p&gt;&amp;nbsp;from &lt;a href="http://weblogs.java.net/blog/timboudreau/"&gt;Tim Boudreau's Blog&lt;/a&gt;&lt;/p&gt; 
  &lt;p&gt;&amp;nbsp;Where's the state?  This is a small but useful question when
            deciding how a problem domain gets carved up into objects:
            What things have state? What things have values that
            can change? When and how can they change? Can the changes be
            observed? Who needs to observe changes in state?
        &lt;/p&gt; 
  &lt;p&gt;
            These questions make a good start for figuring out how to carve
            up a problem domain into objects, if you observe the principle
            &lt;i&gt;keep all related state in one place.&lt;/i&gt; I would go so far as to say
            that the majority of the appeal of Model-View-Controller (MVC)
            architecture is that it encourages you to keep state in one place.
        &lt;/p&gt; 
  &lt;p&gt;
            One big reason why statefulness matters is &lt;i&gt;threading&lt;/i&gt;.
            In practice, it is common to see designs where threading was an
            afterthought. This is
            to be expected. Concurrency is a not natural way for human
            beings to think.  So commonly a library is designed with
            no thought about threading;
            then a problem shows up which multi-threading can solve.
            Threading ends up being introduced into a codebase that was never
            designed for it. Retrofitting a threading model on something designed
            without one is very painful and sometimes impossible.
        &lt;/p&gt; 
  &lt;p&gt;
            Some threading models can be simple.  For example, any time you are
            writing a Swing application, and you have a method that can do long
            running I/O, the first line of that method should be
            &lt;/p&gt; 
  &lt;pre&gt;assert !EventQueue.isDispatchThread();&lt;/pre&gt;
            under all circumstances.
        
        
        
  
  
  &lt;p&gt;
            But keeping I/O off the event thread is the trivial case. Managing
            mutations to a model inside an application
            is a more complicated, less obvious problem.
        &lt;/p&gt; &lt;img height="266" align="right" width="400" src="http://weblogs.java.net/blog/timboudreau/archive/IMG_2949.png" alt="IMG_2949.png" /&gt;&lt;br /&gt; 
  &lt;p&gt;
            Any time you find yourself writing a setter (or more generally,
            mutator) method, it is worth asking yourself
            &lt;i&gt;Who does this piece of state really belong to? Am I putting
            state in the right place?&lt;/i&gt; Blindly following the beans pattern
            (add a getter/setter to whatever type you happen to be editing)
            can result in state being distributed all over objects in an
            application. The result will be harder to maintain, and if it
            has any lifespan, less and less maintainable
            over time.  Like entropy, or the
            &lt;a href="http://en.wikipedia.org/wiki/Broken_windows_theory"&gt;no
            broken windows theory&lt;/a&gt;, the more state is distributed all
            over the place, the more that will masquerade as design and
            make it okay for a programmer to further diffuse state throughout
            objects in the application.  Human beings can only 
            &lt;a href="http://en.wikipedia.org/wiki/Working_memory"&gt;hold so many
            things in their minds&lt;/a&gt; at a time.  The more state is diffused,
            the more things someone must pay attention to simultaneously to
            solve a problem in that code.
        &lt;/p&gt; 
  &lt;p&gt;&lt;a href="http://weblogs.java.net/blog/timboudreau/archive/2008/08/wheres_the_stat.html"&gt;Read the rest of this blog . . . &lt;/a&gt;&lt;/p&gt; 
  &lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/corejavatechtips/~4/359582374" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://blogs.sun.com/CoreJavaTechTips/entry/where_s_the_state</feedburner:origLink></entry>
    <entry>
        <id>http://blogs.sun.com/CoreJavaTechTips/entry/distributing_a_java_web_start</id>
        <title type="html">Distributing a Java Web Start Application via CD-ROM</title>
        <author><name>dananourie</name></author>
        <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/corejavatechtips/~3/341703746/distributing_a_java_web_start" />
        <published>2008-07-21T09:49:36-07:00</published>
        <updated>2008-07-21T09:49:36-07:00</updated> 
        <category term="/TechTip" label="TechTip" />
        <category term="java" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="java-se" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="jws" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="start" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="web" scheme="http://rollerweblogger.org/ns/tags/" />
        <summary type="html">Learn how to distribute a Java Web Start Application via a CD-ROM</summary>
        <content type="html">&lt;p&gt;by &lt;a href="http://today.java.net/pub/au/413"&gt;Luan O'Carroll&lt;/a&gt;&lt;/p&gt; 
  &lt;p&gt; &lt;/p&gt; 
  &lt;p&gt;Isn't &lt;a href="http://java.sun.com/products/javawebstart/"&gt;Java
Web Start&lt;/a&gt; (JWS) supposed to allow web-based distribution of
applications? So why would one want to distribute a Java Web Start
(JWS) application via CD-ROM? Well, for a number of reasons. For
larger applications, a complete installation can still be a major
download even with high-speed broadband. Secondly, not all desktops
are online, and not all can access the internet (for corporate
security reasons, for example). And, lastly, some people just like
CDs.&lt;/p&gt; 
  &lt;p&gt;A client company required that their application be distributed
worldwide, including to places where broadband coverage is sparse.
The application contains information about a large number of
products, including detailed drawings and diagrams. All this
information constituted a major part of the application, and a
complete installation including the JVM amounts to over 40 MB. In
addition to this, the company wanted to be able to distribute the
application on CDs at trade fairs and with promotional materials;
therefore, a CD-based distribution was required. Normally a CD
install is possible using either commercial or open source
installers, of which there are many. However, when an application
is to run with Java Web Start, it needs to be installed in a
specific location and not at the user's discretion, as is the norm
for installers.&lt;/p&gt; 
  &lt;p&gt;This article describes the steps involved in installing an
application that installs both from CD and the internet. The
installation process requires that:&lt;/p&gt; 
  &lt;ol&gt; 
    &lt;li&gt;The installed application must check for updates and integrate
with the JWS cache.&lt;/li&gt; 
    &lt;li&gt;The installation should work on a machine without an existing
or up-to-date version of Java.&lt;/li&gt; 
    &lt;li&gt;The installed application should not require an internet
connection.&lt;/li&gt; 
    &lt;li&gt;A installation must be easy to use and must provide a simple
user interface.&lt;/li&gt; 
  &lt;/ol&gt; 
  &lt;p&gt;Application installation is normally carried out with a generic
installer application, but a traditional install process would
effectively create a separate application that is unaware of JWS.
Each time an update is released, the user would have to download
and install the new version, whereas a JWS application only
downloads those components that have been updated, making the
process far more efficient and reliable. The article therefore also
describes a JWS application installer.&lt;/p&gt; 
  &lt;h3 id="jws-primer"&gt;JWS Primer&lt;/h3&gt; 
  &lt;p&gt;Java Web Start allows Java applications to be launched via a
link to a &lt;a href="http://java.sun.com/products/javawebstart/download-spec.html"&gt;JNLP&lt;/a&gt;
file. The JNLP file describes the main method or entry point into
the application and it references the resources used by the
application.&lt;/p&gt; 
  &lt;p&gt;When a JWS application is launched, the JVM tries to access the
required resources, updating them if necessary, and copies the file
to its cache. On subsequent attempts to launch the application, JWS
can check this cache and skip download of the resources. If the
client machine is offline or if the server cannot be contacted,
then JWS can run the application in an offline mode.&lt;/p&gt; 
  &lt;p&gt;If the JWS launch file (the JNLP) were placed on CD, JWS would
attempt to contact the server and download any new files. Obviously
this would defeat the purpose of distributing the files via CD if
the client machine is online. Instead, we need some way to update
the JWS cache as though the application had been previously loaded
by JWS.&lt;/p&gt; 
  &lt;h3 id="updating-the-jws-cache"&gt;Updating the JWS Cache&lt;/h3&gt; 
  &lt;p&gt;The Java 5 version of JWS includes a little known
&lt;code&gt;-import&lt;/code&gt; option that imports a JWS application into the
cache from a specified location.&lt;/p&gt; 
  &lt;p&gt;The CD image at this location is just a copy of what you would
normally place on the web server: the JNLP file, plus the .jars and
resources referred to by that JNLP file. If you use a servlet to
serve up the JNLP, then the CD image will need a self-contained
snapshot of the generated JNLP file.&lt;/p&gt; 
  &lt;p&gt;The CD image can thus be installed into the JWS cache by
calling:&lt;/p&gt; 
  &lt;p&gt;&lt;code&gt;&amp;lt;JAVA_HOME&amp;gt;/jre/bin/javaws -codebase
&amp;lt;CACHE_IMAGE&amp;gt; -import
&amp;lt;CACHE_IMAGE&amp;gt;/&amp;lt;XXXX&amp;gt;.jnlp&lt;/code&gt;&lt;/p&gt; 
  &lt;p&gt;where &lt;code&gt;&amp;lt;JAVA_HOME&amp;gt;&lt;/code&gt; is the root of the
(possible new) JVM, &lt;code&gt;&amp;lt;CACHE_IMAGE&amp;gt;&lt;/code&gt; is location of
the JWS application on the CD, and &lt;code&gt;&amp;lt;XXXX&amp;gt;&lt;/code&gt; is
the name of the application JNLP file. Later, we will see how this
command is automated and wrapped in a simple GUI.&lt;/p&gt; 
  &lt;p&gt;In installing the cached application, JWS conveniently prompts
the user to install desktop and menu shortcuts for starting the
application. Once the JWS install has been completed, we can again
call JWS to start the newly installed application.&lt;/p&gt; 
  &lt;p&gt;&lt;code&gt;&amp;lt;JAVA_HOME&amp;gt;/jre/bin/javaws -import
&amp;lt;CACHE_IMAGE&amp;gt;/&amp;lt;XXXX&amp;gt;.jnlp&lt;/code&gt;&lt;/p&gt; 
  &lt;p&gt;Again the CD is used, but this time JWS will use the
installation referred to by the JNLP file. If the machine is
connected to the internet, it will check for updates in the normal
way, as part of the process, and then start the application. If
there is no network connection, the application will launch as
delivered on CD.&lt;/p&gt; 
  &lt;p&gt;The next time the user starts the application they can use the
menu or desktop shortcuts and the CD will no longer be needed.
Alternatively, the user can start the application from a link on a
web page that points to the same URL/JNLP file combination; i.e., the
original version from the website.&lt;/p&gt; 
  &lt;h3 id="jvm-complications"&gt;JVM Complications&lt;/h3&gt; 
  &lt;p&gt;One gotcha in all of this is that the above commands require the
presence of a JVM, and in some rare cases this may not be installed
or may not be available by default on the system path and therefore
some extra measures are needed to locate a usable JVM. Furthermore,
when a user inserts the CD, the installation should begin, and the
installation should check for the presence of an existing JVM. The
process of checking for a JVM is then as follows:&lt;/p&gt; 
  &lt;ol&gt; 
    &lt;li&gt;Check for a JVM (for the installer).&lt;/li&gt; 
    &lt;li&gt;Install the JVM if not present.&lt;/li&gt; 
    &lt;li&gt;Launch the installer, showing the usual license
information.&lt;/li&gt; 
    &lt;li&gt;Install the target JVM (if required by the application and
different from 1 above).&lt;/li&gt; 
    &lt;li&gt;Import the JWS cache.&lt;/li&gt; 
    &lt;li&gt;Start the JWS application.&lt;/li&gt; 
  &lt;/ol&gt; 
  &lt;p&gt;Some further complications arise from the fact that the minimum
JVM for the JWS &lt;code&gt;-import&lt;/code&gt; option is Java 5, so even if a
JVM is present and usable for the application, this import option
will still require a fairly recent JVM. Secondly, the import process
takes some time and must complete before the application is
launched, and this sort of delayed execution is difficult to
achieve with many of the normal installers.&lt;/p&gt; 
  &lt;p&gt;Given these complications, it was necessary to build a custom
launch application that could perform these steps.&lt;/p&gt; 
  &lt;p&gt;&lt;a href="http://today.java.net/pub/a/today/2008/07/10/distributing-web-start-via-cd-rom.html"&gt;Read the rest of the article. &lt;/a&gt;&lt;br /&gt;&lt;/p&gt; 
  &lt;p&gt; &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/corejavatechtips/~4/341703746" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://blogs.sun.com/CoreJavaTechTips/entry/distributing_a_java_web_start</feedburner:origLink></entry>
    <entry>
        <id>http://blogs.sun.com/CoreJavaTechTips/entry/launch_java_applications_from_assembly</id>
        <title type="html">Launch Java Applications from Assembly Language Programs</title>
        <author><name>dananourie</name></author>
        <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/corejavatechtips/~3/325246548/launch_java_applications_from_assembly" />
        <published>2008-07-02T15:21:27-07:00</published>
        <updated>2008-07-02T15:21:27-07:00</updated> 
        <category term="/TechTip" label="TechTip" />
        <category term="assembly" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="java" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="language" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="programs" scheme="http://rollerweblogger.org/ns/tags/" />
        <summary type="html">Here I deal with the technique for
invoking Java programs from an ASM process through a demo
application that calls a Java method from assembly language code.</summary>
        <content type="html">&lt;p&gt;by &lt;a href="http://today.java.net/pub/au/491"&gt;Biswajit Sarkar&lt;/a&gt;&lt;/p&gt; 
  &lt;p&gt;&lt;a href="http://java.sun.com/j2se/1.4.2/docs/guide/jni"&gt;Java
Native Interface&lt;/a&gt; (JNI) is a mechanism that can be used to
establish communication between native language programs and the
Java virtual machine. The documentation for JNI and the technical
literature on JNI deal extensively with interactions between the
JVM and C/C++ code. The Java SDK even provides a utility to
generate a header file to facilitate calling C/C++ programs from
Java code. However, there is hardly any mention of Java and
&lt;i&gt;assembly language&lt;/i&gt; code working together. In an &lt;a href="http://today.java.net/pub/a/today/2006/10/19/invoking-assembly-language-from-java.html"&gt;
earlier article&lt;/a&gt; I showed how assembly language programs can be
called from Java applications. Here I deal with the technique for
invoking Java programs from an ASM process through a demo
application that calls a Java method from assembly language code.
The Java method brings up a Swing &lt;code&gt;JDialog&lt;/code&gt; to show that
it has, indeed, been launched.&lt;/p&gt; 
  &lt;p&gt; &lt;/p&gt; 
  &lt;h3 id="why-java-with-asm"&gt;Why Java with ASM?&lt;/h3&gt; 
  &lt;p&gt;JNI is essential to the implementation of Java, since the JVM
needs to interact with the native platform to implement some of its
functionality. Apart from that, however, use of Java classes can
often be an attractive supplement to applications written in other
languages, as Java offers a wide selection of APIs that makes
implementation of advanced functions very simple.&lt;/p&gt; 
  &lt;p&gt;Some time ago, I was associated with an application to collect
real-time data from a number of sources and save them in circular
buffers so that new data would overwrite old data once the buffer
got filled up. If a designated trigger event was sensed through a
digital input, a fixed number of data samples would be saved in the
buffers so that a snapshot of pre- and post-trigger data would be
available. The original application was written in assembly
language. After the application was used for a few months, it was
felt that it would be very useful to have the application mail the
snapshots to authorized supervisors whenever the trigger event
occurred. Of course, it would have been possible to write this
extension in assembly, but the team felt that in that particular
instance it was easier to write that extension in Java and hook it
up with the ASM program. As I had earlier worked with ASM-oriented
JNI, I knew this could be done and, indeed, the project was
implemented quickly and successfully.&lt;/p&gt; 
  &lt;p&gt;I am sure there are many legacy applications written in assembly
language that could benefit from such add-ons. However, it is not
only for old applications in need of renovation that JNI can prove
useful. Although it may seem unlikely to some of us, assembly
language is still used for writing selected portions of new
programs. In an &lt;a href="http://developers.sun.com/solaris/articles/x86_assembly_lang.html"&gt;
article&lt;/a&gt; published not very long ago, the author says, &amp;quot;I have
found that many of Sun's partners still use assembly language in
their products to ensure that hot code paths are as efficient as
possible. While compilers are able to generate much more efficient
code today, the resulting code still doesn't always compete with
hand-coded assembly written by an engineer that knows how to
squeeze performance out of each microprocessor instruction.
Assembly language remains a powerful tool for optimization,
granting the programmer greater control, and with judicious use can
enhance performance.&amp;quot; Clearly, in such &amp;quot;mixed language&amp;quot;
applications the ability to use Java with ASM can be useful.&lt;/p&gt; 
  &lt;p&gt;Note that the technique shown here can also be used to call Java
code from languages other than ASM. If &lt;code&gt;JInvoke&lt;/code&gt; is
rewritten as a .dll, code written in FORTRAN, for instance,
can link to it and call a Java method.&lt;/p&gt; 
  &lt;p&gt;I have used JNI with legacy ASM code in two ways:&lt;br /&gt;&lt;/p&gt; 
  &lt;ul&gt; 
    &lt;li&gt;Functional enhancement: Mail-enabling an existing ASM
application, as mentioned earlier.&lt;/li&gt; 
    &lt;li&gt;Interface enhancement: Adding interactive user interface
(mostly AWT, but some Swing as well).&lt;/li&gt; 
  &lt;/ul&gt; 
  &lt;p&gt;These enhanced applications have run on Windows 2000 and XP. The
Java versions used were 1.3, 1.4, and 1.6. In all cases the
applications worked smoothly.&lt;/p&gt; 
  &lt;p&gt;&lt;a href="http://today.java.net/pub/a/today/2007/10/04/launch-java-applications-from-assembly-language-programs.html"&gt;Read the rest of this article . . . &lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/corejavatechtips/~4/325246548" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://blogs.sun.com/CoreJavaTechTips/entry/launch_java_applications_from_assembly</feedburner:origLink></entry>
    <entry>
        <id>http://blogs.sun.com/CoreJavaTechTips/entry/add_logging_at_class_load</id>
        <title type="html">Add Logging at Class Load Time with Java Instrumentation</title>
        <author><name>dananourie</name></author>
        <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/corejavatechtips/~3/313089503/add_logging_at_class_load" />
        <published>2008-06-16T08:17:05-07:00</published>
        <updated>2008-06-16T08:17:05-07:00</updated> 
        <category term="/TechTip" label="TechTip" />
        <category term="java" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="logging" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="stack" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="trace" scheme="http://rollerweblogger.org/ns/tags/" />
        <summary type="html">This article shows how to implement&amp;nbsp; a Java agent, which
transparently adds entry and exit logging to all methods in all
your classes with the standard Java Logging API. Additionally,&amp;nbsp; the article demonstrates how to make the
original Hello World program behave like the logging Hello World by
manipulating the byte code when it is loaded.</summary>
        <content type="html">&lt;p&gt;by &lt;a href="http://today.java.net/pub/au/661"&gt;Thorbjørn Ravn Andersen&lt;/a&gt;&lt;/p&gt; 
  &lt;p&gt;When you're trying to analyze why a program failed, a very valuable
piece of information is what the program was actually doing when it
failed. In many cases, this can be determined with a stack trace, but
frequently that information is not available, or perhaps what you
need is information about the data that was being processed at the
time of failure.&lt;/p&gt; 
  &lt;p&gt;Traditionally this means using a logging framework like &lt;a href="http://logging.apache.org/log4j/"&gt;log4j&lt;/a&gt; or the &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/logging/package-summary.html"&gt;
Java Logging API&lt;/a&gt;, and then writing and maintaining all
necessary log statements manually. This is very tedious and error-prone, and well-suited for automation. Java 5 added the &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/instrument/Instrumentation.html"&gt;
Java Instrumentation&lt;/a&gt; mechanism, which allows you to provide
&amp;quot;Java agents&amp;quot; that can inspect and modify the byte code of the
classes as they are loaded.&lt;/p&gt; 
  &lt;p&gt;This article will show how to implement such a Java agent, which
transparently will add entry and exit logging to all methods in all
your classes with the standard Java Logging API. The example used
is Hello World:&lt;/p&gt; 
  &lt;pre&gt;&lt;code&gt;public class HelloWorld {
    public static void main(String args[]) {
        System.out.println("Hello World");
    }
}
&lt;/code&gt;
&lt;/pre&gt; 
  &lt;p&gt;And here is the same program with entry and exit log statements
added:&lt;/p&gt; 
  &lt;pre&gt;&lt;code&gt;import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;

public class LoggingHelloWorld {
    final static Logger _log = Logger.getLogger(LoggingHelloWorld.class.getName());

    public static void main(String args[]) {
        if (_log.isLoggable(Level.INFO)) {
            _log.info("&amp;gt; main(args=" + Arrays.asList(args) + ")");
        }
        System.out.println("Hello World");
        if (_log.isLoggable(Level.INFO)) {
            _log.info("&amp;lt; main()");
        }
    }
}
&lt;/code&gt;
&lt;/pre&gt; 
  &lt;p&gt;The default logger format generates output similar to:&lt;/p&gt; 
  &lt;pre&gt;&lt;code&gt;2007-12-22 22:08:52 LoggingHelloWorld main
INFO: &amp;gt; main(args=[])
Hello World
2007-12-22 22:08:52 LoggingHelloWorld main
INFO: &amp;lt; main()
&lt;/code&gt;
&lt;/pre&gt; 
  &lt;p&gt;Note that each log statement is printed on two lines. First, a
line with a time stamp, the provided log name, and the method in
which the call was made, and then a line with the provided log
text.&lt;/p&gt; 
  &lt;p&gt;The rest of the article will demonstrate how to make the
original Hello World program behave like the logging Hello World by
manipulating the byte code when it is loaded. The manipulation
mechanism is the Java Instrumentation API added in Java 5.&lt;/p&gt; 
  &lt;p&gt;&lt;a href="http://today.java.net/pub/a/today/2008/04/24/add-logging-at-class-load-time-with-instrumentation.html"&gt;Read the rest of this article&lt;/a&gt;. &lt;br /&gt;&lt;/p&gt; 
  &lt;p&gt; &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/corejavatechtips/~4/313089503" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://blogs.sun.com/CoreJavaTechTips/entry/add_logging_at_class_load</feedburner:origLink></entry>
    <entry>
        <id>http://blogs.sun.com/CoreJavaTechTips/entry/source_code_analysis_using_java</id>
        <title type="html">Source Code Analysis Using Java 6 APIs</title>
        <author><name>dananourie</name></author>
        <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/corejavatechtips/~3/294477855/source_code_analysis_using_java" />
        <published>2008-05-20T12:06:52-07:00</published>
        <updated>2008-05-20T12:06:52-07:00</updated> 
        <category term="/TechTip" label="TechTip" />
        <category term="6" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="analysis" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="compiler" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="java-se" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="jdk" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="processing" scheme="http://rollerweblogger.org/ns/tags/" />
        <summary type="html">In this article, you'll explore the features of each of these APIs
and go on to develop a simple demo application that verifies
certain Java coding rules on a set of source code files supplied as
input.</summary>
        <content type="html">&lt;p&gt;
by &lt;a href="http://today.java.net/pub/au/638"&gt;Seema Richard&lt;/a&gt;, &lt;a href="http://today.java.net/pub/au/647"&gt;Deepa Sobhana&lt;/a&gt;

&lt;/p&gt;&lt;p&gt;
Have you ever thought of how tools like Checkstyle or FindBugs perform a static code analysis, or how Integrated Development Environments (IDEs) like NetBeans or Eclipse execute quick code fixes or find the exact references of a field declared in your code? In many cases, IDEs have their own APIs to parse the source code and generate a standard tree structure, called an Abstract Syntax Tree (AST) or &amp;quot;parse tree,&amp;quot; which can be used for deeper analysis of the source elements. The good news is that it is now possible to accomplish the said tasks plus a lot more with the help of three new APIs introduced in Java as part of the Java Standard Edition 6 release. The APIs that might be of interest to developers of Java applications that need to perform source code analysis are the Java Compiler API (JSR 199), the Pluggable Annotation Processing API (JSR 269), and the Compiler Tree API.
&lt;/p&gt;&lt;p&gt;
In this article, we explore the features of each of these APIs and go on to develop a simple demo application that verifies certain Java coding rules on a set of source code files supplied as input. This utility also shows the coding violation messages as well as the location of violated source code as output. Consider a simple Java class that overrides the equals() method of the Object class. The coding rule to be verified is that every class that implements the equals() method should also override the hashcode() method with the proper signature. You can see that the TestClass class below does not define the hashcode() method, even though it has the equals() method.
&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre&gt;public class TestClass implements Serializable {&lt;br /&gt; int num;&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt;  public boolean equals(Object obj) {&lt;br /&gt;        if (this == obj)&lt;br /&gt;                return true;&lt;br /&gt;        if ((obj == null) || (obj.getClass() != this.getClass()))&lt;br /&gt;                return false;&lt;br /&gt;        TestClass test = (TestClass) obj;&lt;br /&gt;        return num == test.num;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Let us go on and analyze this class as part of the build process
with the help of these three APIs.&lt;/p&gt;
&lt;h3 id="invoking-the-compiler-from-code-the-java-compiler-api"&gt;Invoking the Compiler from Code: The Java Compiler API&lt;/h3&gt;
&lt;p&gt;We all use the &lt;code&gt;javac&lt;/code&gt; command-line tool for
compiling Java source files to class files. Then why do we need an
API to compile Java files? Well, the answer is quite simple: as the
name describes, this new standard API lets us invoke the compiler
from our own Java applications; i.e., you can programmatically
interact with the compiler and thereby make compilation part of
application-level services. Some typical uses of this API are
listed below.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;The compiler API helps application servers to minimize the time
taken to deploy applications, for example, by avoiding the overhead
of using an external compiler for compiling the servlet sources
generated from the JSP pages.&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Developer tools like IDEs and code analyzers can invoke the
compiler from within the editor or build tools that significantly
reduce the compile time.&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;The Java compiler classes are packaged under the
&lt;code&gt;javax.tools&lt;/code&gt; package. The &lt;code&gt;ToolProvider&lt;/code&gt;
class of this package provides a method called
&lt;code&gt;getSystemJavaCompiler()&lt;/code&gt; that returns an instance of
some class that implements the &lt;code&gt;JavaCompiler&lt;/code&gt; interface.
This compiler instance can be used to create a compilation task
that will perform the actual compilation. The Java source files to
be compiled will be then passed to the compilation task. For this,
the compiler API provides a file manager abstraction called
&lt;code&gt;JavaFileManager&lt;/code&gt;, which allows Java files to be
retrieved from various sources, such as the file system, databases, memory, and so on. In this sample, we use &lt;code&gt;StandardFileManager&lt;/code&gt;, a
file manager based on &lt;code&gt;java.io.File&lt;/code&gt;. The standard file
manager can be acquired by calling the
&lt;code&gt;getStandardFileManager()&lt;/code&gt; method of the
&lt;code&gt;JavaCompiler&lt;/code&gt; instance. The code snippet for the
above-mentioned steps is shown below:&lt;/p&gt;

&lt;pre&gt;//Get an instance of java compiler&lt;br /&gt;JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();&lt;br /&gt;&lt;br /&gt;//Get a new instance of the standard file manager implementation&lt;br /&gt;StandardJavaFileManager fileManager = compiler.&lt;br /&gt;        getStandardFileManager(null, null, null);&lt;br /&gt;        &lt;br /&gt;// Get the list of java file objects, in this case we have only &lt;br /&gt;// one file, TestClass.java&lt;br /&gt;Iterable compilationUnits1 = &lt;br /&gt;        fileManager.getJavaFileObjectsFromFiles(&amp;quot;TestClass.java&amp;quot;);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;A diagnostic listener can be optionally passed to the
&lt;code&gt;getStandardFileManager()&lt;/code&gt; method to produce diagnostic
reports of any non-fatal problems. In this code snippet, we pass
&lt;code&gt;null&lt;/code&gt; values, since we are not collecting the
diagnostics from the tool. For details of the other parameters
passed to these methods, please refer to the &lt;a href="http://java.sun.com/javase/6/docs/api/javax/tools/JavaCompiler.html"&gt;
Java 6 API.&lt;/a&gt; The &lt;code&gt;getJavaFileObjectsfromFiles()&lt;/code&gt;
method of the &lt;code&gt;StandardJavaFileManager&lt;/code&gt; returns all the
&lt;code&gt;JavaFileObject&lt;/code&gt; instances that correspond to the
supplied Java source files.&lt;/p&gt;&lt;p&gt;&lt;a href="http://today.java.net/pub/a/today/2008/04/10/source-code-analysis-using-java-6-compiler-apis.html"&gt;Read the rest of this article&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/corejavatechtips/~4/294477855" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://blogs.sun.com/CoreJavaTechTips/entry/source_code_analysis_using_java</feedburner:origLink></entry>
    <entry>
        <id>http://blogs.sun.com/CoreJavaTechTips/entry/swingset3_nimbus_and_java_se</id>
        <title type="html">Nimbus Look and Feel in Java SE 6 Update 10 Beta</title>
        <author><name>dananourie</name></author>
        <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/corejavatechtips/~3/277021556/swingset3_nimbus_and_java_se" />
        <published>2008-04-24T09:41:41-07:00</published>
        <updated>2008-05-27T10:21:44-07:00</updated> 
        <category term="/TechTip" label="TechTip" />
        <category term="10" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="java_se" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="nimbus" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="swing" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="swingset3" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="update" scheme="http://rollerweblogger.org/ns/tags/" />
        <summary type="html">Discover the changes and improvements included in Nimbus in the Java SE 6 Update 10.</summary>
        <content type="html">&lt;p&gt;&lt;i&gt;By Ethan Nicholas&lt;/i&gt; &lt;br /&gt;&lt;/p&gt;
&lt;!-- BEGIN SEPARATOR --&gt;
&lt;div class="hr"&gt;&lt;hr /&gt;&lt;/div&gt;
&lt;!-- END SEPARATOR --&gt;
&lt;p&gt;When the venerable &lt;a href="http://java.sun.com/docs/books/tutorial/figures/uiswing/lookandfeel/MetalLAF.gif"&gt;Metal 
look and feel&lt;/a&gt; for Swing first debuted, its main aesthetic
competition was the &lt;a href="http://upload.wikimedia.org/wikipedia/en/9/90/Am_windows95_desktop.png"&gt;Windows 
95 interface&lt;/a&gt;.  Given the state of graphical user interfaces a decade
ago, Metal was an attractive and elegant alternative to the other common
interfaces of the time.&lt;/p&gt;
&lt;p&gt;The updated &lt;a href="http://java.sun.com/docs/books/tutorial/figures/uiswing/lookandfeel/OceanLAF.gif"&gt;Ocean&lt;/a&gt; 
theme in Java SE 5 helped to keep Metal a viable choice up to the
present day, but it's time for Swing's cross-platform look and feel to get an
overhaul.&lt;/p&gt;
&lt;p&gt;Enter the &lt;a href="https://nimbus.dev.java.net/"&gt;Nimbus Look and Feel&lt;/a&gt;.  A
brand new, modern look and feel based on &lt;a href="http://javadesktop.org/articles/synth/"&gt;Synth&lt;/a&gt;, Nimbus provides a
polished look to applications which choose to use it.  And because Nimbus is
drawn entirely using Java 2D vector graphics, rather than static bitmaps, it's
tiny (only 56KB!) and can be rendered at arbitrary resolutions.&lt;/p&gt;
&lt;!-- BEGIN G20 COMPONENT V.9 --&gt;
&lt;div class="g20 g20r1 g20v9"&gt;
&lt;div class="g20w1" style="width: 665px;"&gt;

&lt;div class="g20w2"&gt;
&lt;div style="background: transparent url(http://java.sun.com/developer/technicalArticles/javase/java6u10/images/metal.gif) no-repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 654px; height: 400px;" class="imgbox imgcenter"&gt;&lt;img height="400" border="0" width="654" style="display: none;" alt="SwingSet3 in Metal" src="http://java.sun.com/developer/technicalArticles/javase/java6u10/images/metal.gif" /&gt;&lt;/div&gt;
&lt;div class="small" style="text-align: center;"&gt;Figure 3: SwingSet3 in Metal&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;/div&gt;
&lt;!-- END G20 COMPONENT V.9 --&gt;
&lt;span class="sp20"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;!-- BEGIN G20 COMPONENT V.9 --&gt;
&lt;div class="g20 g20r1 g20v9"&gt;
&lt;div class="g20w1" style="width: 665px;"&gt;

&lt;div class="g20w2"&gt;
&lt;div style="background: transparent url(http://java.sun.com/developer/technicalArticles/javase/java6u10/images/nimbus.gif) no-repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 654px; height: 400px;" class="imgbox imgcenter"&gt;&lt;img height="400" border="0" width="654" style="display: none;" alt="SwingSet3 in Nimbus" src="http://java.sun.com/developer/technicalArticles/javase/java6u10/images/nimbus.gif" /&gt;&lt;/div&gt;
&lt;div class="small" style="text-align: center;"&gt;Figure 4: SwingSet3 in Nimbus&lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;/div&gt;
&lt;!-- END G20 COMPONENT V.9 --&gt;   
&lt;span class="sp10"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;p&gt;For compatibility reasons, Metal is still the default Swing look and feel, but
updating applications to use Nimbus couldn't be simpler.  It only takes a single
line of code:&lt;/p&gt;
&lt;!-- BEGIN PC1 COMPONENT V.2 --&gt;
&lt;div class="pc1 pc1v2"&gt;
&lt;div class="pc1w1"&gt;&lt;div class="pc1w2"&gt;&lt;div class="pc1w3 cornerBL"&gt;&lt;div class="pc1w4"&gt;   
&lt;pre&gt;UIManager.setLookAndFeel(&amp;quot;com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel&amp;quot;);&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;!-- END PC1 COMPONENT V.2 --&gt;
&lt;p&gt;You can also force Nimbus to be the default look and feel by specifying
&lt;code&gt;-Dswing.defaultlaf=com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel&lt;/code&gt;.
on the  command line.  A more permanent way to set the property is to add&lt;/p&gt;
&lt;!-- BEGIN PC1 COMPONENT V.2 --&gt;
&lt;div class="pc1 pc1v2"&gt;
&lt;div class="pc1w1"&gt;&lt;div class="pc1w2"&gt;&lt;div class="pc1w3 cornerBL"&gt;&lt;div class="pc1w4"&gt;   
&lt;pre&gt;swing.defaultlaf=com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;!-- END PC1 COMPONENT V.2 --&gt;
&lt;p&gt;to the file &lt;code&gt;&amp;lt;JAVA_HOME&amp;gt;/lib/swing.properties&lt;/code&gt;.  You will have to create
the swing.properties file if it does not already exist.&lt;/p&gt;
&lt;p&gt;For further reading about Nimbus, take a look at &lt;a href="http://java.sun.com/javase/downloads/ea/6u10/nimbus.jsp"&gt;the Nimbus early
access page.&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/corejavatechtips/~4/277021556" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://blogs.sun.com/CoreJavaTechTips/entry/swingset3_nimbus_and_java_se</feedburner:origLink></entry>
    <entry>
        <id>http://blogs.sun.com/CoreJavaTechTips/entry/jslider_appearance_improvements</id>
        <title type="html">JSlider Appearance Improvements</title>
        <author><name>dananourie</name></author>
        <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/corejavatechtips/~3/264207223/jslider_appearance_improvements" />
        <published>2008-04-04T13:34:02-07:00</published>
        <updated>2008-04-04T13:34:02-07:00</updated> 
        <category term="/TechTip" label="TechTip" />
        <category term="code_samples" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="java" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="java_se" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="tips" scheme="http://rollerweblogger.org/ns/tags/" />
        <summary type="html">Learn how you can change any of the three
  defaults in JSlider: the direction of the scrollbar, and whether tick marks should
  appear, and what to show next to them.</summary>
        <content type="html">&lt;p&gt;by John Zukowsi &lt;/p&gt;
&lt;p&gt;The &lt;code&gt;JSlider&lt;/code&gt; component is a popular component for selecting a value from
  a numerical range. While some people might think of a &lt;code&gt;JScrollBar&lt;/code&gt; for
  numerical input, that really serves the purpose of scrolling around a
  viewport, not data input. By default, the input range of a &lt;code&gt;JSlider&lt;/code&gt; is
  &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;100&lt;/code&gt;, with an initial value of &lt;code&gt;50&lt;/code&gt;. You can change any of the three
  defaults, the direction of the scrollbar, and whether tick marks should
  appear and what to show next to them. You'll look at all of these
  possible features.&lt;/p&gt;

&lt;p&gt;First off is the basic &lt;code&gt;JSlider&lt;/code&gt;, just creating it and adding it to a
  screen, preserving all the defaults. Nothing fancy here, but builds the
  basics for what to build on for the remaining examples. The &lt;code&gt;SliderSample&lt;/code&gt;
  program actually has four sliders; two horizontal and two vertical.&lt;/p&gt;
  
&lt;pre&gt;import javax.swing.*;
import java.awt.*;

public class SliderSample {
  public static void main(final String args[]) {
    Runnable runner = new Runnable() {
      public void run() {
        JFrame frame = new JFrame("Sample Sliders");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JSlider js1 = new JSlider();
        JSlider js2 = new JSlider();
        js2.setInverted(true);
        JSlider js3 = new JSlider(JSlider.VERTICAL);
        js3.setPaintLabels(true);
        JSlider js4 = new JSlider(JSlider.VERTICAL);
        js4.setInverted(true);
        frame.add(js1, BorderLayout.NORTH);
        frame.add(js2, BorderLayout.SOUTH);
        frame.add(js3, BorderLayout.WEST);
        frame.add(js4, BorderLayout.EAST);
        frame.setSize(300, 200);
        frame.setVisible(true);
      }
    };
    EventQueue.invokeLater(runner);
  }
}&lt;/pre&gt;
&lt;p&gt;Compiling and running the program shows a screen with four sliders on
  it. While you cannot tell from the screen, the ones in the &lt;code&gt;EAST&lt;/code&gt; and
  &lt;code&gt;SOUTH&lt;/code&gt; regions of the &lt;code&gt;BorderLayout&lt;/code&gt; are actually inverted. So, for the
  horizontal sliders, &lt;code&gt;0&lt;/code&gt; is on the left for the top one and &lt;code&gt;100&lt;/code&gt; is on the
  left for the inverted bottom one. For the vertical sliders, &lt;code&gt;0&lt;/code&gt; is on
  the bottom for the left one and on the top for the inverted right one.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blogs.sun.com/CoreJavaTechTips/resource/first.png" width="300" height="200" /&gt;&lt;/p&gt;
&lt;p&gt;By default, there is no indicator on the slider for what its value is.
  Instead, you would just ask the slider its value at some later time, or
  attach a listener to the control to be told the value upon movement.
  Ignoring the import lines, here is a listener that reports the value
  when the user stops dragging the slider knob. The &lt;code&gt;getValueIsAdjusting()&lt;/code&gt;
  method reports true while the user still has the knob selected with the
  mouse.&lt;/p&gt;
&lt;pre&gt; public class SliderChangeListener implements ChangeListener {
    public void stateChanged(ChangeEvent changeEvent) { 
      Object source = changeEvent.getSource();
      JSlider theJSlider = (JSlider)source;
      if (!theJSlider.getValueIsAdjusting()) { 
        System.out.println ("Slider changed: " + theJSlider.getValue());
      } 
    } 
  } &lt;/pre&gt;
&lt;p&gt;Not showing a value on the slider makes it somewhat useless, though you
  can certainly work with it where the exact value doesn't matter and the
  user can see results based upon relative position. To help in making the
  slider more useful, you can show tick marks with labels. There are two
  classes of tick marks, major and minor ones. Major and minor are just
  classifications for the length and positioning of the lines drawn for
  the tick mark, where major tick marks are longer than minor ones. To
  enable tick marks, you have to call &lt;code&gt;setPaintTicks(true)&lt;/code&gt;, and, say how
  far apart the tick marks should appear. By default, the spacing is
  zero, resulting in no tick marks drawn, even when paint ticks is true.
  Adding the appropriate lines to the earlier program will show tick
  marks on the top and left sliders, with major ticks every 10 and
  minor ones at the midpoint between them.&lt;/p&gt;
&lt;pre&gt;  
  js1.setPaintTicks(true);
  js1.setMajorTickSpacing(10);
  js1.setMinorTickSpacing(5);

  js3.setPaintTicks(true);
  js3.setMajorTickSpacing(10);
  js3.setMinorTickSpacing(5); &lt;/pre&gt;

&lt;p&gt;&lt;img src="http://blogs.sun.com/CoreJavaTechTips/resource/ticks.png" width="300" height="200" /&gt;&lt;/p&gt;
&lt;p&gt;Showing tick marks certainly helps, but showing labels makes things
  most useful. Adding &lt;code&gt;setPaintLabels(true)&lt;/code&gt; calls will show labels at
  the major tick marks. By default, the labels are their respective
  cardinal numbers, so with a major tick mark at value &lt;code&gt;0&lt;/code&gt;, the associated
  label is string &amp;quot;0,&amp;quot; and so on for &amp;quot;10,&amp;quot;, &amp;quot;20,&amp;quot;, all the way to &amp;quot;100.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blogs.sun.com/CoreJavaTechTips/resource/labels.png" width="400" height="300" /&gt;&lt;/p&gt;

&lt;p&gt;Instead of showing the cardinal numbers, you can provide a label table:
  &lt;code&gt;setLabelTable(Dictionary labels)&lt;/code&gt;. In the table, you would map integer
  values to different components to show as the label. In generic-speak,
  that would be &lt;code&gt;Dictionary&amp;lt;Integer, JComponent&amp;gt;&lt;/code&gt;, though the method
  isn't explicitly defined to require the key-value pair to be such.
  Typically, the mapping is &lt;code&gt;Integer&lt;/code&gt; object to &lt;code&gt;JLabel&lt;/code&gt;. As the Swing
  component set predates the &lt;code&gt;Collections&lt;/code&gt; framework, the method takes
  a &lt;code&gt;Dictionary&lt;/code&gt;, not a &lt;code&gt;Map&lt;/code&gt;, so remember to use a &lt;code&gt;Hashtable&lt;/code&gt; for the label
  table. Here's one label table setup that shows text roughly every
  eleven positions. At the ends are colored diamond icons, instead of
  text, to help show that that are labels not text strings that can go
  at each position.&lt;/p&gt;

&lt;pre&gt;
   Hashtable&amp;lt;Integer, JComponent&amp;gt; table =
      new Hashtable&amp;lt;Integer, JComponent&gt;();
    table.put(new Integer(0), new JLabel(
      new DiamondIcon(Color.RED)));
    table.put(new Integer(11), new JLabel("Eleven"));
    table.put(new Integer(22), new JLabel("Twenty-Two"));
    table.put(new Integer(33), new JLabel("Thirty-Three"));
    table.put(new Integer(44), new JLabel("Fourty-Four"));
    table.put(new Integer(55), new JLabel("Fifty-Five"));
    table.put(new Integer(66), new JLabel("Sixty-Six"));
    table.put(new Integer(77), new JLabel("Seventy-Seven"));
    table.put(new Integer(88), new JLabel("Eighty-Eight"));
    table.put(new Integer(100), new JLabel(
      new DiamondIcon(Color.BLACK)));
     js4.setLabelTable(table);
     js4.setPaintLabels(true); &lt;/pre&gt;
&lt;p&gt;&lt;img src="http://blogs.sun.com/CoreJavaTechTips/resource/eleven.png" width="400" height="300" /&gt;&lt;/p&gt;
&lt;p&gt;The definition for the &lt;code&gt;DiamondIcon&lt;/code&gt; will be shown at end with the
  full class definition.&lt;/p&gt;
&lt;p&gt;Notice that the slider in the eastern area of the screen was used for
  the label table. Had the southern slider been used instead, the label
  text would overlap. Keep that in mind when you work with slider labels.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blogs.sun.com/CoreJavaTechTips/resource/elevenBottom.png" width="400" height="300" /&gt;&lt;/p&gt;

&lt;p&gt;One last thing you can do to affect the display. You can hide the
  track that the knob slides on. Just call the &lt;code&gt;setPaintTrack(&lt;/code&gt;) method,
  with a setting of false. Here, the bottom slider has its track hidden.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blogs.sun.com/CoreJavaTechTips/resource/hidden.png" width="400" height="300" /&gt;&lt;/p&gt;
&lt;p&gt;There isn't that much more you can do to customize the look of the
  &lt;code&gt;JSlider&lt;/code&gt;, but as you've seen there is certainly quite a bit you can do.
  From adding tick marks and labels to hiding the track, you've seen the
  most significant features. If you want to get really fancy, consider
  creating a custom UI for the component and show it as a dial instead of
  a line. Sounds like an idea for a future tip.&lt;/p&gt;
&lt;p&gt;Here's the final and complete source used to generate the samples. You
  will need to work backwards to remove code sections to return back to
  the first screen shot.&lt;/p&gt;
&lt;pre&gt;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.util.Hashtable;

public class SliderSample {
  public static void main(final String args[]) {
    Runnable runner = new Runnable() {
      public void run() {
        JFrame frame = new JFrame("Sample Sliders");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ChangeListener listener = new SliderChangeListener();
        JSlider js1 = new JSlider();
        js1.setPaintLabels(true);
        js1.setPaintTicks(true);
        js1.setMajorTickSpacing(10);
        js1.setMinorTickSpacing(5);
        js1.addChangeListener(listener);
        JSlider js2 = new JSlider();
        js2.setInverted(true);
	js2.setPaintTrack(false);
        js2.addChangeListener(listener);
        JSlider js3 = new JSlider(JSlider.VERTICAL);
        js3.setPaintLabels(true);
        js3.setPaintTicks(true);
        js3.setMajorTickSpacing(10);
        js3.setMinorTickSpacing(5);
        js3.addChangeListener(listener);
        JSlider js4 = new JSlider(JSlider.VERTICAL);
        js4.setInverted(true);
        Hashtable&amp;lt;Integer, JComponent&amp;gt; table =
          new Hashtable&amp;lt;Integer, JComponent&amp;gt;();
        table.put(new Integer(0), new JLabel(
          new DiamondIcon(Color.RED)));
        table.put(new Integer(11), new JLabel("Eleven"));
        table.put(new Integer(22), new JLabel("Twenty-Two"));
        table.put(new Integer(33), new JLabel("Thirty-Three"));
        table.put(new Integer(44), new JLabel("Fourty-Four"));
        table.put(new Integer(55), new JLabel("Fifty-Five"));
        table.put(new Integer(66), new JLabel("Sixty-Six"));
        table.put(new Integer(77), new JLabel("Seventy-Seven"));
        table.put(new Integer(88), new JLabel("Eighty-Eight"));
        table.put(new Integer(100), new JLabel(
          new DiamondIcon(Color.BLACK)));
        js4.setLabelTable(table);
        js4.setPaintLabels(true);
        js4.addChangeListener(listener);
        frame.add(js1, BorderLayout.NORTH);
        frame.add(js2, BorderLayout.SOUTH);
        frame.add(js3, BorderLayout.WEST);
        frame.add(js4, BorderLayout.EAST);
        frame.setSize(400, 300);
        frame.setVisible(true);
      }
    };
    EventQueue.invokeLater(runner);
  }
  public static class SliderChangeListener implements ChangeListener {
    public void stateChanged(ChangeEvent changeEvent) { 
      Object source = changeEvent.getSource();
      JSlider theJSlider = (JSlider)source;
      if (!theJSlider.getValueIsAdjusting()) { 
        System.out.println ("Slider changed: " + theJSlider.getValue());
      } 
    } 
  }
  public static class DiamondIcon implements Icon {
    private Color color;
    private boolean selected;
    private int width;
    private int height;
    private Polygon poly;
    private static final int DEFAULT_WIDTH = 10;
    private static final int DEFAULT_HEIGHT = 10;

    public DiamondIcon(Color color) {
      this(color, true, DEFAULT_WIDTH, DEFAULT_HEIGHT);
    }

    public DiamondIcon(Color color, boolean selected) {
      this(color, selected, DEFAULT_WIDTH, DEFAULT_HEIGHT);
    }

    public DiamondIcon(Color color, boolean selected,
        int width, int height) {
      this.color = color;
      this.selected = selected;
      this.width = width;
      this.height = height;
      initPolygon();
    }

    private void initPolygon() {
      poly = new Polygon();
      int halfWidth = width / 2;
      int halfHeight = height / 2;
      poly.addPoint(0, halfHeight);
      poly.addPoint(halfWidth, 0);
      poly.addPoint(width, halfHeight);
      poly.addPoint(halfWidth, height);
    }

    public int getIconHeight() {
      return height;
    }

    public int getIconWidth() {
      return width;
    }

    public void paintIcon(Component c, Graphics g, int x, int y) {
      g.setColor(color);
      g.translate(x, y);
      if (selected) {
        g.fillPolygon(poly);
      } else {
        g.drawPolygon(poly);
      }
      g.translate(-x, -y);
    }
  }
}

&lt;/pre&gt;
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/corejavatechtips/~4/264207223" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://blogs.sun.com/CoreJavaTechTips/entry/jslider_appearance_improvements</feedburner:origLink></entry>
    <entry>
        <id>http://blogs.sun.com/CoreJavaTechTips/entry/using_generics_with_wildcards_and</id>
        <title type="html">Using Generics With Wildcards and Extends</title>
        <author><name>dananourie</name></author>
        <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/corejavatechtips/~3/249176750/using_generics_with_wildcards_and" />
        <published>2008-03-10T16:56:23-07:00</published>
        <updated>2008-06-26T14:08:57-07:00</updated> 
        <category term="/TechTip" label="TechTip" />
        <category term="extends" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="generics" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="java" scheme="http://rollerweblogger.org/ns/tags/" />
        <summary type="html">Learn how to use generics with Wildcards and Extends.</summary>
        <content type="html">&lt;p&gt;By John Zukowski

&lt;/p&gt; 
  &lt;p&gt;Java 2 Platform, Standard Edition 5.0 (J2SE 5.0) introduced
generics to the Java programming language and platform. In the
simplest case and typical usage, generics allow for the
identification of what you want to store in a collection. So instead
of saying that your program has a &lt;code&gt;List&lt;/code&gt; of

&lt;code&gt;Objects&lt;/code&gt;, you can now specify that you have a
&lt;code&gt;List&lt;/code&gt; of &lt;code&gt;String&lt;/code&gt; objects or some other class
type. Then, if you accidentally try to add something to the
&lt;code&gt;List&lt;/code&gt; that is of the wrong type, the compiler notifies
you of the error and it can be fixed at compile time, rather than
having to wait until you run the program and the program reaches the
point in code where the fetch operation produces a runtime casting
exception. &lt;/p&gt; 
  &lt;p&gt;This brings up a second benefit of generics. Iterators now become
typesafe. The &lt;code&gt;next()&lt;/code&gt; method of the

&lt;code&gt;Iterator&lt;/code&gt; interface returns the typesafe version of the
next element of the collection.

&lt;/p&gt; 
  &lt;p&gt;But this is not a tip about the use of generics, which a &lt;a href="http://java.sun.com/developer/JDCTechTips/2005/tt0315.html#1" title="2005 tip"&gt;2005 Core Java Technologies Tip&lt;/a&gt; explained. Most
people don't fully understand the use of the &lt;code&gt;extends&lt;/code&gt;
keyword when using generics. A typical example shown to explain the
use of &lt;code&gt;extends&lt;/code&gt; has to do with drawing shapes. Instead,
this tech tip will use an example that uses Swing components so that
you do not have to create extra new classes. In a very limited case,
the class hierarchy for Swing button components is shown here, with
&lt;code&gt;Object&lt;/code&gt; as the real root: &lt;/p&gt; 
  &lt;pre&gt;Component
|- Container
   |- JComponent
      |- AbstractButton
         |- JButton
         |- JMenuItem
            |- JCheckBoxMenuItem
            |- JMenu
            |- JRadioButtonMenuItem
         |- JToggleButton
            |- JCheckBox
            |- JRadioButton
&lt;/pre&gt; 
  &lt;p&gt;One thing that all &lt;code&gt;AbstractButton&lt;/code&gt; subclasses share
in common is a &lt;code&gt;getText()&lt;/code&gt; method. So in the spirit of
generics, you can define a method that takes a &lt;code&gt;List&lt;/code&gt; of
&lt;code&gt;AbstractButton&lt;/code&gt; items and return a &lt;code&gt;List&lt;/code&gt; of
the &lt;code&gt;String&lt;/code&gt; labels of those buttons. Here's the first
version of such a method:


&lt;/p&gt; 
  &lt;pre&gt;  public static List&amp;lt;String&amp;gt; getLabels(List&amp;lt;AbstractButton&amp;gt; list) {
    List&amp;lt;String&amp;gt; labelList = new ArrayList&amp;lt;String&amp;gt;(list.size());
    for (AbstractButton button: list) {
      labelList.add(button.getText());
    }
    return labelList;
  }
&lt;/pre&gt; 
  &lt;p&gt;And here is how you might use the method. First, define a
&lt;code&gt;List&lt;/code&gt; of &lt;code&gt;AbstractButton&lt;/code&gt; types, fill it up,
and call the method:


&lt;/p&gt; 
  &lt;pre&gt;  List&amp;lt;AbstractButton&amp;gt; buttonList =
      new ArrayList&amp;lt;AbstractButton&amp;gt;();
  buttonList.add(new JButton("Hello"));
  buttonList.add(new JCheckBox("World"));
  buttonList.add(new JRadioButton("Hola"));
  buttonList.add(new JMenuItem("Mundo"));

  List&lt;string&gt; labels = getLabels(buttonList);
  System.out.println(labels);
&lt;/string&gt;&lt;/pre&gt; 
  &lt;p&gt;&amp;quot;Hola, Mundo&amp;quot; is the Spanish translation of &amp;quot;Hello, World,&amp;quot;
according to Google. The results of the &lt;code&gt;println()&lt;/code&gt; call
is as follows:

&lt;/p&gt; 
  &lt;pre&gt;[Hello, World, Hola, Mundo]
&lt;/pre&gt; 
  &lt;p&gt;With a &lt;code&gt;List&lt;/code&gt; of &lt;code&gt;AbstractButtons&lt;/code&gt;,
everything functions fine, but this breaks down when the
&lt;code&gt;List&lt;/code&gt; is of something else, specifically a subclass. One
would logically think that with a &lt;code&gt;List&lt;/code&gt; of
&lt;code&gt;JButton&lt;/code&gt; items, everything would work fine, because
&lt;code&gt;JButton&lt;/code&gt; is a subclass of &lt;code&gt;AbstractButton&lt;/code&gt;.
Shouldn't you be able to call

&lt;code&gt;getLabels(List&amp;lt;AbstractButton&amp;gt;)&lt;/code&gt; with a
&lt;code&gt;List&lt;/code&gt; of a subclass of &lt;code&gt;AbstractButton&lt;/code&gt;?

&lt;/p&gt; 
  &lt;pre&gt;  List&amp;lt;JButton&amp;gt; buttonList = ...
  // ... Fill list ...
  List&amp;lt;String&amp;gt; labels = getLabels(buttonList);

&lt;/pre&gt; 
  &lt;p&gt;Well, that isn't the case. Because this is a compile-time check,
and because the definition of &lt;code&gt;getLabels()&lt;/code&gt; is defined to
accept only an &lt;code&gt;AbstractButton List&lt;/code&gt;, you cannot pass
anything else to it. The compilation-time error message follows:

&lt;/p&gt; 
  &lt;pre&gt;GetList.java:13: getLabels(java.util.List&amp;lt;javax.swing.AbstractButton&amp;gt;)
  in GetList cannot be applied to (java.util.List&amp;lt;javax.swing.JButton&amp;gt;)

    List&amp;lt;String&amp;gt; labels = getLabels(buttonList);
                          ^
1 error

&lt;/pre&gt; 
  &lt;p&gt;And this is where the &lt;code&gt;extends&lt;/code&gt; keyword comes in
handy. Instead of defining the &lt;code&gt;getLabels()&lt;/code&gt; method to
accept only an &lt;code&gt;AbstractButton&lt;/code&gt; list, define it to accept
any &lt;code&gt;List&lt;/code&gt; of &lt;code&gt;AbstractButton&lt;/code&gt; subclasses:


&lt;/p&gt; 
  &lt;pre&gt;    public static List&amp;lt;String&amp;gt; getLabels(
      List&amp;lt;? extends AbstractButton&amp;gt; list) {
&lt;/pre&gt; 
  &lt;p&gt;The wildcard &lt;code&gt;?&lt;/code&gt; here says that the method doesn't
care what the exact class type is, as long as it is a subclass of
&lt;code&gt;AbstractButton&lt;/code&gt;. Here's a complete example that puts all
the pieces together:


&lt;/p&gt; 
  &lt;pre&gt;import java.util.*;
import javax.swing.*;

public class GetList {
  public static void main(String args[]) {
    List&amp;lt;JButton&amp;gt; buttonList =
      new ArrayList&amp;lt;JButton&amp;gt;();
    buttonList.add(new JButton("Hello"));
    buttonList.add(new JButton("World"));
    buttonList.add(new JButton("Hola"));
    buttonList.add(new JButton("Mundo"));

    List&lt;string&gt; labels = getLabels(buttonList);
    System.out.println(labels);

  }

  public static List&amp;lt;String&amp;gt; getLabels(
        List&amp;lt;? extends AbstractButton&amp;gt; list) {
    List&amp;lt;String&amp;gt; labelList = new ArrayList&amp;lt;String&amp;gt;(list.size());
    for (AbstractButton button: list) {
      labelList.add(button.getText());
    }
    return labelList;
  }
}

&lt;/string&gt;&lt;/pre&gt; 
  &lt;p&gt;Now, when you are defining your own classes and methods with
generics and are thinking of accepting an abstract class as the
generic argument, or any superclass, remember to use wildcards so
that the same method works best with subclasses too.

&lt;/p&gt; 
  &lt;p&gt;For more information on generics, see two earlier tutorials by
Gilad Bracha: &lt;a href="http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf"&gt;a 2004
tutorial (PDF)&lt;/a&gt; and the generics lesson in the online &lt;a href="http://java.sun.com/docs/books/tutorial/extra/generics/"&gt;Java
Tutorial&lt;/a&gt;.


&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/corejavatechtips/~4/249176750" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://blogs.sun.com/CoreJavaTechTips/entry/using_generics_with_wildcards_and</feedburner:origLink></entry>
    <entry>
        <id>http://blogs.sun.com/CoreJavaTechTips/entry/getting_to_know_boxlayout</id>
        <title type="html">Getting to Know BoxLayout</title>
        <author><name>dananourie</name></author>
        <link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/corejavatechtips/~3/234035888/getting_to_know_boxlayout" />
        <published>2008-02-12T15:37:33-08:00</published>
        <updated>2008-02-12T15:37:33-08:00</updated> 
        <category term="/TechTip" label="TechTip" />
        <category term="applications" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="desktop" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="gui" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="java" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="layout" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="managers" scheme="http://rollerweblogger.org/ns/tags/" />
        <category term="swing" scheme="http://rollerweblogger.org/ns/tags/" />
        <summary type="html">Learn how and when to use the BoxLayout manager, plus how to make use of the Box struts and glue components.</summary>
        <content type="html">&lt;p&gt;One of the standard layout managers that come with the Java platform is
  &lt;code&gt;BoxLayout&lt;/code&gt;. This allows you to layout a single row or column of components
  in a container. This may sound like a not-