Enterprise Java Technologies Tech Tips Tips, Techniques, and Sample Code 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 reference implementation of Java EE 5 called GlassFish. You can download GlassFish from the GlassFish Project page (https://glassfish.dev.java.net/). You can view this issue of the Tech Tips on the Web at http://java.sun.com/developer/EJTechTips/2006/tt0128.html. 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 at http://developers.sun.com/dispatcher.jsp?uid=6910008. 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, (http://java.sun.com/webservices/jaxb/index.jsp) 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 (http://java.sun.com/developer/EJTechTips/2004/tt1221.html#1) and using JAXB with RelaxNG (http://java.sun.com/developer/EJTechTips/2005/tt0524.html#2). 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 (http://www.jcp.org/en/jsr/detail?id=222), includes a number of important improvements to JAXB 1.0. Some of these are: o 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. o.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. o A significant reduction in the number of generated schema-derived classes. o Additional validation capabilities through the JAXP 1.3 validation APIs. o 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 (http://java.sun.com/developer/EJTechTips/download/ttjan2006-jaxb20.zip). To run the examples, you'll need the most current Early Access 3 version of the JAXB 2.0 Reference Implementation (https://jaxb.dev.java.net/jaxb20-ea3/). The Early Access 3 version of the JAXB 2.0 Reference Implementation is also packaged in Java WSDP 2.0 (http://java.sun.com/webservices/downloads/webservicespack.html). 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 (http://java.sun.com/webservices/docs/1.6/tutorial/doc/index.html). If you examine the po.xsd schema, note especially the restrictions specified for the quantity element and the partNum attribute: 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. Reliving the Ordeal 150 11.99 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 (http://java.sun.com/developer/EJTechTips/2005/tt1025.html#1). 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 (http://www.jcp.org/en/jsr/detail?id=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 (http://download.java.net/jdk6/docs/api/javax/xml/bind/annotation/package-summary.html). 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 (http://jcp.org/aboutJava/communityprocess/pfd/jsr222/index.html). 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 (https://jaxb.dev.java.net/). 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 (http://java.sun.com/j2se/1.5.0/download.jsp). 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 (https://jaxb.dev.java.net/ri-download.html). 3. Download the sample archive (http://java.sun.com/developer/EJTechTips/download/ttjan2006-jaxb20.zip) for the tip. Extract the downloaded archive contents to the /samples directory, where is the directory where you installed JAXB 2.0 RI EA 3. You should now see the newly extracted directory as /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 /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 /apache-ant/bin directory (where is where you installed Java WSDP 1.6). Or you can download ant from the apache web site (http://ant.apache.org/bindownload.cgi). 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: Linus Pauling 93 Male Respect for vitamin C The Nature of the Chemical Bond 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 (http://java.sun.com/performance/reference/whitepapers/StAX-1_0.pdf). 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 (https://xmltest.dev.java.net/). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MONITORING WEB SERVICES Satish Viswanatham and Nazrul Islam One of the new technologies introduced in J2EE 1.4 was J2EE Management, JSR 77 (http://www.jcp.org/en/jsr/detail?id=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" (http://java.sun.com/developer/EJTechTips/2005/tt0222.html#1).) 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 (http://java.sun.com/javaee/glassfish/getit.jsp). Then set the following environment variables: o GLASSFISH_HOME. This should point to where you installed GlassFish (for example C:\Sun\AppServer) o 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 (http://ant.apache.org/). The example requires Apache ant 1.6.5. o 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" (http://java.sun.com/developer/EJTechTips/2005/tt1220.html#1). 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: \bin\asadmin start-domain domain1 where is the directory in which you installed GlassFish You should see the following in response: Starting Domain domain1, please wait. Log redirected to /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). 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. 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: o LOW. Monitors response times, throughput, and the total number of requests and faults. o HIGH. Performs the same monitoring as LOW and enables Message Trace (Content Visualization). o 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. 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. The same could also be obtained from the following CLI command (the command should be entered on one line): \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. 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 Authors 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. . . . . . . . . . . . . . . . . . . . . . . . Please read our Terms of Use and Licensing policies: http://www.sun.com/share/text/termsofuse.html http://developers.sun.com/dispatcher.jsp?uid=6910008 PRIVACY STATEMENT: Sun respects your online time and privacy (http://sun.com/privacy). You have received this based on your e-mail preferences. If you would prefer not to receive this information, please follow the steps at the bottom of this message to unsubscribe. * FEEDBACK Comments? Send your feedback on the Enterprise Java Technologies Tech Tips to: http://developers.sun.com/contact/feedback.jsp?category=sdn * SUBSCRIBE/UNSUBSCRIBE Subscribe to other Java developer Tech Tips: - 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). To subscribe to these and other JDC publications: - Go to the Sun Developer Network - Subscriptions page, (https://softwarereg.sun.com/registration/developer/en_US/subscriptions), choose the newsletters you want to subscribe to and click "Submit". - To unsubscribe, go to the Subscriptions page, (https://softwarereg.sun.com/registration/developer/en_US/subscriptions), uncheck the appropriate checkbox, and click "Submit". - To use our one-click unsubscribe facility, see the link at the end of this email: - ARCHIVES You'll find the Enterprise Java Technologies Tech Tips archives at: http://java.sun.com/developer/EJTechTips/index.html - COPYRIGHT Copyright 2006 Sun Microsystems, Inc. All rights reserved. 901 San Antonio Road, Palo Alto, California 94303 USA. This document is protected by copyright. For more information, see: http://java.sun.com/developer/copyright.html Enterprise Java Technologies Tech Tips January 28, 2006 Trademark Information: http://www.sun.com/suntrademarks/ Java, J2SE, J2EE, J2ME, and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries.