You are receiving this e-mail because you elected to receive e-mail from Sun Microsystems, Inc. To update your communications preferences, please see the link at the bottom of this message. We respect your privacy and post our privacy policy prominently on our Web site http://sun.com/privacy/

Please do not reply to the mailed version of the newsletter, this alias is not monitored. Feedback options are listed in the footer for both content and delivery issues.
  Welcome to the Enterprise Java Technologies Tech Tips.
Enterprise Java Technologies
TECHNICAL TIPS
January 28, 2006
View this issue as simple text
In this Issue
 
Welcome to the Enterprise Java Technologies Tech Tips for January 28, 2006. Here you'll get tips on using enterprise Java technologies and APIs, such as those in Java 2 Platform, Enterprise Edition (J2EE) and Java Platform, Enterprise Edition 5 (Java EE 5).

This issue covers:

» What's New in JAXB 2.0
» Monitoring Web Services

These tips were developed using an open source implementation of Java EE 5 called GlassFish. You can download GlassFish from the GlassFish Project page.

You can download the sample archive for the JAXB tip at http://java.sun.com/developer/EJTechTips/download/ttjan2006-jaxb20.zip.

Any use of this code and/or information below is subject to the license terms.

See the Subscribe/Unsubscribe note at the end of this newsletter to subscribe to Tech Tips that focus on technologies and products in other Java platforms.

WHAT'S NEW IN JAXB 2.0
 
by Kim LiChong

Java Architecture for XML Binding, JAXB, is a technology that simplifies the use of XML content in Java programming language applications. JAXB does this by specifying a binding between an XML document and JavaBeans technology components, based on the XML document's XSD schema. Previous Enterprise Java Technologies Tech Tips covered XML Serialization with JAXB and using JAXB with RelaxNG. Both tips used JAXB 1.0, which is packaged with the Java Web Services Developer Pack (Java WSDP) 1.6.

JAXB 2.0, JSR 222, includes a number of important improvements to JAXB 1.0. Some of these are:

  • Support for all W3C XML Schema features. JAXB 1.0 did not specify bindings for some of the W3C XML Schema features.This support will be fully provided in the FCS release, but is not yet complete in the current Early Access release.

  • Support for binding Java-to-XML, with the addition of the javax.xml.bind.annotation package to control this binding. JAXB 1.0 specified the mapping of XML Schema-to-Java, but not Java-to-XML Schema.

  • A significant reduction in the number of generated schema-derived classes.

  • Additional validation capabilities through the JAXP 1.3 validation APIs.

  • Smaller runtime libraries.

This tip demonstrates two of these improvements: validation (as a part of marshalling and unmarshalling) using the JAXP validation APIs, and Java-to-Schema binding.

You'll find the example code for this tip in a downloadable archive. To run the examples, you'll need the most current Early Access 3 version of the JAXB 2.0 Reference Implementation. The Early Access 3 version of the JAXB 2.0 Reference Implementation is also packaged in Java WSDP 2.0.

Unmarshalling and Marshalling with the JAXP 1.3 Validation Schema

One of the enhancements in JAXB 2.0 is the additional validation capabilities provided through the use of the JAXP 1.3 validation APIs. Let's examine this by looking at unmarshalling and marshalling in JAXB 2.0 using the JAXP 1.3 validation schema. Using JAXB, a Java application can unmarshal an XML instance document into Java content objects, optionally validating the source XML document before generating the Java content objects. A Java application can also use JAXB to marshal Java content objects into XML instance documents.

Before an XML document can be unmarshalled, you need to bind the schema for the XML document into a set of Java interfaces and classes that represents the schema. You then compile the interfaces and classes. The example in this tip uses a purchase order schema, po.xsd. This is the same schema that is used in the JAXB samples packaged in Java WSDP 1.6. The JAXB samples are described in the Java Web Services Developer Pack 1.6 Tutorial. If you examine the po.xsd schema, note especially the restrictions specified for the quantity element and the partNum attribute:

   <xsd:element name="quantity">
      <xsd:simpleType>
      <xsd:restriction base="xsd:positiveInteger">
         <xsd:maxExclusive value="100"/>
       </xsd:restriction>
              
      <xsd:attribute name="partNum" type="SKU" 
        use="required"/>

The quantity cannot exceed 100 and the part number must have an SKU type.

As is the case in JAXB 1.0, you bind the schema in JAXB 2.0 using the XML binding compiler (xjc). You then compile the generated interfaces and classes using the javac command. In the example archive, the binding and compilation steps are provided as ant tasks in a build file, build.xml.

After binding and compiling, you can unmarshal the XML document. The XML document used in this tip, po.xml, is a purchase order document that contains some information that violates the restrictions specified in the po.xsd schema. In particular, one of the items in the purchase order specifies a quantity greater than 100 and a partNum attribute that does not correspond to the type SKU.

     <item partNum="002" >
        <productName>Reliving the Ordeal</productName>
        <quantity>150</quantity>
        <USPrice>11.99</USPrice>
     </item>

Unmarshalling in JAXB 2.0 is much the same as unmarshalling in JAXB 1.0. You first create a JAXBContext object that provides an entry point to the JAXB API. Then you create an Unmarshaller object that controls the process of unmarshalling.

   JAXBContext jc = JAXBContext.newInstance( "techtip" );
   Umarshaller u = jc.createUnmarshaller();  

Where JAXB 2.0 differs from JAXB 1.0 in the unmarshalling process is validation. In JAXB 1.0 you could validate source data against an associated schema as part of the unmarshalling process by specifying:

   unmarshaller.setValidating(true);

Validation capabilities have been expanded in JAXB 2.0 through the use of the JAXP 1.3 Schema Validation Framework. To use this enhanced level of validation, you first create an instance of the SchemaFactory for the W3C XML Schema 1.0 language:

   SchemaFactory sf = SchemaFactory.newInstance(
      javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);

The SchemaFactory instance is used to create a new JAXP 1.3 Schema object:

   Schema schema = sf.newSchema(new File("po.xsd"));

Then you use the setSchema method to identify the JAXP 1.3 Schema object (in this case, the po.xsd) that should be used to validate subsequent unmarshal operations. If you pass null into this method, it disables validation.

   u.setSchema(schema);

The application has the option of customizing validation error handling by overriding the default event handler. It does this using the method call setEventHandler(ValidationEventHandler).

The previous approach to unmarshalling by JAXB 1.0, called "structural unmarshalling", is more rigid in regard to invalid XML content. If JAXB 1.0 detects a structural inconsistency that it is unable to recover from, it aborts the unmarshal process and throws an UnmarshalException. For example, it can rigidly give up unmarshalling if it encounters an unexpected element or attribute.

JAXB 2.0, by comparison, allows for more flexible unmarshalling. Flexible unmarshalling enables greater predictability in unmarshalling invalid XML content. JAXB 2.0 unmarshals xml content by element name, rather than strictly by the position of the element within a content model.

Here is how to specify your own custom event handler:

   u.setEventHandler(new DefaultValidationEventHandler());  

The custom validation event handler must implement the ValidationEventHandler interface and the method handleEvent. The boolean return value should be set to true if the JAXB Provider attempts to continue the current unmarshal, validate, or marshal operation after handling this warning or error. The return value should be set to false if the provider terminates the current operation with the appropriate UnmarshalException, ValidationException, or MarshalException. Note that the default ValidationHandler in JAXB 2.0 always returns true (provided that the handleEvent is not overridden). Here is an example of a custom event handler:

   public class MyValidationEventHandler implements 
    ValidationEventHandler{
     
      public boolean handleEvent(ValidationEvent ve) {            
        if (ve.getSeverity()==ve.FATAL_ERROR ||  
                               ve .getSeverity()==ve.ERROR){
            ValidationEventLocator  locator = ve.getLocator();
            //print message from valdation event
            System.out.println("Message is " + ve.getMessage());
            //output line and column number
            System.out.println("Column is " + 
                  locator.getColumnNumber() + 
                  " at line number " + locator.getLineNumber());
         }
         return true;
       }
    
   }

The JAXB specification mandates that all provider implementations report validation errors when errors are encountered. However, the implementation does not have to stop processing the data. A JAXB implementation can successfully unmarshal an invalid XML document even if the XML document is not valid.

After po.xml is unmarshalled, you can manipulate the marshalled objects like any other Java objects. For example, to display the shipTo address, do the following:

   JAXBElement<?> poElement = 
   JAXBElement<?>)u.unmarshal( 
      new FileInputStream( "po.xml" ) );
   PurchaseOrderType po = (
      PurchaseOrderType)poElement.getValue();
   USAddress address = po.getShipTo();            

To marshal content back to an XML file, you perform the same steps as in JAXB 1.0. After creating a JAXBContext object (as shown earlier for unmarshalling), you create a Marshaller object that controls the process of marshalling. The following code snippet, for example, creates a Marshaller to marshal content to a file named incorrectpo.xml:

   Marshaller m = jc.createMarshaller();
        m.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, 
              Boolean.TRUE );
        OutputStream os = new FileOutputStream( 
              "incorrectpo.xml" );
        m.marshal(po, os);

The property JAXB.FORMATTED.OUTPUT controls whether the Marshaller formats the resulting XML data with line breaks and indentation.

Although not shown in the example code for this tip, JAXB 2.0 supports validation at marshal time (as well as at unmarshal time). JAXB 1.0 provided for validation only at unmarshal time, and also supported on-demand validation of a JAXB content tree. Marshal-time validation was added because of web services. A web service processing model should be lax in reading in data, and strict when writing it out. To meet that model, JAXB 2.0 added marshal-time validation to ensure that users do not invalidate an xml document if they modify the document in JAXB form.

Generating XML from Java Classes with Java-to-Schema Binding

As mentioned previously, JAXB 1.0 specified the mapping of XML Schema-to-Java, but not the mapping of Java-to-XML Schema. JAXB 2.0 completes this by specifying the mapping from Java-to-XML Schema. In addition, JAXB 2.0 relies on the use of annotations as specified in "A Metadata Facility for the Java Programming Language", JSR 175, to control this binding.

This tip demonstrates how to use JAXB 2.0 to generate an XML file from existing Java classes and then printing the contents of the generated XML file to the console. The two classes used are Scientist and Person, where the Person object is encapsulated in the Scientist object.

A class maps to either an XML Schema complex type or an XML Schema simple type. The XML Schema type is derived based on the mapping of JavaBean properties and fields contained in the class. In JAXB 2.0, annotations are used to specify to the Java-to-Schema binding framework how to treat the Java classes. The annotation @Xmltype is used for a top-level value class, mapping it to a complex schema type:

   @XmlType       
   public class Person  {
            
      private String name;
       private int age;
   .....

When a top-level class is annotated with the @XmlRootElement annotation, the value of the class is represented as an XML root element in an XML document:

   @XmlRootElement
        
   public class Scientist  {
    
       private Person person;    
       private String researchInstitute; 
       private Collection publications;
   ...

These annotations specify that the Scientist object is the root element, and the Person object is of Xmltype. There are many other annotation types defined including XmlAttribute, XmlElement, and XmlSchema. The full list is available in the javax.xml.bind.annotation API documentation.

The annotations and default mapping are designed to enable the classes to be mapped to schema with minimal changes to existing code. The default mapping is specified in terms of default annotations that are considered to apply to a program element even if the annotations are not specified. For more detail, see section 8.12 in the final JAXB 2.0 specification. In the code example for this tip, the class Person does need not be annotated with @XmlType. Without the annotation, the JavaBeans object is still mapped to the correct type (you can test this by commenting out the annotation). You should specify a customizing annotation when the default binding is not sufficient. For example, you should use @XmlAttribute to specify a customizing annotation for the default binding of a field or property to an attribute.

With the Java-to-XML Schema mapping in place, you can marshal Java objects without providing an XMLSchema. First create a JavaContext object, specifying the pertinent context path. In this example, the Scientist Java object (which requires the creation of a Person object) provides the context path. Then you pass the JavaContext object to the marshaller.

   JAXBContext context = 
      JAXBContext.newInstance(Scientist.class);
   Marshaller m = context.createMarshaller();
   m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

After creating the necessary Scientist and Person objects with appropriate properties, you can perform any operation using the marshalled XML file. For example you can print the XML contents to the console:

   Scientist scientist = js.getScientist();
   m.marshal(scientist, System.out);

For more information about JAXB 2.0, see the JAXB 2.0 project page.

Running the Sample Code

A sample package accompanies this tip that demonstrates the techniques covered in the tip. To install and run the sample:

  1. If you don't have Java 2 Platform, Standard Edition (J2SE) 5.0 installed, download and install it from the J2SE 5.0 downloads page. JAXB 2.0 requires J2SE 5.0 because it uses some of the new language features in J2SE 5.0 such as annotations.

  2. Download and install latest JAXB 2.0 bundle from JAXB 2.0 Project downloads page.

  3. Download the sample archive for the tip. Extract the downloaded archive contents to the <JAXB_RI>/samples directory, where <JAXB_RI> is the directory where you installed JAXB 2.0 RI EA 3. You should now see the newly extracted directory as <JAXB_RI>/samples/techtip. For example, if you installed the EA3 release on a Windows machine at C:\Sun\, then your newly created directory should be at C:\Sun\jaxb-ri-20050622\samples\techtip.

    It is important to extract this zip file to this directory because build.xml file for the tip depends on the directory structure defined in the JAXB 2.0 EA3 bundle. The classpath and execute properties are already defined in the build.xml file, so that you can compile and execute the appropriate targets.

    To execute the unmarshalling and marshalling example, perform the following steps:

  4. Navigate to the <JAXB_RI>/samples/techtip directory, and execute the following command:
          ant compile
    
    This generates and compiles the Java classes from the po.xsd schema, and the example Java classes. Note that there is no ant binary packaged with JAXB 2.0 package. If you have Java WSDP 1.6 installed, you can use the ant binary located in the <JWSDP_HOME>/apache-ant/bin directory (where <JWSDP_HOME> is where you installed Java WSDP 1.6). Or you can download ant from the apache web site.

  5. Unmarshal the po.xml document, validating it with the JAXP 1.3 Schema Validation Framework, and then marshal it. To do that, execute the following command:
       
          ant run-validate
    
    The marshalling operation will generate the incorrectpo.xml file. The output should include the following:
         Message is cvc-type.3.1.3: The value '150' of element 
         'quantity' is not valid.
         Column is 31 at line number 28
            Bugsy Brown
            99 9th Avenue
            New York, NY 12345
            US
            
         Still able to marshal invalid document
    
    To execute the Java to Schema binding example, execute the following command:
       ant run-javaToSchema 
    
    The output should include the following:
       <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
       <scientist>
           <person>
               <name>Linus Pauling</name>
               <age>93</age>
               <sex>Male</sex>
           </person>
           <publications xmlns:
           xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           xsi:type="xs:string">Respect for vitamin C
           </publications>
           <publications xmlns:
           xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           xsi:type="xs:string">The Nature of the Chemical Bond
           </publications>
       </scientist>
    

About the Author

Kim LiChong is a Member of Technical Staff in the Java Web Services Performance Engineering Group at Sun Microsystems. His interests include XML parsing performance, and is one of the authors of the StAX 1.0 White Paper: Streaming APIs for XML Parsers. He also is a co-owner of xmltest, a microbenchmark used to measure XML parsing performance. For more information about xmltest, see the xmltest project page.

Back to Top

MONITORING WEB SERVICES
 
by Satish Viswanatham and Nazrul Islam

One of the new technologies introduced in J2EE 1.4 was J2EE Management, JSR 77. J2EE Management provided a standard management model for exposing and accessing management information, operations, and attributes for J2EE components. Together with technologies such as Java Management Extensions (JMX), J2EE Management provides developers with a vendor-neutral way of managing and monitoring resources in J2EE servers. (For more information about JMX, see the Tech Tip Understanding JMX Technology.) One of the resources that can be managed and monitored through these technologies is a web service. However, in general, tools have not taken advantage of these technologies to make web services easy to manage and monitor. One recent exception is GlassFish, an open source application server implementation of Java EE 5. In GlassFish, web services are first class objects, that can be easily monitored and managed. In this tip, you'll have the opportunity to try out these GlassFish features to monitor a web service.

Getting Started

Let's start by doing some initial setup. If you haven't already done so, download GlassFish from the GlassFish Downloads page. Then set the following environment variables:

  • GLASSFISH_HOME. This should point to where you installed GlassFish (for example C:\Sun\AppServer)

  • ANT_HOME. This should point to where ant is installed. Ant is included in the GlassFish bundle that you downloaded. (In Windows, it's in the lib\ant subdirectory.) You can also download Ant from the Apache Ant Project page. The example requires Apache ant 1.6.5.

  • JAVA_HOME. This should point to the location of JDK 5.0 on your system.

Also, add the ant location to your PATH environment variable.

This tip uses the web service named Calculator that was described in the Tech Tip Developing Web Services Using JAX-WS. If you don't have that web service deployed, follow the instructions in that Tech Tip for building and deploying the web service.

Web Services as First Class Objects

Most J2EE-compliant application servers list the deployed archives, that is, ear, war, jar and rar files. However they don't typically list deployed web services -- at least, not in a way that makes it easy to find all the deployed web service endpoints in a domain. To manage web services in these application servers, a user has to examine the deployment descriptors for the web services. By comparison, all web service endpoints are discovered and shown distinctly in GlassFish. All web services are listed in the GlassFish management console, in addition to other enterprise resources such as Enterprise JavaBeans (EJB) components and servlets. This makes it easier to manage web services.

To demonstrate, start the GlassFish Application Server by entering the following command:

     <GLASSFISH_HOME>\bin\asadmin start-domain domain1

where <GLASSFISH_HOME> is the directory in which you installed GlassFish

You should see the following in response:

   Starting Domain domain1, please wait.
   Log redirected to 
   <GLASSFISH_HOME>/domains/domain1/logs/server.log.
   Domain domain1 started.

After GlassFish starts, open the Administration Console by pointing your browser to http://localhost:4848. Then login with the appropriate administrator user name and password (the default username is admin, and the default password is adminadmin). This will open a Welcome screen. In the Welcome screen expand the Applications folder in the left navigation, and select Web Services. This will open a Web Services window. You should see an entry for the Calculator service. Notice that the entry displays basic information about the service such as the application the service belongs to (jaxws-webservice-web), the associated WSDL file (CalculatorService.wsdl), and how the service is implemented (servlet).

Web Services window

If you click on the Calculator endpoint, you should see detailed information about that web service, such as its endpoint URI, the name of the module in which the web service is packaged, and a list of associated descriptor files.

General - Calculator window

Monitoring a Web Service

GlassFish has the capability to track and graphically show operational statistics for web services, such as the number of requests per second, average response time, and throughput. You can enable monitoring for individual web services in an application. There are three monitoring levels that are supported:

  • LOW. Monitors response times, throughput, and the total number of requests and faults.

  • HIGH. Performs the same monitoring as LOW and enables Message Trace (Content Visualization).

  • OFF. No monitoring data is collected.

If monitoring is turned on for a web service (by specifying LOW or HIGH), monitoring is enabled for all operations performed by that web service.

To display monitoring information, click on the Monitor tab in the window that displays detailed information about a web service. By default, monitoring is OFF, so you'll initially see a message that says "No Statistic is available for this web service." You can click the Configuration tab in the window to turn on monitoring. To start collecting statistics and messages, set the monitoring level to HIGH and click Save.

Calculator - Monitoring Configuration window

Now send a SOAP request to the Calculator web service by following the instructions in the "Run the Client" section of the "Developing Web Services Using JAX-WS" Tech Tip. You should see output similar to the following:

   runtest-jaxws:
        [echo] Executing appclient with client class as 
        client.JAXWSClient
        [exec]  Retrieving port from the service 
        com.techtip.jaxws.sample.CalculatorService@162522b
        [exec]  Invoking add operation on the calculator port
        [exec]  Adding : 0 + 10 = 10
        [exec]  Adding : 1 + 10 = 11
        [exec]  Adding : 2 + 10 = 12
        [exec]  Adding : 3 + 10 = 13
        [exec]  Adding : 4 + 10 = 14
        [exec]  Adding : 5 + 10 = 15
        [exec]  Adding : 6 + 10 = 16
        [exec]  Adding : 7 + 10 = 17
        [exec]  Adding : 8 + 10 = 18
        [exec]  Adding : 9 + 10 = 19
 
   all: 
   BUILD SUCCESSFUL
   Total time: 6 seconds

If you click on the Statistics tab of the Monitor window, you should see the following statistics collected for the Calculator web service.

Calculator - Monitoring Statistics window

The same could also be obtained from the following CLI command (the command should be entered on one line):

   <GLASSFISH_HOME>\bin\asadmin get -m --port 4848 
   "server.applications.jaxws-webservice-web.Calculator.
   webservice-endpoint.*"

In response, you should see output similar to the following:

   server.applications.jaxws-webservice-web.Calculator.
   webservice-endpoint.averageresponsetime-count = 3
   server.applications.jaxws-webservice-web.Calculator.
   webservice-endpoint.averageresponsetime-description 
   = Average response time measured in milliseconds
   server.applications.jaxws-webservice-web.Calculator.
   webservice-endpoint.averageresponsetime-lastsampletime 
   = 1136835037801
   server.applications.jaxws-webservice-web.Calculator.
   webservice-endpoint.averageresponsetime-name 
   = AverageResponseTime
   ...

Notice that the results include more information than shown in the Administration console. For instance, the CLI results include a description of each statistic and its unit of measurement.

Using Message Trace

If the monitoring level is HIGH, you can display the last n messages for a web service endpoint (the default is 25). The messages are kept in memory for each server instance. The messages show details of SOAP requests, as well as response and HTTP header information. To display the messages, click the Messages tab of the Monitor window.

Calculator - Messages window

You can view additional details for a message by clicking on the message in the Messages window. The displayed details also includes a button to request the details in XML format.

About the Author

Satish Viswanatham is an engineer in Sun's Application Server team. He has worked on J2EE technology since its inception. Satish is currently actively involved in making the J2EE Application Server a Service-Oriented Architecture(SOA) engine. He has experience in JDBC, as well as EJB Transactions and Management technologies. Prior to working at Sun, Satish worked on pre-J2EE application servers such as the Kiva Application Server and Netscape Web Server. He has applied for 3 patents during his tenure at Sun.

Nazrul Islam is a senior member of the Application Server's Administration and Management team. He has worked in the J2EE group for the last five years. He was a key contributor to the Application Server Enterprise Edition design and implementation. During his tenure at Sun, Nazrul has applied for 8 patents.

Back to Top

Rate and Review
Tell us what you think of the content of this page.
Excellent   Good   Fair   Poor  
Comments:
If you would like a reply to your comment, please submit your email address:
Note: We may not respond to all submitted comments.
Comments? Send your feedback on the Tech Tips: http://developers.sun.com/contact/feedback.jsp?category=newslet

Subscribe to the following newsletters for the latest information about technologies and products in other Java platforms:
  • Core Java Technologies Tech Tips. Get tips on using core Java technologies and APIs, such as those in the Java 2 Platform, Standard Edition (J2SE).
  • Wireless Developer Tech Tips. Get tips on using wireless Java technologies and APIs, such as those in the Java 2 Platform, Micro Edition (J2ME).
You can subscribe to these and other Java technology developer newsletters or manage your current newsletter subscriptions on the Sun Developer Network Subscriptions page

IMPORTANT: Please read our Terms of Use, Privacy, and Licensing policies:
http://www.sun.com/share/text/termsofuse.html
http://www.sun.com/privacy/
http://developer.java.sun.com/berkeley_license.html

ARCHIVES: You'll find the Enterprise Java Technologies Tech Tips archives at:
http://java.sun.com/developer/EJTechTips/index.html

© 2006 Sun Microsystems, Inc. All Rights Reserved. For information on Sun's trademarks see: http://sun.com/suntrademarks
Java, J2EE, J2SE, J2ME, and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries.