X

Recent Posts

datasource

DataSource Resource Definition in Java EE 6

by Jagadish RamuPlease note: This blog was updated on May 7, 2010.Java EE applications use DataSource objects when they access relational databases through the JDBC API.A DataSource has a set of properties that identify and describe the real-world data source that it represents.These properties include information such as the location of the database server, the name of the database, and the network protocolto use to communicate with the server. In addition, a DataSource object works with a Java Naming andDirectory Interface (JNDI) naming service. After a DataSource object is registered with a JNDI naming service,an application can use the JNDI API to access that DataSource object, which can then be used to connect to thedatasource it represents.Prior to Java EE 6, you could create a DataSource object using vendor-specific mechanisms, such as commands,and use the DataSource object in the application.However, Java EE 6 makes datasource definition more flexible. It introduces a new datasource definitionresource that you can declare portably for database connectivity across any Java EE 6-compatible application server.You can declare datasource definitions either through annotations or through the use of deployment descriptors.This Tech Tip shows you how to create a datasource definition using either annotations or deployment descriptors.It also includes a sample application that demonstrates the use of these features.Creating Datasource Definitions Using AnnotationsJava EE 6 provides two new annotations for creating datasource definitions:@DataSourceDefinition and @DataSourceDefinitions. Both of these annotations are inthe javax.annotation.sql package. You use the @DataSourceDefinitionannotation to create a single datasource definition. You use the @DataSourceDefinitions annotation to createmultiple datasource definitions.@DataSourceDefinition AnnotationYou can use the @DataSourceDefinition annotation to create a datasource definition. You canspecify the annotation in an application component class such as an application client, servlet, or Enterprise JavaBeans (EJB) component.This defines a DataSource object and registers it with JNDI. You configure the DataSourceobject by setting the annotation elements with commonly used DataSource properties. You can specify additionalstandard and vendor-specific properties in the properties element of the annotation.For example, the following annotation creates a datasource definition for a Derby database: @DataSourceDefinition(name = "java:app/env/Servlet_DataSource", minPoolSize = 0, initialPoolSize = 0, className = "org.apache.derby.jdbc.ClientXADataSource", user = "APP", password = "APP", databaseName = "testdb", properties = {"connectionAttributes=;create=true"} )The datasource definition is uniquely identified by the name element. This is the JNDI name by which the datasource willbe registered. Notice that the name specified in the name element begins with a namespace scope, in this case,java:app. Java EE 6 introduces application component environment namespaces, which includes the following scopes.java:comp. Names in this namespace have per-component visibility.java:module. Names in this namespace are shared by all components in a module, for example, the EJB componentsdefined in an a ejb-jar.xml file.java:app. Names in this namespace are shared by all components and modules in an application, for example,the application-client, web, and EJB components in an .ear file.java:global. Names in this namespace are shared by all the applications in the server.Depending on the namespace scope you specify in the name element, you can make the datasource available acrossa module, an application, or globally across a server. If you prefix the name element value with:java:comp/env/, the datasource will be available for thecomponent in which it is defined, such as a servlet, EJB, or application client component.java:module/env/, the datasource will be available for all the EJB components defined in its ejb-jar.xmlfile.java:app/env/, the datasource will be available for all the components and modules in the application,such as EJB, servlet, and application client components.@DataSourceDefinitions AnnotationYou can use the @DataSourceDefinitions annotation to create multiple datasource definitionsin a component class. You specify each datasource definition in a value element in the annotation. Here is an examplethat creates in an EJB class multiple datasource definitions for a Derby database: @DataSourceDefinitions( value = { @DataSourceDefinition(name = "java:app/env/HelloStatefulEJB_DataSource", minPoolSize = 0, initialPoolSize = 0, className = "org.apache.derby.jdbc.ClientXADataSource", portNumber = 1527, serverName = "localhost", user = "APP", password = "APP", databaseName = "testdb", properties = {"connectionAttributes=;create=true"} ), @DataSourceDefinition(name = "java:comp/env/HelloStatefulEJB_DataSource", minPoolSize = 0, initialPoolSize = 0, className = "org.apache.derby.jdbc.ClientXADataSource", portNumber = 1527, serverName = "localhost", user = "APP", password = "APP", databaseName = "testdb", properties = {"connectionAttributes=;create=true"} ) } ) @Stateful public class HelloStatefulEJB implements HelloStateful { ... ... }Creating Datasource Definitions Using a Deployment DescriptorYou can create a datasource definition resource using a deployment descriptor in an application.xml,application-client.xml, web.xml, or ejb-jar.xml file. For example, thefollowing deployment descriptor creates the same datasource definition as was defined in the previous@DataSourceDefinition annotation example: <data-source> <name>java:app/env/Application_Level_DataSource</name> <class-name>org.apache.derby.jdbc.ClientXADataSource</class-name> <server-name>localhost</server-name> <port-number>1527</port-number> <database-name>testdb</database-name> <user>APP</user> <password>APP</password> <property> <name>connectionAttributes</name> <value>;create=true</value> </property> </data-source>You've seen two examples that create the same datasource definition, one using an annotation and one using adeployment descriptor. In fact, it is possible to create two datasource definitions with the same name in this way.In that case, the values specified in the deployment descriptor take precedence over those specified in the annotation.For example, if you create two datasource definitions with the same name, one using an annotation and one using adeployment descriptor, and you specify a database name is each, the database name that you specified in the deploymentdescriptor will be honored. However, if you specify a value for an element in an annotation and you don't specify an equivalentelement in a deployment descriptor, the value from the annotation will be merged with the deployment descriptor-based information.Sample Application A sample application accompanies this tip. The application demonstrates datasource definition usingannotations and deployment descriptors, and it does it for various types of Java EE components and for variousnamespace scopes. The application includes the following Java EE components:Web component: Servlet.javaEJB components: HelloStatefulEJB.java and HelloEJB.javaApplication client: Client.javaThe application is supplied a datasource definition name. It then does a lookup of the datasource in the application client, EJB, and servletcomponents. Based on the availability of the resource in the component's scope, the application either uses the provided datasourceor a default datasource, java:app/env/Application_DD_DataSource.Here are the datasource definitions that are created or exported by the application:java:app/env/Application_DD_DataSourcejava:comp/env/Servlet_DD_DataSourcejava:module/env/Servlet_DataSourcejava:app/env/Servlet_DataSourcejava:comp/env/HelloStatefulEJB_DataSourcejava:app/env/HelloStatefulEJB_DataSourcejava:comp/env/HelloEJB_DataSourcejava:module/env/HelloEJB_DataSourcejava:app/env/HelloEJB_DD_DataSourcejava:comp/env/Appclient_DD_DataSourcejava:module/env/Appclient_DD_DataSourcejava:app/env/Appclient_DataSourceFrom the name and the namespace scope of the resource, the component in which the resource is defined can be identified.For example, for the datasource definition named java:app/env/HelloEJB_DD_DataSource, the namespace scope isjava:app and the resource is defined for "HelloEJB" in a deployment descriptor, "DD".To run the application, do the following:If you haven't already done so, download GlassFish v3.Set the environment variable GF_HOME to where you installed GlassFish v3.Ensure that you have an installed version of theJava Platform Standard Edition (Java SE) 6 SDK.Ensure that the PATH environment variable includes JAVA_HOME/bin, whereJAVA_HOME is set to where the Java SE 6 SDK is installed.Ensure that the ANT tool is installed. It should be installed as part of GlassFish v3. Also ensure thatthe PATH environment variable includes ANT_HOME/bin, where ANT_HOMEis set to where the ANT tool is installed.Start the GlassFish v3 application server by entering the following command: <GF_HOME>/bin/asadmin start-domainStart the Derby database that is packaged with the GlassFish v3 by entering the following command: <GF_HOME>/bin/asadmin start-databaseDownload and extract the sample application, DSD.zip.Change to the sample directory. If your installation of GlassFish v3 requires an administration password, specify the password as the value of the admin.password property in the config.properties file.Execute the following command: ant allThe command compiles, assembles, deploys, and runs the application. It then undeploys the application.In response, you should see output for various datasources. Here is the output you should see for thedatasource named java:app/env/Servlet_DataSource: [exec] Mode : appclient [exec] Data-Source name : java:app/env/Servlet_DataSource [exec] ---------------------------------------------------------------------------------------------------------- [exec] REQUESTED DATA SOURCE : java:app/env/Servlet_DataSource [exec] ACTUAL DATA SOURCE USED : java:app/env/Servlet_DataSource [exec] RESULT : DATASOURCE ACCESSIBLE [exec] ---------------------------------------------------------------------------------------------------------- [exec] [exec] Mode : servlet [exec] Data-Source name : java:app/env/Servlet_DataSource [exec] ---------------------------------------------------------------------------------------------------------- [exec] REQUESTED DATA SOURCE : java:app/env/Servlet_DataSource [exec] ACTUAL DATA SOURCE USED : java:app/env/Servlet_DataSource [exec] RESULT : DATASOURCE ACCESSIBLE [exec] ---------------------------------------------------------------------------------------------------------- [exec] [exec] Mode : stateful_ejb [exec] Data-Source name : java:app/env/Servlet_DataSource [exec] ---------------------------------------------------------------------------------------------------------- [exec] REQUESTED DATA SOURCE : java:app/env/Servlet_DataSource [exec] ACTUAL DATA SOURCE USED : java:app/env/Servlet_DataSource [exec] RESULT : DATASOURCE ACCESSIBLE [exec] ---------------------------------------------------------------------------------------------------------- [exec] [exec] Mode : stateless_ejb [exec] Data-Source name : java:app/env/Servlet_DataSource [exec] ---------------------------------------------------------------------------------------------------------- [exec] REQUESTED DATA SOURCE : java:app/env/Servlet_DataSource [exec] ACTUAL DATA SOURCE USED : java:app/env/Servlet_DataSource [exec] RESULT : DATASOURCE ACCESSIBLE [exec] ----------------------------------------------------------------------------------------------------------In the above output, DATASOURCE ACCESSIBLE in the RESULT rows indicates that the datasource named java:app/env/Servlet_DataSourceis available across all components, that is, across the EJB, servlet, and application client components.Similarly, here is what the output for the resource named java:module/env/HelloEJB_DataSource should look like : [exec] Mode : appclient[exec] Data-Source name : java:module/env/HelloEJB_DataSource[exec] ----------------------------------------------------------------------------------------------------------[exec] REQUESTED DATA SOURCE : java:module/env/HelloEJB_DataSource[exec] ACTUAL DATA SOURCE USED : java:global/default-datasource[exec] RESULT : DATASOURCE NOT ACCESSIBLE[exec] ----------------------------------------------------------------------------------------------------------[exec][exec] Mode : servlet[exec] Data-Source name : java:module/env/HelloEJB_DataSource[exec] ----------------------------------------------------------------------------------------------------------[exec] REQUESTED DATA SOURCE : java:module/env/HelloEJB_DataSource[exec] ACTUAL DATA SOURCE USED : java:global/default-datasource[exec] RESULT : DATASOURCE NOT ACCESSIBLE[exec] ----------------------------------------------------------------------------------------------------------[exec][exec] Mode : stateful_ejb[exec] Data-Source name : java:module/env/HelloEJB_DataSource[exec] ----------------------------------------------------------------------------------------------------------[exec] REQUESTED DATA SOURCE : java:module/env/HelloEJB_DataSource[exec] ACTUAL DATA SOURCE USED : java:module/env/HelloEJB_DataSource[exec] RESULT : DATASOURCE ACCESSIBLE[exec] ----------------------------------------------------------------------------------------------------------[exec][exec] Mode : stateless_ejb[exec] Data-Source name : java:module/env/HelloEJB_DataSource[exec] ----------------------------------------------------------------------------------------------------------[exec] REQUESTED DATA SOURCE : java:module/env/HelloEJB_DataSource[exec] ACTUAL DATA SOURCE USED : java:module/env/HelloEJB_DataSource[exec] RESULT : DATASOURCE ACCESSIBLE [exec] ----------------------------------------------------------------------------------------------------------Here, the RESULT lines indicate that the datasource named java:module/env/HelloEJB_DataSource is available only for theEJB components defined in the ejb-jar.xml file, that is, HelloEJB and HelloStatefulEJB.Note that the sample application does a lookup to get access to a resource. However, it is also possible to inject the datasource as follows : @Stateless public class HelloEJB implements Hello { @Resource(lookup = "java:app/env/HelloEJB_DataSource") private DataSource app; ... ... }Also note that the sample application defines many datasources in addition to the ones named previously. To run the application for theseadditional datasources, find the build.xml file in the sample directory. Then uncomment the commentedtarget="runclient" calls.Further ReadingFor more information about DataSource resource definition in Java EE 6, see Section EE.5.17"DataSource Resource Definition" in the Java EE 6 Specification.About the AuthorJagadish Ramu is an engineer in the GlassFish Application Server team. He works in the areas of JDBC, connection pooling, and connectors.He has been involved with the connectors team at Sun since mid-2005. Jagadish holds an M.Tech degree from BITS Pilani, India.

by Jagadish Ramu Please note: This blog was updated on May 7, 2010. Java EE applications use DataSource objects when they access relational databases through the JDBC API. A DataSource has a set of...

Servlet API

Asynchronous Support in Servlet 3.0

by Rajiv MordaniOne of the significant enhancements made inJSR 315: Java Servlet 3.0, is support for asynchronous processing.With this support, a servlet no longer has to wait for a response from a resource such as a database before its thread can continueprocessing, that is, the thread is not blocked. Previous to Servlet 3.0, asynchronous support in the Java EE web container wasprovided in a proprietary way — either through APIs built on top of the Servlet 2.5 API or through non-Servlet APIs orimplementations.In modern web applications there are times when you need to asynchronously handle some part of the request, so that the web containercan continue serving other requests in a seamless fashion. One example is a chat room application. In this type of application youwant to enable long-lived client connections with a servlet. You don't want a server thread to be blocked for a long period of timeserving a request from a single client. You want the servlet to process a request from the client and then free up the server threadas quickly as possible for other work. In other words, you want the request to be processed and a response generated asynchronously.With the upcoming release of the Servlet 3.0 specification, standard asynchronous support has been added to the Servlet API.This Tech Tip introduces the asynchronous support that has been added to the Servlet API in Java Servlet 3.0 technology.It also includes a sample application that demonstrates those features.Asynchronous Support FeaturesThe primary features of the asynchronous support in Servlet 3.0 are as follows.Annotation AttributesServlet 3.0 introduces the use of annotations as an alternative to deployment descriptorsfor servlet-related configuration in a web application. Two of these annotations are @WebServlet, which defines a servlet,and @WebFilter, which defines a servlet filter. Both of these annotations include an attribute, asyncSupported.Setting the asyncSupported attribute to true, declares that the servlet or servlet filter supports asynchronousprocessing. For example, the following annotation defines a servlet in a web application and declares that the servlet supportsasynchronous processing: @WebServlet(url="/foo" asyncSupported=true)The asyncSupported attribute is needed to differentiate code written for synchronous processing from that written for use inan asynchronous context. In fact, for an application to use the asynchronous feature, the entire request processing chain must havethe have this attribute set either through the annotation or in its deployment descriptor. An IllegalStateException will be thrownif an application tries to start an asynchronous operation and there is a servlet or servlet filter in the request processing chainthat does not support asynchronous processing.Servlet Request MethodsThe support for asynchronous processing also includes new ServletRequest methods, such asstartAsync(servletRequest, servletResponse), startAsync(), and getAsyncContext(). After you set theasyncSupported attribute in the request processing chain to support asynchronous processing, you call either thestartAsync(servletRequest, servletResponse) or startAsync() method to make an asynchronous request.Here, for example, is a call that makes an asynchronous request: AsyncContext aCtx = req.startAsync(req, res);The difference between the two startAsync method signatures is that the startAsync() method implicitly usesthe original request and response, while the startAsync(servletRequest, servletResponse) method uses the request and responseobjects passed in the method call. The request and response passed in the call can be wrapped by filters or other servlets earlier in therequest processing chain. Notice that the startAsync method returns an AsyncContext object —see AsyncContext Class for more details. The AsyncContext object is initialized appropriatelywith the request and response objects depending on the method used. You must exercise caution when wrapping the response and calling theno arguments signature of the startAsync() method. You could lose the data if any of data is written to the wrappedresponse and not flushed to the underlying response stream.There are a few more methods in the ServletRequest class that are part of the support for asynchronous processing.These include isAsyncSupported() and isAsyncStarted() You can use these convenience methods in an applicationto determine if asynchronous operations are supported or started on a request.AsyncContext ClassThe AsyncContext class is a new class in Servlet 3.0 that provides the execution context for an asynchronous operation.The class provides a variety of methods that you can use to get access to the underlying request and response objects.For example, you can use the AsyncContext.dispatch(), AsyncContext.dispatch(path),or AsyncContext.dispatch(servletContext, path) method to dispatch the request to the container. Using any of thedispatch methods, enables the processing to return to the container after the asynchronous operation that was started on the ServletRequest iscompleted — for instance, after waiting for a call to a web service to return. These methods dispatch the request back to the containerso you can use frameworks such as JavaServer Pages (JSP) to generate the response.The dispatch() method, that is, the method with no arguments, forwards the request back to the original URL.Also, if a call to AsyncContext.dispatch or RequestDispatcher.forward occurs after an asynchronous contexthas been initialized, the dispatch() method forwards the request to the path for the AsyncContextor RequestDispatcher-related requests.The dispatch(path) method forwards the request to the path relative to the context of the request.The dispatch(ServletContext, path) method forwards the request to the path relative to the specified context.For example, here is a call that forwards the request back to the container so that the JSP framework can generate the response. ctx.dispatch("/render.jsp");Another AsyncContext method, complete(), completes the asynchronous operation that was started on the request thatwas used to initialize this AsyncContext object. It closes the response that was used to initialize this AsyncContextobject. You can call this method, for example, when the response generated by the asynchronous operation is complete.The container can also implicitly call this method if the application dispatches the request back to the container using the forwardmethod with no subsequent startAsync call on the request.Asynchronous Listener ClassServlet 3.0 also adds a new listener class for asynchronous processing, AsyncListener. You can use this class in anapplication to get notified when asynchronous processing is completed, if a timeout has occurred, an error has occurred, or a subsequent callto startAsync has occurred. The following code snippet creates a new AsyncListener object and uses it toget notified when an asynchronous processing operation is completed . AsyncContext ac = req.startAsync(); req.addAsyncListener(new AsyncListener() { public void onComplete(AsyncEvent event) throws IOException { ... } ... }Notice that the parameter passed to the onComplete method is an AsyncEvent object. TheAsyncEvent class is another new class provided as part of the Servlet 3.0 support for asynchronous processing.It represents an event that gets fired when the asynchronous operation initiated on a ServletRequesthas completed, timed out, or produced an error.A Simple Application That Uses the Asynchronous Support in Servlet 3.0Now that you've seen the key features in the Servlet 3.0 support for asynchronous processing, let's look at a more completeexample. The following shows the code for a simple web application. In the application, a servlet makes an asynchronous requestto a web service, waits for the call to return, and then dispatches the request back to the container to render the resultusing JSP. Note that the complete code for servlet is not shown. @WebServlet("/foo" asyncSupported=true) public class MyServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) { ... AsyncContext aCtx = request.startAsync(req, res); ScheduledThreadPoolExecutor executor = new ThreadPoolExecutor(10); executor.execute(new AsyncWebService(aCtx)); } } public class AsyncWebService implements Runnable { AsyncContext ctx; public AsyncWebService(AsyncContext ctx) { this.ctx = ctx; } public void run() { // Invoke web service and save result in request attribute // Dispatch the request to render the result to a JSP. ctx.dispatch("/render.jsp"); }}Sample Application One of the sample applications provided with the Java EE 6 SDKis a chat application that uses the asynchronous support in Servlet 3.0.To run the application, do the following:If you haven't already done so, download the Java EE 6 SDK. Also be sure to have an installed version of theJava Platform Standard Edition (Java SE) 6 SDK.Download the sample application,async-request-war.warStart the GlassFish v3 application server that is packaged with the Java EE 6 SDK by entering thefollowing command: <javaee_home>/bin/asadmin start-domainwhere <javaee_home> is where you installed the Java EE 6 SDK.Deploy the sample application by copying it to the <javaee_home>/domains/domain1/autodeploy directory.Execute the application by opening two browser windows. For simplicity, let's call them say Browser A and Browser B.Point both Browser A and Browser B to the URL http://localhost:8080/async_request_war. In response, you should see a chat user interface (UI) in each browser window. The UI presents a text area to view chat entries, a text field to enter a user ID, and a Login button.In Browser A, enter a user name, say "userA", in the text field and click the Login button. You should see the following message appear in the text area: System Message: userA has joined. You should also see a new text area for posting messages to the chat and a button labeled Post Message. Login as "userB" in Browser B. You should see the following message appear in both browser windows: System Message: userB has joined. The text area for posting messages and the Post Message button should appear in Browser B. Now, you're ready to chat.In Browser A, enter "Hello" in the text box and click the Post Message button. You should see the following message in both Browser A and Browser B: userA: HelloIn Browser B, enter "Hello" in the text box and click the Post Message button. You should see the following message in both Browser A and Browser B: userB: HelloYou can view the source code for the application in the <javaee_home>/samples/javaee6/web/servlet/async-request-war/srcdirectory.Further ReadingFor more information, see the following resources:JSR 315: Java Servlet 3.0Java Servlet TechnologyRajiv Mordani's BlogAbout the AuthorRajiv Mordani is a senior staff engineer at Sun Microsystems. He was part of the original J2EE platform team and has worked ona wide variety of server-side XML and web technologies, including Jakarta Tomcat and most recently Java Servlet 3.0.Rajiv is currently the specification lead for Servlet 3.0. Read his blog.

by Rajiv Mordani One of the significant enhancements made inJSR 315: Java Servlet 3.0, is support for asynchronous processing.With this support, a servlet no longer has to wait for a response from a...

JavaServer Faces (JSF) technology

POST-REDIRECT-GET and JSF 2.0

by Ed BurnsMichael Jouravlev, in his influential August 2004 articleRedirect After Post,described a problem that many web applications present. He described the problem as follows:All interactive programs provide two basic functions: obtaining user input and displaying the results.Web applications implement this behavior using two HTTP methods: POST and GET respectively. This simple protocol getsbroken when an application returns a web page in response to a POST request. Peculiarities of the POST method combined withidiosyncrasies of different browsers often lead to an unpleasant user experience and may produce an incorrect state ofthe server application.To address the problem, Jouravlev described a technique that he called POST-REDIRECT-GET, or the PRG pattern for short.The rules of the pattern are as follows:Never show pages in response to POSTAlways load pages using GETNavigate from POST to GET using REDIRECTPrevious versions of JavaServer Faces (JSF) technology violated the firstof these rules by using POST for every page navigation.In navigating from one page to another in a JSF-enabled application, the JSF framework forwarded a POST requestthrough the Servlet API's RequestDispatcher.forward( ) method. This caused a new Faces page to be renderedand returned to the browser in response to the postback request.Indeed, most popular Java Servlet-based web frameworks, including Struts, use this approach for navigation. HTTP purists rightlypoint out that this approach violates the first rule in the PRG pattern. Not only did JSF violate the first rule, but untilJavaServer Faces 2.0, it was very difficult to do it any other way.Thanks to a JSF contribution from the Seam team at JBoss, it is now much easier to do PRG with JSF.This Tech Tip shows how to implement the PRG pattern in JSF 2.0. The content of the tip is an adaptation of a sectionon PRG and JSF 2.0 in my upcoming book, with Neil Griffin,JavaServer Faces 2.0: The Complete Reference.A Non-PRG ExampleLet's start by examining a simple JSF 2.0 application that handles user registration. In this first example, the applicationdoes not implement the PRG pattern. The initial page for the application is coded in file register.xhtml, as follows: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <h:head> <title>A Simple JavaServer Faces Registration Application</title> </h:head> <h:body> <h:form> <h2>JSF Registration App</h2> <h4>Registration Form</h4> <table> <tr> <td>First Name:</td> <td> <h:inputText label="First Name" id="fname" value="#{userBean.firstName}" required="true"/> <h:message for="fname" /> </td> </tr> <tr> <td>Last Name:</td> <td> <h:inputText label="Last Name" id="lname" value="#{userBean.lastName}" required="true"/> <h:message for="lname" /> </td> </tr> ... additional table rows not shown. </table> <p><h:commandButton value="Register" action="confirm" /></p> </h:form> </h:body> </html>The page presents text fields for the user to enter a first name and a last name. It also displays a Register button.When the user presses the Register button, the JSF navigation rule system looks for a page within the application whose extensionis the same as the current page and whose filename is confirm. If confirm.xhtml exists,JSF uses the navigation components in that file to navigate to the next page. Here is the confirm.xhtmlfile: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <h:head> <title>A Simple JavaServer Faces Registration Application</title> </h:head> <h:body> <h:form> <h2>JSF Registration App</h2> <h4>Registration Confirmation</h4> <table> <tr> <td>First Name:</td> <td> <h:outputText value="First Name" value="#{userBean.firstName}" </td> </tr> <tr> <td>Last Name:</td> <td> <h:outputText label="Last Name" value="#{userBean.lastName}" </td> </tr> ... additional table rows not shown. </table> <p><h:commandButton value="Edit" action="register" /></p> <p><h:commandButton value="Confirm" action="#{userBean.addConfirmedUser}" /></p> </h:form> </h:body> </html>The confirm.xhtml file includes markup for an Edit button and a Confirm button.If the user clicks the Edit button, he or she is taken back to the register.xhtml page. If the user clicks theConfirm button, an action is invoked. The Confirm button specifies an action method, addConfirmedUser( ), thatdetermines the outcome programmatically in the logic of the method. Here is the UserBean.java file, which containsthe addConfirmedUser( ) method: package com.jsfcompref.model; ... imports @ManagedBean @SessionScoped public class UserBean { ... properties and methods public String addConfirmedUser() { boolean added = true; // actual application may fail to add user FacesMessage doneMessage = null; String outcome = null; if (added) { doneMessage = new FacesMessage("Successfully added new user"); outcome = "done"; } else { doneMessage = new FacesMessage("Failed to add new user"); outcome = "register"; } FacesContext.getCurrentInstance().addMessage(null, doneMessage); return outcome; }For this simple case, addConfirmedUser( ) causes a message stating Successfully added new userto be displayed on the page and returns "done" as the outcome.When the addConfirmedUser( ) method returns "done" as the outcome,it takes the user to the done.xhtml page.This is an example of implicit navigation, a new feature in JSF 2.0.If no matching navigation case is found after checking all available rules, the navigation handler checks to see whetherthe action outcome corresponds to a view id. If a view matching the action outcome is found, an implicit navigation tothe matching view occurs. Here the outcome is "done" and the matching view is done.xhtml,so the user is taken to the done.xhtml page. Implicit navigation saves you the effort of adding navigation rulesin the faces-config.xml file.Here is the done.xhtml page: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <h:head> <title>A Simple JavaServer Faces Registration Application</title> </h:head> <h:body> <h:form> <h2>JSF Registration App</h2> <h4>Registration Confirmation</h4> <h:messages /> <table> <tr> <td>First Name:</td> <td> <h:outputText value="First Name" value="#{userBean.firstName}" </td> </tr> </table> </h:form> </h:body> </html>POST-REDIRECT-GET Using View ParametersView Parameters is a simple, declarative way to map incoming requestparameter values to special components within the view. These mappings are specified using the new<f:viewParam> component, within the new <f:metadata> section of the view. Consider the following example: <f:metadata> <f:viewParam name="foo" value="#{bean.foo}"/> </f:metadata>This example specifies that the value of the request parameter with the name "foo" is automatically assignedto the property at #{bean.foo}. So for a GET request as follows: page1.jspx?foo=barThe value of the #{bean.foo} property will be set to bar when JSF starts processing the request.View Parameters is similar in spirit to the page parameters feature found in JBoss Seam, but the JSF 2.0 incarnation of the featureis tightly integrated with the core JSF specification, making the feature easier to use and more powerful.Let’s look at another simple example. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <h:head> <title>A Simple JavaServer Faces 2.0 View</title> </h:head> <h:body> <h:form> <p>First Name:< <h:inputText id="fname" value="#{userBean.firstName}" /> </p> <p><h:commandButton value="submit" action="page02?faces-redirect=true&amp;includeViewParams=true" /></p> </h:form> </h:body> </html>The <h:commandButton> element has action="page02?faces-redirect=true". In the Internet standard thatdefines URLs, the presence of a ? character indicates the remainder of the URL will be an & or &amp;-separated list ofname=value pairs that should be submitted to the server along with the request for the URL. This is known as a query string.JSF borrows the meaning of the ? character here, and the meaning is exactly the same as in the Internet standard for URLs.There are two special query strings parameters recognized by JSF when it parses the outcome on the server side.The faces-redirectquery string tells the navigation system that this implicit navigation case must be treated asif it were a real <navigation-case> element that includes a <redirect/> element. The otherspecial query string parameter, includeViewParams, tells the navigation handler to include the view parameters whenperforming the navigation. But what view parameters should be included? The view parameters to be included when performing thenavigation are declared on the to-view-id page. In this case, we are using implicit navigation, so theimplicit to-view-id is page02.xhtml, shown below. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"><f:metadata> <f:viewParam name="fname> value="#userBean.firstName}"/> </f:metadata> <h:head> <title>A Simple JavaServer Faces 2.0 View</title> </h:head> <h:body> <h:form> <p> Hello #{userBean.firstName}.</p> </h:form> </h:body> </html>When the navigation handler encounters the matching navigation-case (implicit or explicit) that declares that view parameters should be included,it looks at the view parameters of the from-view-id and to-view-id pages and performs a match-and-copy algorithmto convey the view parameters to the new page. In this case, the navigation-case also requested a redirect.Now let’s look at the registration example, this time implemented to do PRG with view parameters. The register.xhtml page looks like this: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"><f:metadata> <f:viewParam name="fname" value="#{userBean.firstName}" /> <f:viewParam name="lname" value="#{userBean.lastName}" /> <f:viewParam name="sex" value="#{userBean.sex}" /> <f:viewParam name="dob" value="#{userBean.dob}"> <f:convertDateTime pattern="MM-dd-yy" /> </f:viewParam> <f:viewParam name="mail" value="#{userBean.email}" /> <f:viewParam name="sLevel" value="#{userBean.serviceLevel}" /> </f:metadata> <h:head> <title>A Simple JavaServer Faces Registration Application</title> </h:head> <h:body> <h:form> <h2>JSF Registration App</h2> <h4>Registration Form</h4> <table> <tr> <td>First Name:</td> <td> <h:inputText label="First Name" id="fname" value="#{userBean.firstName}" required="true"/> <h:message for="fname" /> </td> </tr> ... remaining table rows omitted, they are the same as the original </table> <!-- The query parameters on the action attribute cause JSF to do the POST REDIRECT GET pattern --> <p><h:commandButton value="Register" action="confirm?faces-redirect=true&amp;includeViewParams=true" /></p> </h:form> </h:body> </html>In the previous View Parameters example, we stated that The only changes to this code are to make the bean be request-scoped andto add the query parameters to the implicit navigation string. In this case, the includeViewParams=true parameter is added,causing whatever view parameters declared on the to-view-id page to be included in the navigation.The confirm.xhtml page follows: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"><f:metadata> <f:viewParam name="fname" value="#{userBean.firstName}" /> <f:viewParam name="lname" value="#{userBean.lastName}" /> <f:viewParam name="sex" value="#{userBean.sex}" /> <f:viewParam name="dob" value="#{userBean.dob}"> <f:convertDateTime pattern="MM-dd-yy" /> </f:viewParam> <f:viewParam name="mail" value="#{userBean.email}" /> <f:viewParam name="sLevel" value="#{userBean.serviceLevel}" /> </f:metadata> <h:head> <title>A Simple JavaServer Faces Registration Application</title> </h:head> <h:body> <h:form> <h2>JSF Registration App</h2> <h4>Registration Confirmation</h4> <table> <tr> <td>First Name:</td> <td> <h:outputText value="First Name" value="#{userBean.firstName}" </td> </tr> ... additional rows omitted, they are the same as the original. </table> <p><h:commandButton value="Edit" action="register?faces-redirect=true&amp;includeViewParams=true" /></p> </h:form><h:form> <h:inputHidden value="#{userBean.firstName}" /> <h:inputHidden value="#{userBean.lastName}"/> <h:inputHidden value="#{userBean.sex}" /> <h:inputHidden value="#{userBean.dob}"> <f:convertDateTime pattern="MM-dd-yy" /> </h:inputHidden> <h:inputHidden value="#{userBean.email}" /> <h:inputHidden value="#{userBean.serviceLevel}" /> <p><h:commandButton value="Confirm" action="#{userBean.addConfirmedUser}" /></p> </h:form> </h:body> </html>As in the register.xhtml page, we need the <f:metadata> section at the top of the page and the additionalquery parameters on the action string. What is new here are the additional <h:form> element and<h:inputHidden> elements, and the fact that the Confirm button has been moved into this new form.This is necessary because we need to carry forward to the next page as regular form submit parameters the values passed to this page asview parameters. But there are no regular input fields as there are on the register.xhtml page.Therefore, we use hidden fields to carry the values forward. Note also the continued necessity for the<f:convertDateTime> on the dob field.Finally, here is the done.xhtml page: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"><f:metadata> <f:viewParam name="fname" value="#{userBean.firstName}" /> <f:viewParam name="lname" value="#{userBean.lastName}" /> <f:viewParam name="sex" value="#{userBean.sex}" /> <f:viewParam name="dob" value="#{userBean.dob}"> <f:convertDateTime pattern="MM-dd-yy" /> </f:viewParam> <f:viewParam name="email" value="#{userBean.email}" /> <f:viewParam name="sLevel" value="#{userBean.serviceLevel}" /> </f:metadata> <h:head> <title>A Simple JavaServer Faces Registration Application</title> </h:head> <h:body> <h:form> <h2>JSF Registration App</h2> <h4>Registration Confirmation</h4> <h:messages /> <table> <tr> <td>First Name:</td> <td> <h:outputText value="First Name" value="#{userBean.firstName}" </td> </tr> ... additional rows omitted </table> </h:form> </h:body> </html>The only difference between this done.xhtml and the original one is the now familiar<f:metadata> section.Running the Sample CodeA sample application that implements PRG accompanies this tip.These instructions use the Maven 2 software project management tool to build the sample application and then deploy it in theGlassFish v3 Preview application server.If you haven't already done so, download a recentpromoted build ornightly build of the GlassFish v3 Previewapplication server. Ifyou haven't already done so, download Maven 2.Download the sample application package, PostRedirectGet.zipExtract the contents of the sample application package. You should see the folders prgViewParams,which contains the code for the PRG application that uses View Parameters.Create the WAR file for the PRG application by changing to the prgViewParams directoryand entering the following Maven command: mvn installYou should see the file prgViewParams.war in a newly-created target subdirectory under theprgViewParams directory.Start the GlassFish v3 Preview application server by entering the following command: <GFv3_inst>/bin/asadmin start-domainwhere <GFv3_inst> is where you installed the GlassFish v3 Preview application server.Deploy the sample application. One way to do that is to copy the prgViewParams.war file to the<GFv3inst>/domains/domain1/autodeploy directory.Execute the application by opening a browser and accessing the URL http://localhost:8080/prgViewParams.You should see the form shown in Figure 1.Figure 1. Registration Page Enter information as appropriate into the form and click the Register button. You should see a page similar the one shown inFigure 2.Figure 2. Registering Through the Registration Page Click the Confirm button. You should see a page similar the one shown in Figure 3.Figure 3. Confirmation Page Further ReadingFor more information, see the following resources:JSR 314: JavaServer Faces 2.0JavaServer Faces 2.0: The Complete ReferenceRedirect After PostJSF 2.0 Bookmarkability/View ParametersAbout the AuthorEd Burns is a senior staff engineer at Sun Microsystems. Ed has worked on a wide variety of client and server-side web technologies since 1994,including NCSA Mosaic, Mozilla, the Sun Java Plugin, Jakarta Tomcat and, most recently JavaServer Faces. Ed is currently the co-spec lead forJavaServer Faces. He is the coauthor ofJavaServer Faces: The Complete Referenceand the author of Secrets of the RockstarProgrammers. He is also the coauthor of the upcoming bookJavaServer Faces 2.0: The Complete Reference.Read Ed Burns's blog.

by Ed Burns Michael Jouravlev, in his influential August 2004 articleRedirect After Post, described a problem that many web applications present. He described the problem as follows: All interactive...

JavaServer Faces (JSF) technology

Using CDI and Dependency Injection for Java in a JSF 2.0 Application

by Roger KitainThis Tech Tip covers the intersection of three powerful technologies that are part of the Java EE 6 platform: JSR 299: Contexts and DependencyInjection, JSR 330: Dependency Injection For Java, and JSR 314: JavaServer Faces 2.0.JSR 299: Contexts and DependencyInjection (CDI) defines a set of services for the Java EE environment that makes applicationsmuch easier to develop. It provides an architecture that allows Java EE components such asservlets, enterprise beans, and JavaBeans to exist within the lifecycle of an application withwell-defined scopes. In addition, CDI services allow Java EE components, including EJB session beans andJavaServer Faces (JSF) managed beans to be injected and to interact in a loosely coupled way by firingand observing events. Perhaps most significantly,CDI unifies and simplifies the EJB and JSF programming models. It allows enterprise beans to act as managed beans in a JSF application.Through its services, CDI brings transactional support to the web tier. This can make it a lot easier to access transactionalresources in web applications. For example, CDI services makes it a lot easier to build a Java EE web application that accessesa database with persistence provided by the Java Persistence API.JSR 330: Dependency Injection For Javaintroduces a standard set of annotations that can be used for dependency injection. Dependency injection is a popular techniquein developing enterprise Java applications. Unfortunately, there has not been a standard approach for annotation-based dependency injection.Dependency Injection For Java changes that by providing a standardized and extensible API for dependency injection.The API comprises a set of annotations for use on injectable classes.JavaServer Faces technology provides a server-side component framework that is designed to simplify the development of userinterfaces (UIs) for Java EE applications. The latest release of the technology,JSR 314: JavaServer Faces 2.0, makes UI development forJava EE applications even easier through support for annotations and the addition of new features such as Facelets andcomposite components.This Tech Tip illustrates the use of CDI and Dependency Injection for Java in a JSF 2.0 application.An Example ApplicationLet's look at some key parts of a JSF 2.0 application that uses CDI and Dependency Injection for Java. You can findthe source code for the application in the sample application package that accompanies this tip.See Running the Sample Code for instructions on how to install and run the application.Figure 1 shows the UI for the application. The UI prompts a user to guess a number that the system has randomly selected.The prompt is as follows: I am thinking of a number between min to max, where min and maxrepresent the minimum and maximum values allowable as a guess, respectively. The UI displays a text field for the user to enter the number,a Guess button to submit the number, and a Reset button to restart the game. If the user enters a number that is lower than the correct number,the UI responds with the message Higher! It also changes the min value in the prompt message to one more than the guessed number. If the user's entryis too high, the UI responds with the message Lower! and changes the max value in the prompt message to one less than the guessed number. The systemsets a limit for the number of guesses, and with each incorrect guess, the UI displaysa message that tells the user how many guesses remain. The game ends when the user correctly guesses the number or when the user reachesthe limit of guesses.Figure 1. The UI for the Guess Number JSF 2.0 Application Here is the code for the application's UI: 1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2. <html xmlns="http://www.w3.org/1999/xhtml" 3. xmlns:ui="http://java.sun.com/jsf/facelets" 4. xmlns:h="http://java.sun.com/jsf/html" 5. xmlns:f="http://java.sun.com/jsf/core"> 6. <h:head> 7. <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> 8. <title>JSF 2.0 Weld Example</title> 9. </h:head> 10. <h:body> 11. <h:form id="NumberGuessMain"> 12. <h:panelGrid styleClass="title-panel"> 13. <h:outputText value="Guess Number" styleClass="title-panel-text"/> 14. <h:outputText value="Powered By JavaServer Faces 2.0 and Weld" styleClass="title-panel-subtext"/> 15. </h:panelGrid> 16. <div style="color: black; font-size: 24px;"> 17. I'm thinking of a number between <span style="color: blue">#{game.smallest}</span> and <span style="color: blue">#{game.biggest}</span>. You have <span style="color: blue">#{game.remainingGuesses}</span>guesses. 18. </div> 19. <h:panelGrid border="1" columns="5" style="font-size: 18px;"> 20. Number: 21. <h:inputText id="inputGuess" value="#{game.guess}" required="true" size="3" disabled="#{game.number eq game.guess}" validator="#{game.validateNumberRange}"/> 22. <h:commandButton id="GuessButton" value="Guess" action="#{game.check}" disabled="#{game.number eq game.guess}"/> 23. <h:commandButton id="RestartButton" value="Reset" action="#{game.reset}" immediate="true" /> 24. <h:outputText id="Higher" value="Higher!" rendered="#{game.number gt game.guess and game.guess ne 0}" style="color: red"/> 25. <h:outputText id="Lower" value="Lower!" rendered="#{game.number lt game.guess and game.guess ne 0}" style="color: red"/> 26. </h:panelGrid> 27. <div style="color: red; font-size: 14px;"> 28. <h:messages id="messages" globalOnly="false"/> 29. </div> 30. <h:outputStylesheet name="stylesheet.css" /> 31. </h:form> 32. </h:body> 33. </html>The code for the UI should look familiar to you if you develop applications with JSF. In fact, everything on the page is standard JSF 2.0 view markup.Notice the highlighted expression language (EL) expressions. These expressions refer to a contextual bean instancenamed game. A contextual bean instance is also known as a managed bean or simply a bean.Actually, the concept of managed beans goes beyond CDI. Managed beans, which is introduced in Java EE 6, is designed to unify all of the various typesof beans in Java EE, including JSF managed beans, enterprise beans, and CDI beans. A managed bean is a Java class that is treated asa managed component by the Java EE container. Optionally, you can give it a name in the same namespace as that used by EJB components.A managed bean can also rely on a small number of container-provided services, mostly related to lifecycle management and resource injection.Other Java EE technologies such as JSF, EJB, and CDI build on this basic definition of a managed bean byadding services. So, for example, a JSF managed bean adds lifecycle scopes, an EJB session bean adds services such as supportfor transactions, and a CDI bean adds services such as dependency injection.Returning to the highlighted EL expressions in the code for the UI, the EL expressions bind to various beanproperties and methods, as follows:The EL expressions in line 17, 24, and 25 bind to bean properties.The EL expressions in line 21 bind to bean properties and to a bean validation method.The EL expressions in lines 22 and 23 bind to bean action methods.As you can see, in JSF 2.0, binding to a CDI bean is no different than binding to a typical JSF managed bean.The Anatomy of a Simple Contextual BeanAs mentioned previously, beans can be bound to a lifecycle context, can be injected, and can interact with other beans ina loosely coupled way by firing and observing events. In addition, a bean may be called directly from Java code,or as you've seen in the UI for the example application, it may be invoked in an EL expression. This enables a JSF pageto directly access a bean.Let's examine the game bean used in the application. Here is its source code: 1. package weldguess; 2. 3. import java.io.Serializable; 4. import javax.annotation.PostConstruct; 5. import javax.enterprise.context.SessionScoped; 6. import javax.enterprise.inject.Instance; 7. import javax.inject.Inject; 8. import javax.inject.Named; 9. import javax.faces.application.FacesMessage; 10. import javax.faces.component.UIComponent; 11. import javax.faces.component.UIInput; 12. import javax.faces.context.FacesContext; 13. 14. @Named 15. @SessionScoped 16. public class Game implements Serializable { 17. private static final long serialVersionUID = 1L; 18. 19. private int number; 20. private int guess; 21. private int smallest; 22. 23. @MaxNumber @Inject 24. private int maxNumber; 25. 26. private int biggest; 27. private int remainingGuesses; 28. 29. @Random @Inject Instance<Integer> randomNumber; 30. 31. public Game() { 32. } 33. 34. public int getNumber() { 35. return number; 36. } 37. 38. public int getGuess() { 39. return guess; 40. } 41. 42. public void setGuess(int guess) { 43. this.guess = guess; 44. } 45. 46. public int getSmallest() { 47. return smallest; 48. } 49. 50. public int getBiggest() { 51. return biggest; 52. } 53. 54. public int getRemainingGuesses() { 55. return remainingGuesses; 56. } 57. 58. public String check() throws InterruptedException { 59. if (guess>number) { 60. biggest = guess - 1; 61. } 62. if (guess<number) { 63. smallest = guess + 1; 64. } 65. if (guess == number) { 66. FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Correct!")); 67. } 68. remainingGuesses--; 69. return null; 70. } 71. 72. @PostConstruct 73. public void reset() { 74. this.smallest = 0; 75. this.guess = 0; 76. this.remainingGuesses = 10; 77. this.biggest = maxNumber; 78. this.number = randomNumber.get(); 79. } 80. 81. public void validateNumberRange(FacesContext context, UIComponent toValidate, Object value) { 82. if (remainingGuesses <= 0) { 83. FacesMessage message = new FacesMessage("No guesses left!"); 84. context.addMessage(toValidate.getClientId(context), message); 85. ((UIInput)toValidate).setValid(false); 86. return; 87. } 88. int input = (Integer) value; 89. if (input < smallest || input > biggest) { 90. ((UIInput)toValidate).setValid(false); 91. FacesMessage message = new FacesMessage("Invalid guess"); 92. context.addMessage(toValidate.getClientId(context), message); 93. } 94. } 95. }Notice especially the following highlighted annotations in the bean.The @Named annotation in Line 14. This is a Dependency Injection For Java annotation that is usedto associate a name with the bean. Because there is no name specified as an argument to the annotation, thename of the bean will be the name of the JavaBean with its first letter made lowercase, that is, game.The annotation enables the application to reference the bean by that name using the EL expressions in the view.The @SessionScoped annotation in Line 15. This is a CDI annotation that specifies a scope for the bean.All beans have a scope that determines the lifecycle of their instances and which instances of the beans are visible to instancesof other beans. The @SessionScoped annotation declares that this bean is a session scoped bean, meaning that itslifecycle is the lifecycle of the session.The @Inject annotation in Line 23 and line 29. This is a CDI annotation that is used to identify a dependencyinjection point, that is, a point at which a dependency on a Java class or interface can be injected. In line 23, the annotationidentifies a dependency injection point for the maxNumber field. Line 23 also specifies a qualifier annotation,@MaxNumber, that identifies the implementation to inject. Qualifiers are strongly-typed keys that help distinguishdifferent uses of objects of the same type. Later in this tip, you'll learn more about qualifiers. Defining@MaxNumber as a qualifier annotation enables the injection of the limit value for the maximum number of guesses.In line 29, the @Inject annotation identifies a dependency injection point for the randomNumberfield. Line 29 also specifies a qualifier annotation, @Random, that identifies the implementation to inject.Defining @Random as a qualifier annotation enables the injection of a random number that the user needs to guess.The @PostConstruct annotation in line 72. This annotation is defined inJSR 250, Common Annotations for the Java Platform. Theannotation is used to identify a method that will perform initialization after a component is created. Here, thereset()method is marked with a @PostConstruct annotation. After the bean is created, thereset()method initializes a number of variables such as remainingGuesses, which tracks the remaining numberof guesses; biggest, which holds the value for the maximum number of guesses; and number,which holds the randomly generated number that the user needs to guess.Supporting AnnotationsYou've seen that the bean uses the @Random and @MaxNumber annotations as qualifier annotations.Now let's see how those annotations are defined.Here is the definition of the @Random annotation: 1. package weldguess; 2. 3. import static java.lang.annotation.ElementType.FIELD; 4. import static java.lang.annotation.ElementType.METHOD; 5. import static java.lang.annotation.ElementType.PARAMETER; 6. import static java.lang.annotation.ElementType.TYPE; 7. import static java.lang.annotation.RetentionPolicy.RUNTIME; 8. import java.lang.annotation.Documented; 9. import java.lang.annotation.Retention; 10. import javax.inject.Qualifier; 11. 12. @Target( { TYPE, METHOD, PARAMETER, FIELD }) 13. @Retention(RUNTIME) 14. @Documented 15. @Qualifier 16. public @interface Random { 17. }The @Qualifier annotation in line 15 is a Dependency Injection For Java annotation that is usedto identify an annotation as a qualifier annotation. A qualifier identifies a specific implementation ofa Java class or interface to be injected. In order to use a qualifier annotation, you first need to define itstype as a qualifier. You use the @Qualifier annotation to do that.Defining @Random as a qualifier annotation enables a random number to be injected into the application.The @Qualifier annotation is also used in the definition of the @MaxNumber annotation, as shown below: 1. package weldguess; 2. 3. import static java.lang.annotation.ElementType.FIELD; 4. import static java.lang.annotation.ElementType.METHOD; 5. import static java.lang.annotation.ElementType.PARAMETER; 6. import static java.lang.annotation.ElementType.TYPE; 7. import static java.lang.annotation.RetentionPolicy.RUNTIME; 8. import java.lang.annotation.Documented; 9. import java.lang.annotation.Retention; 10. import java.lang.annotation.Target; 11. import javax.inject.Qualifier; 12. 13. @Target( { TYPE, METHOD, PARAMETER, FIELD }) 14. @Retention(RUNTIME) 15. @Documented 16. @Qualifier 17. public @interface MaxNumber { 18. }The @Qualifier annotation in line 16 defines @MaxNumber as a qualifier annotation.Defining @MaxNumber as a qualifier annotation enables the injection of the maximum number of allowed guessesinto the application.The Utility BeanThere is one more important component of the application, a utility bean named Generator.Here is what the Generator bean looks like: 1. package weldguess; 2. 3. import java.io.Serializable; 4. import javax.enterprise.context.ApplicationScoped; 5. import javax.enterprise.inject.Produces; 6. 7. @ApplicationScoped 8. public class Generator implements Serializable { 9. private static final long serialVersionUID = -7213673465118041882L; 10. private java.util.Random random = new java.util.Random( System.currentTimeMillis() ); 11. private int maxNumber = 100; 12. java.util.Random getRandom() { 13. return random; 14. } 15. @Produces @Random int next() { 16. return getRandom().nextInt(maxNumber); 17. } 18. @Produces @MaxNumber int getMaxNumber() { 19. return maxNumber; 20. } 21. }Here are what the highlighted annotations in the bean do:The @ApplicationScoped annotation in line 7 is a CDI annotation that specifies a scope for the class. The annotationdeclares that an instance of the Generator class exists for the lifecycle of the application.The @Produces annotation in line 15 and line 18 is a CDI annotation that is used to identify a method as aproducer method. A producer method is called whenever another bean in the application needs an injected object. In line 15, theproducer method is next(). The method is called by the Beans Manager when the Gamebean needs to obtain an instance of the next random number. In line 18, the producer method is getMaxNumber(). The methodis called by the Beans Manager when the Game bean needs to obtain the maximum number of allowedguesses — in this case, 100.How the Components Work TogetherLet's return to the UI discussed earlier. When a user responds to the prompt and clicks the Guess button, CDI technology goes into action.The Java EE container automatically instantiates a contextual instance of the Game bean and the Generator bean.After the Game bean is created, its reset() method is called to initialize a number of variables such asbiggest, which holds the value for the maximum number of guesses, and number, which holds the randomly generated numberthat the user needs to guess.The Game bean gets the maximum number of guesses from its maxNumber field. Recall that a dependency injectionpoint with the qualifier annotation, @MaxNumber, is specified for the maxNumber field. Recall too thata producer method, getMaxNumber(), in the Generator bean is associated with the @MaxNumberqualifier annotation.As a result, when the Game bean accesses the @MaxNumber field, it calls the getMaxNumber()method in the Generator bean. The getMaxNumber() method returns the value of the maxNumberfield, that is, 100.The Game bean takes a similar route to provide a random number for the user to guess. The bean calls therandomNumber.get() method as part of its post-construct initialization. Recall that a dependency injection point with thequalifier annotation, @Random, is specified for the randomNumber field, and a producer method,getRandom(), in the Generator bean is associated with the @Random qualifier annotation.As a result, when the Game bean calls the randomNumber.get() method, it invokes the getRandom()method in the Generator bean. The randomNumber.get() method uses the getRandom()method of the java.util.Random class to generate a random number within the range 0 to 100.Running the Sample CodeA sample application accompanies this tip. To run the sample application, do the following:If you haven't already done so, download a recentpromoted build ornightly build of the GlassFish v3 Previewapplication server.Download the sample application package, weld-guess.zipExtract the contents of the sample application package. You should see the WAR file for the application,weld-guess.war, as well as folders for the application source code.The source code for the UI is in the web folder. The source code for the beans and annotations are in thesrc folder.Start the GlassFish v3 Preview application server by entering the following command: <GFv3_inst>/bin/asadmin start-domainwhere <GFv3_inst> is where you installed the GlassFish v3 Preview application server.Deploy the sample application by copying the weld-guess.war file to the<GFv3inst>/domains/domain1/autodeploy directory.Execute the application by opening a browser and accessing the URL http://localhost:8080/weld-guessFurther ReadingFor more information, see the following resources:JSR 299: Contexts and DependencyInjection (CDI)JSR 330: Dependency Injection For JavaJSR 314: JavaServer Faces 2.0JSR 250: Common Annotations for the Java PlatformContext And Dependency Injection (JSR 299) and ServletsAbout the AuthorRoger Kitain is the JavaServer Faces co-specification lead. He has been extensively involved with server-side web technologiesand products since 1997. Roger started working on JavaServer Faces technology in 2001, as a member of the referenceimplementation team. He has experience with Servlet and JSP technologies. Most recently, Roger has been involved withthe CDI specification and integration of CDI with the GlassFish container. Read Roger Kitain'sblog.

by Roger Kitain This Tech Tip covers the intersection of three powerful technologies that are part of the Java EE 6 platform: JSR 299: Contexts and DependencyInjection, JSR 330: Dependency Injection...

Enterprise Java technology

Locking and Concurrency in Java Persistence 2.0

by Carol McDonaldThe Java Persistence API (informally referredto as JPA) provides a plain old Java object (POJO)-based persistence modelfor Java EE and Java SE applications. It handles the details of how relational data is mapped to Java objects, and itstandardizes Object/Relational (O/R) mapping. The latest update to JPA,Java Persistence 2.0, adds a number of newfeatures such as additional O/R mapping functionality and new query language capabilities. Another area thathas been enhanced in JPA 2.0 is locking and concurrency.This Tech Tip highlights the new locking and concurrency features in JPA 2.0 and provides an application that demonstrates these capabilities.Locking and ConcurrencyLocking is a technique for handling database transaction concurrency. When two or more database transactions concurrentlyaccess the same data, locking is used to ensure that only one transaction at a time can change the data.There are generally two locking approaches: optimistic and pessimistic. Optimistic locking assumes that therewill be infrequent conflicts between concurrent transactions, that is, they won't often try to read and change thesame data at the same time. In optimistic locking, the objective is to give concurrent transactions a lot of freedomto process simultaneously, but to detect and prevent collisions. Two transactions can accessthe same data simultaneously. However, to prevent collisions, a check is made to detect any changes made to the datasince the data was last read.Pessimistic locking assumes that transactions will frequently collide. In pessimistic locking, a transaction thatreads the data locks it. Another transaction cannot change the data until the first transaction commits the read.Optimistic locking works best for applications where concurrent transactions do not conflict. Pessimistic lockingworks best where concurrent transactions do conflict.With JPA it is possible to lock an entity. This allows you to control when, where, and which kind of locking to usefor an entity. Recall that in JPA, an entity is a lightweight persistence domain object. Typically, an entity representsa table in a relational database, with each entity instance corresponding to a row in that table.Locking Support in JPA 1.0JPA 1.0 only supports optimistic read or optimistic write locking. In this support, any transaction can readand update an entity. However, when a transaction commits, JPA checks the version attribute of the entityto determine if it was updated since the entity was last read. If the version attribute was updated sincethe entity was last read, JPA throws an exception. The advantage of this approach is that no database locks are held.This can result in better scalability than for pessimistic locking. The disadvantage of this approach is that the useror application must refresh and retry failed updates.A versioned entity is marked with the @Version annotation, as illustrated in the following codesnippet: public class User { @ID int id; @Version int version;and its corresponding database schema has a version column, such as that created by the following SQL statement: CREATE TABLE USER (ID NUMBER NOT NULL, VERSION NUMBER), PRIMARY KEY (ID));The version attribute can be an int, short, long, or timestamp. It is incremented when a transactionsuccessfully commits. This results in an SQL operation such as the following: UPDATE User SET ..., version = version + 1 WHERE id = ? AND version = readVersionFigure 1 illustrates optimistic locking.Figure 1. Optimistic LockingHere, two concurrent transactions attempt to update Part p. Transaction 1 commits first. In response,JPA increments the version attribute for the p entity. When Transaction 2 commits, JPAthrows an OptimisticLockException because the version attribute for the p entityis higher than it was when Transaction 2 last read the p entity. As a result, Transaction 2 is rolled back.You can further control the way JPA manages locking on a versioned entity by specifying a lock mode. You do this throughthe lock() method of the EntityManager class. Here is the method signature: public void lock(Object entity, LockModeType lockMode);The first method parameter is the entity instance that needs to be locked in the transaction. The second method parameteris the lock mode.In JPA 1.0, the lock mode value could only be one of the following:READ. In this case, the JPA entity manager performs the optimistic locking operations as previouslydescribed. It locks the entity and before a transaction commits, checks the entity's version attribute todetermine if it has been updated since the entity was last read. If the version attribute has been updated, the entitymanager throws an OptimisticLockException and rolls back the transaction.WRITE. In this case, the entity manager performs the same optimistic locking operations as forthe READ lock mode. However, it also updates the entity's version column.Additional Locking Support in JPA 2.0JPA 2.0 adds five new lock modes. Two of these are used for optimistic locking. JPA 2.0 also adds support for pessimisticlocking and provides three lock modes for pessimistic locking. The two new optimistic lock modes are:OPTIMISTIC. This is the same as the READ lock mode. The READ lock mode isstill supported in JPA 2.0, but specifying OPTIMISTIC is recommended for new applications.OPTIMISTIC_FORCE_INCREMENT. This is the same as the WRITE lock mode. The WRITElock mode is still supported in JPA 2.0, but specifying OPTIMISTIC_FORCE_INCREMENT is recommended for newapplications.The three new pessimistic lock modes are:PESSIMISTIC_READ. The entity manager locks the entity as soon as a transaction reads it. Thelock is held until the transaction completes. This lock mode is used when you want to query data usingrepeatable-read semantics. In other words, you want to ensure that the data is not updated between successive reads.This lock mode does not block other transactions from reading the data.PESSIMISTIC_WRITE. The entity manager locks the entity as soon as a transaction updates it.This lock mode forces serialization among transactions attempting to update the entity data.This lock mode is often used when there is a high likelihood of update failure among concurrentupdating transactions.PESSIMISTIC_FORCE_INCREMENT. The entity manager locks the entity when a transactionreads it. It also increments the entity's version attribute when the transaction ends,even if the entity is not modified.JPA 2.0 also provides multiple ways to specify the lock mode for an entity. You can specify the lock modein the lock() and find() methods of the EntityManager. In addition,if you call the EntityManager.refresh() method, it refreshes the state of the entity instancefrom the database and locks it based on the entity's lock mode.You can also set the lock mode for a query through the setLockMode() method of the Queryinterface. And you can specify a lock mode for the results returned by a named query through thesetLockMode element of the @NamedQuery annotation.Let's look at some examples of the new locking support in JPA 2.0.OPTIMISTIC Lock ModeThe typical use case for OPTIMISTIC lock mode is where an entity has an intrinsic dependency on one ormore entities to ensure consistency, for example, when there is a relationship between two entities. In the exampleshown in Figure 2, Transaction 1 on the left updates the price for part p1. Thisincrements p1s version attribute. Transaction 2 on the right submits a bid for a user,u1. If the part price is lower than the user's current bid, Transaction 2 increases the bid.Figure 2. Using OPTIMISTIC Lock ModeIn this scenario, you don't want Transaction 2 to commit if Transaction T1 changes the price for the partafter Transaction T2 reads the price. So OPTIMISTIC lock mode is a good choice: em.lock(p1, OPTIMISTIC);Before committing Transaction 2, the entity manager checks the version attribute for the p1 entity.The p1 version attribute is higher than when p1 was last read, so the entity manager throws anOptimisticLockException and rolls back Transaction2. Note that checking u1s versionattribute for an update would not throw an exception. That's because Transaction 1 updates p1sversion attribute — it does not increment u1s version attribute.OPTIMISTIC_FORCE_INCREMENT Lock ModeOPTIMISTIC_FORCE_INCREMENT lock mode causes an optimistic lock failure if another transaction tries tomodify the locked entity. The common use for this lock is to guarantee consistency among entities in a relationship.Figure 3 shows an example of OPTIMISTIC_FORCE_INCREMENT lock mode.Figure 3. Using OPTIMISTIC_FORCE_INCREMENT Lock ModeTransaction 2 on the right wants to ensure that the price for a part p1 does not change during the transaction,so it locks the p1 entity as follows: em.lock(p1, OPTIMISTIC_FORCE_INCREMENT);Transaction 2 then calls em.flush()— this increments p1s version attributein the database. Any parallel attempt to update p1 will throw an OptimisticLockException androll back. As you can see, Transaction 1 attempts to update p1s price after Transaction 2 callsem.flush(). When Transaction T1 attempts to commit, the entity manager checks the p1version attribute. Because the attribute has been updated since the last read, the entity managerthrows an OptimisticLockException and rolls back Transaction T1.PESSIMISTIC Lock ModesThe pessimistic lock modes lock a database row when data is read. This is the equivalent to the actiontaken in response to the SQL statement SELECT . . . FOR UPDATE [NOWAIT]. Pessimistic locking ensuresthat transactions do not update the same entity at the same time. This can simplify application code, but it limitsconcurrent access to the data, something that can cause poor scalability and may cause deadlocks. Pessimistic lockingis better for applications with a higher risk of contention among concurrent transactions.The following figures show various examples of PESSIMISTIC lock modes:Figure 4 shows an example of reading an entity and in a later stepsetting it in PESSIMISTIC_READ lock mode.Figure 5 shows an example of reading an entity and at the same timesetting it in PESSIMISTIC_WRITE lock mode.Figure 6 shows an example of reading an entity and in a later stepsetting it in PESSIMISTIC_WRITE lock mode.Figure 4. Setting PESSIMISTIC_READ Lock Mode After Reading an EntityFigure 5. Setting PESSIMISTIC_WRITE Lock Mode While Reading an EntityFigure 6. Setting PESSIMISTIC_WRITE Lock Mode After Reading an EntityThe right locking approach to use depends on your application. Some questions you might want to ask to help make the decisionare:What is the risk of contention among concurrent transactions?What are the requirements for scalability?What are the requirements for user retrying after a failure?Sample Application Accompanying this tip is a sample application that demonstrates some of the locking supportin JPA 2.0. The application is also available in the Java EE 6SDK Preview release — look for "The Java Persistence API Locking Sample Application" in thesamples directory of the Java EE 6 SDK Preview release download package.The application consists of a client, a servlet, entity classes for part and user data, and stateless session beans thatprovide the logic for accessing and updating the data. The client calls the servlet to initialize the data. The client thenmakes multiple requests to the servlet that simulate parallel read and update operations. These operations are performedby the beans. Some of the operations are performed using optimistic locking, some using pessimistic locking. For example,the following method, updateWithOptimisticReadLock() demonstrates parallel operations performed usingoptimistic locking. public boolean updateWithOptimisticReadLock(int uID, int s) { boolean updateSuccessfull = true; // find part update price partEJB.updatePrice(uID, s); simulateThinkTimeForSecond(s); // find user and part, lock part OPTIMISTIC, update user userEJB.updateBid(uID, s); try { em.flush(); } catch (OptimisticLockException e) { System.out.println("updateWithOptimisticReadLock OptimisticLockException while updating with Optimistic Lock. " + "The transaction will be rolled back"); updateSuccessfull = false; } catch (PersistenceException e) { System.out.println("Got Exception while updating with optimstic lock" + e); updateSuccessfull = false; } System.out.println("updateWithOptimisticReadLock " + " updateSuccessful? " + updateSuccessfull); return updateSuccessfull; }The updateWithOptimisticReadLock() method calls the updatePrice() method in the partEJBbean to find a user and then update the price of a part. The updateWithOptimisticReadLock() method then waits toallow parallel method calls to find other users before calling the updateBid() method in the userEJBbean. The updateBid() method sets an optimistic lock for the part and then submits a user bid that is based on thepart price, as shown below: public void updateBid(int uID, int s) { User u = em.find(User.class, uID); int pID = u.getPart().getId(); Part p = em.find(Part.class, pID); em.lock(p, LockModeType.OPTIMISTIC); System.out.println("UserManagmentBean updateBid " + " for userId " + uID); if (p.getPrice() <= u.getBid() && ! (p.isSold())) { u.setBid(u.getBid() +10); } }The updateWithOptimisticReadLock() method then calls em.flush(). At that point, the entitymanager performs a version check on the part entity. If any transaction submitted by any of the other users updates the partwhile it is locked, the entity manager increments the part's version attribute. If the version attribute for the partis higher than it was when the part was last read by the set bid transaction, the updateWithOptimisticReadLock()method throws an OptimisticLockException and rolls back that transaction.You can find the source code for the application in the /samples/javaee6/jpa/locking directory.To run the sample application, do the following:If you haven't already done so, download the Java EE 6SDK Preview release. Also be sure to have an installed version of theJava Platform Standard Edition (Java SE) 6 SDK.Download the sample application.Set up your build environment and configure the application server byfollowing the common build instructions.Change to the samples_install_dir/javaee6/jpa/locking directory, wheresamples_install_dir is where you installed the sample application.Build, deploy, and run the sample application by entering the following command on the command line: ant allYou can replace the ant all command with thefollowing set of commands:ant default — compiles and packages the application.ant dir — deploys the application to the application server.ant run — runs the test Java client.In response, you should see output similar to the following: [java] LockingJavaClient: Test is starting [java] Calling URL:http://localhost:8080/locking/test/?tc=initData&nc=6 &ns=3&np=3 [java] [java] Starting parallel updates with 9 users for operation: updateWOL [java] Calling URL:http://localhost:8080/locking/test/?tc=updateWOL&uid=1 [java] Calling URL:http://localhost:8080/locking/test/?tc=updateWOL&uid=2 [java] Calling URL:http://localhost:8080/locking/test/?tc=updateWOL&uid=7 [java] Calling URL:http://localhost:8080/locking/test/?tc=updateWOL&uid=9 [java] Calling URL:http://localhost:8080/locking/test/?tc=updateWOL&uid=5 [java] Calling URL:http://localhost:8080/locking/test/?tc=updateWOL&uid=3 [java] Calling URL:http://localhost:8080/locking/test/?tc=updateWOL&uid=8 [java] Calling URL:http://localhost:8080/locking/test/?tc=updateWOL&uid=6 [java] Calling URL:http://localhost:8080/locking/test/?tc=updateWOL&uid=4 [java] Result for operation updateWOL for userId 1 is Success [java] Result for operation updateWOL for userId 2 is Success [java] Result for operation updateWOL for userId 5 is Failure [java] Result for operation updateWOL for userId 6 is Failure [java] Result for operation updateWOL for userId 7 is Failure [java] Result for operation updateWOL for userId 8 is Success [java] Result for operation updateWOL for userId 9 is Success [java] Result for operation updateWOL for userId 3 is Success [java] Result for operation updateWOL for userId 4 is Failure [java] Parallel updates executed with 9 users for operation: updateWOL Time taken:6146 miliseconds [java] ... [java] [java] Starting parallel updates with 9 users for operation: updateWPL [java] Calling URL:http://localhost:8080/locking/test/?tc=updateWPL&uid=2 [java] Calling URL:http://localhost:8080/locking/test/?tc=updateWPL&uid=5 [java] Calling URL:http://localhost:8080/locking/test/?tc=updateWPL&uid=3 [java] Calling URL:http://localhost:8080/locking/test/?tc=updateWPL&uid=9 [java] Calling URL:http://localhost:8080/locking/test/?tc=updateWPL&uid=1 [java] Calling URL:http://localhost:8080/locking/test/?tc=updateWPL&uid=4 [java] Calling URL:http://localhost:8080/locking/test/?tc=updateWPL&uid=7 [java] Calling URL:http://localhost:8080/locking/test/?tc=updateWPL&uid=6 [java] Calling URL:http://localhost:8080/locking/test/?tc=updateWPL&uid=8 [java] Result for operation updateWPL for userId 5 is Success [java] Result for operation updateWPL for userId 3 is Success [java] Result for operation updateWPL for userId 9 is Success [java] Result for operation updateWPL for userId 2 is Success [java] Result for operation updateWPL for userId 1 is Success [java] Result for operation updateWPL for userId 8 is Success [java] Result for operation updateWPL for userId 4 is Success [java] Result for operation updateWPL for userId 6 is Success [java] Result for operation updateWPL for userId 7 is Success [java] Parallel updates executed with 9 users for operation: updateWPL Time taken:15054 miliseconds [java] LockingJavaClient: Test is endedThe operations, which are identified in the tc parameter values in the URL calls, are as follows:updateWOL. Finds a part. Simulates think time to allow parallel threads to find users in parallel.Updates the part using optimistic locking.updateWOR. Finds a part and a user. Simulates think time to allow parallel threads to find users in parallel.Locks the part using optimistic locking. Updates the user.updateWOW. Finds a part and a user. Simulates think time to allow parallel threads to find users in parallel.Locks the part using an OPTIMISTIC_FORCE_INCREMENT lock. Updates the user.updateWRP. Finds a part. Simulates think time to allow parallel threads to find users in parallel.Locks the part using a PESSIMISTIC_READ lock. Updates the part.updateWRR. Finds a part. Simulates think time to allow parallel threads to find users in parallel.Refreshes using a PESSIMISTIC_WRITE lock. Updates the part.updateWPL. Finds a part using a PESSIMISTIC_WRITE lock. Simulates think time to allow parallel threads to findusers in parallel. Updates the part.Notice that some update operations that use optimistic locking, such as updateWOL, fail, while all updateoperations that use pessimistic locking, such as updateWPL, are successful. However, the time it takes to updateusing pessimistic locking is much higher than that taken using optimistic locking.Use the command ant clean to undeploy the sample application and to remove temporary directories.Further ReadingFor more information, see the following resources:PreventingNon-Repeatable Reads in JPA Using EclipseLinkJavaPersistence API 2.0: What's New ?What's New and Exciting in JPA 2.0Beginning Java EE 6 Platform withGlassFish 3: From Novice to ProfessionalJavaPersistence API: Best Practices and TipsAbout the AuthorCarol McDonald is a Java Technology Evangelist at Sun Microsystems. As a software developer since 1986, Carol's experiencehas been in the technology areas of distributed network applications and protocols, including Java EE technology, XML,Internet/Intranet applications, LDAP, Distributed Network Management (CMIP,SNMP) and Email (X.400,X.500). Besides Java,Carol is also fluent in French and German. Read Carol McDonald'sblog.

by Carol McDonald The Java Persistence API (informally referred to as JPA) provides a plain old Java object (POJO)-based persistence modelfor Java EE and Java SE applications. It handles the details of...

Enterprise JavaBeans Technology

A Sampling of EJB 3.1

by Ken SaksThe latest update to Enterprise JavaBeans (EJB) technology,EJB 3.1, is nearing completion.A Proposed Final Draft ofthe EJB 3.1 specification is now available. The main goals of this new specification are to further simplify developmentusing EJB technology and to add a number of long-requested features such as singleton beans.EJB 3.1 will be included in Java Platform, Enterprise Edition (Java EE) 6. A preview version of Java EE 6 is currentlyavailable for download. The preview version includesa nearly complete implementation of EJB 3.1 and a sample application that takes advantage of some of the new featuresin EJB 3.1.This Tech Tip introduces a few of these exciting new EJB 3.1 capabilities. It also includes instructions on howto run the EJB 3.1 sample application in the Java EE 6 preview.Ease of DevelopmentEJB 3.1 builds on the ease-of-use enhancements in EJB 3.0 by providing many new ways to improve developer productivity.Chief among these are the ability to implement session beans using only a bean class and the ability to package enterprisebean classes directly in a .war file, without the need for an ejb-jar file.No-interface ViewThe EJB 3.0 local client view is based on a plain old java interface (POJI) called a local business interface.A local interface defines the business methods that are exposed to the client and that are implemented on the bean class.Although this separation of interface and implementation is a well-accepted approach to application design, the separationsometimes is unnecessarily cumbersome and adds little value. This is especially true for very fine-grainedcomponents with closely coupled clients that are collocated in the same module.Developers have asked for a way to get the same enterprise bean functionality without having to writea separate business interface. The EJB 3.1 specification addresses this by making local business interfaces optional.The result is the no-interface local view.The no-interface view has the same behavior as the EJB 3.0 local view, for example, it supports features such aspass-by-reference calling semantics and transaction and security propagation. However, a no-interface view does not requirea separate interface, that is, all public methods of the bean class are automatically exposed to the caller. By default,any session bean that has an empty implements clause and does not define any other local or remote client views,exposes a no-interface client view.For example, the following session bean exposes a no-interface view: @Stateless public class HelloBean { public String sayHello() { String message = propertiesBean.getProperty("hello.message"); return message; } }As is the case for a local view, the client of a no-interface view always acquires an EJB reference -- either through injectionor JNDI lookup. The only difference is that the Java type of the EJB reference is the bean class type rather than the type ofa local interface. This is shown in the following bean client: @EJB private HelloBean helloBean; ... String msg = helloBean.sayHello();Note that even though there is no interface, the client cannot use the new() operator to explicitly instantiatethe bean class. That's because all bean invocations are made through a special EJB reference, or proxy, provided by the container.This allows the container to provide all the additional bean services such as pooling, container-managed transactions, andconcurrency management.Simplified PackagingThe EJB specification has always required that enterprise beans be packaged in an enterprise module called anejb-jar file. Since it is common for Java EE web applications to use enterprise beans, this packaging requirementcan be burdensome. These applications are forced to use a web application archive (.war file) forthe web application, an ejb-jar file for the enterprise beans, and an enterprise archive (.ear file)that encompasses the other packages. This packaging approach is further complicated by the special handling required forany classes or resources that must be shared between the modules.The EJB 3.1 specification addresses this problem by removing the restriction that enterprise bean classes must be packagedin an ejb-jar file. You now have the option of placing EJB classes directly in the .war file,using the same packaging guidelines that apply to web application classes. This means that you can place EJB classes underthe WEB-INF/classes directory or in a .jar file within the WEB-INF/libdirectory. The EJB deployment descriptor is also optional. If it's needed, you can package it as aWEB-INF/ejb-jar.xml file.New EJB 3.1 FeaturesBecause of the concentrated focus on ease of use in EJB 3.0, there was not enough time to add many of the otherfeatures that developers have requested. The EJB 3.1 specification adds a number of these features to the EJB API.Four of the new features are singleton session beans, application initialization/shutdown callbacks,asynchronous session bean invocations, and automatic EJB timers. This section describes singleton session beansand application initialization/shutdown callbacks.SingletonsA long-standing omission in the EJB API has been the ability to easily share state between multiple instancesof an enterprise bean component or between multiple enterprise bean components in the application. By contrast, theJava EE web application programming model has always provided this type of capability through aServletConfig object. In EJB 3.1, this omission has been addressed with the introduction ofsingleton beans, also known as singletons.A singleton is a new kind of session bean that is guaranteed to be instantiated once for an application ina particular Java Virtual Machine (JVM)\*. A singleton is defined using the@Singleton annotation, as shown in the following code example: @Singleton public class PropertiesBean { private Properties props; private int accessCount = 0; public String getProperty(String name) { ... } public int getAccessCount() { ... } }Because it's just another flavor of session bean, a singleton can define the same local and remote client viewsas stateless and stateful beans. Clients access singletons in the same way as they access stateless and statefulbeans, that is, through an EJB reference. For example, a client can access the above PropertiesBeansingleton as follows: @EJB private PropertiesBean propsBean; ... String msg = propsBean.getProperty("hello.message");Here, the container ensures that all invocations to all PropertiesBean references in the same JVM are servicedby the same instance of the PropertiesBean. By default, the container enforces the same threadingguarantee as for other component types. Specifically, no more than one invocation is allowed to access a particularbean instance at any one time. For singletons, that means blocking any concurrent invocations. However, this is just thedefault concurrency behavior. There are additional concurrency options that allow more efficient concurrent access tothe singleton instance.Application Startup/Shutdown CallbacksThe introduction of singletons also provides a convenient way for EJB applications to receive callbacks during applicationinitialization or shutdown. By default, the container decides when to instantiate the singleton instance. However,you can force the container to instantiate the singleton instance during application initialization by using the@Startup annotation. This allows the bean to define a @PostConstruct method that is guaranteedto be called at startup time. In addition, any @PreDestroy method for a singleton is guaranteed to be calledwhen the application is shutting down, regardless of whether the singleton was instantiated using lazy instantiationor eager instantiation. In lazy instantiation, the singleton isn't instantiated until it's method's are first needed.In eager instantiation, the singleton is instantiated at startup time whether or not it gets used.Here is an example that shows part of a singleton that includes a @Startup annotation as wellas @PostConstruct and @PreDestroy methods: @Singleton @Startup public class PropertiesBean { @PostConstruct private void startup() { ... } @PreDestroy private void shutdown() { ... } ... }Sample Application The Java EE 6 SDK Preview release includes anapplication that uses each of the EJB 3.1 features covered in this tip. The application is composed of a servlet,a singleton session bean, and a stateless session bean. Each session bean exposes a no-interfaceview. The singleton defines a callback that is called by the container during application initialization.Both the servlet and stateless bean use the singleton to access common application configuration information.When the servlet is accessed, it invokes both session beans and prints some messages containing the return values.The entire application is packaged within a .war file, without any .xml file.To run the sample application, do the following:If you haven't already done so, download the Java EE 6SDK Preview. Also be sure to have an installed version of theJava Platform Standard Edition (Java SE) 6 SDK.Download the sample application,ejb31-war.warStart the GlassFish V3 Prelude application server that is packaged with the Java EE 6 SDK by entering thefollowing command: <javaee_home>/bin/asadmin start-domainwhere <javaee_home> is where you installed the Java EE 6 SDK.Deploy the sample application by copying it to the <javaee_home>/domains/domain1/autodeploy directory.Execute the application by opening a browser and accessing the URL http://localhost:8080/ejb-ejb31-warYou should see the following output appear in a browser window: ejb31-war Servlet HelloBean says : Hello, world Singleton property access count = 2You can view the source code for the application in the <javaee_home>/samples/javaee6/ejb/ejb31-war/srcdirectory.Further ReadingFor more information, see the following resources:JSR-318 Enterprise JavaBeans 3.1(Proposed Final Draft)EnterpriseJavaBeans 3.1 (EJB 3.1) Technology OverviewEnterprise JavaBeans(EJB) technologyJava EE 6 SDK PreviewKen Saks's BlogAbout the AuthorKen Saks is the Specification Lead for EJB 3.1 and a Senior Staff Engineer in the Java EE team at Sun.Read his blog.\* As used on this web site, the terms "Java Virtual Machine" and"JVM" mean a virtual machine for the Java platform.

by Ken Saks The latest update to Enterprise JavaBeans (EJB) technology, EJB 3.1, is nearing completion. A Proposed Final Draft of the EJB 3.1 specification is now available. The main goals of this new...

Metro

A Common Ant Build File for Metro-Based Services and Clients

by Harold CarrMetro is a high performance, extensible, easy to use web service stack.It combines the JAX-WS reference implementation withWeb Services Interoperability Technologies (WSIT),formerly known as Project Tango. WSIT includes features that enable advanced web service interoperability withthe .NET Windows Communication Foundation (WCF), a set of technologies for building and running connected systems.Metro is bundled as part of the GlassFish Server,and runs in other containers such as Tomcat.An earlier Tech Tip,Testing Interoperability Between Metro and .NET, described an interoperability test in which a Metro-based clientcommunicates with a WCF-based service. In using Metro-based services for these tests, I sometimes start witha Web Service Definition Language (WSDL) file. Sometimes I build Metro-based services from Java classes. SometimesI deploy the services to containers. Sometimes I don't deploy to a container. To simplify the task of using Metro-basedservices for these tests, I have a common ant build.xml file. The file handles all these combinationsof web service sources and deployment approaches. This Tech Tip describes the contents and operation of thebuild.xml file.A .tar file, CommonAntBuild.tar, accompanies this tip. The tar file contains thecode and build files referenced in the tip. Note that the directory structure of the code uses symbolic linksthat work on UNIX and LINUX platforms. The tip assumes that you are running on a UNIX or LINUX platform.If you are running on a Windows platform, you will need to use other techniques for sharing common files -- these techniquesare not covered in this tip.Top-Level TargetsTo get started, let's see what the build.xml file advertises by entering thefollowing commands. Note that the commands in this tip assume that you haveconnected to the root directory of the source code associated with this tip. cd examples/from-java-container antIn response, you should see the following build file targets: help: [echo] service-from-wsdl-container : Builds, wars, deploys service [echo] service-from-java-container : Builds, wars, deploys service [echo] service-from-wsdl-publish : Builds, wars, publishes service [echo] service-from-java-publish : Builds, wars, publishes service [echo] service-undeploy : Undeploys the service WAR from the container [echo] client : Builds and runs the client [echo] clean : Delete all generated codeEach of the targets that begin with service-from- either builds a service from a WSDL descriptionor from a Java class annotated with @WebService. It then either creates a WAR file and deploys the warfile to a container or it invokes the Endpoint.publish() method to publish the web service endpoint usingthe HTTP server built into the Java platform.General Project LayoutHere is the general layout of a project that uses the common build file. cd examples/from-java-container ls -alF -rw-r--r-- 1 carr staff 74 May 27 09:21 .README lrwxr-xr-x 1 carr staff 5 May 27 09:00 build-common@ -> ../.. -rw-r--r-- 1 carr staff 436 May 27 09:06 build.properties lrwxr-xr-x 1 carr staff 29 May 27 09:00 build.xml@ -> build-common/build-common.xml drwxr-xr-x 4 carr staff 136 May 27 09:07 etc/ drwxr-xr-x 3 carr staff 102 May 27 08:44 src/To avoid duplicating files, I use symbolic links. The common build file is located in the root directory.It is named build-common.xml and linked in the current directory as build.xml.The following lines in the file import property files: <project basedir="." default="help" name="tango/code/build-common"> <property file="build.properties"/> <property file="${tools.properties}"/> <property file="${container.properties}"/>The first import is for the build.properties file in the current directory. The first two lines ofthe build.properties file define the other two property files to be imported. As shown below, thetwo other files to be imported are tools.properties and tomcat-container.properties: tools.properties=build-common/tools.properties container.properties=build-common/tomcat-container.propertiesThe tools.properties file defines settings for the wsgen and wsimportcommands. The wsgen command generates Java API for XML Web Services (JAX-WS) portable artifacts fora web service. The wsimport command generates JAX-WS portable artifacts for a web service client.Here are the contents of the tools.properties file: # WSGEN options wsgen.verbose=true wsgen.keep=true # WSIMPORT options wsimport.debug=false wsimport.verbose=false wsimport.keep=true wsimport.extension= wsimport.xendorsed=trueYou can either globally control settings for all the code that uses this property file or you can define a propertyfile specifically for a particular project.The tomcat-container.properties file sets up ant constants that are used to build and deploy a servicein a Tomcat container. Here are the contents of the tomcat-container.properties file: catalina.home=/usr/local/hc/java/apache/apache-tomcat-5.5.26 lib.home=${catalina.home}/shared/lib lib.endorsed=${catalina.home}/common/endorsed lib.glassfishv3=${catalina.home} deploy.dir=${catalina.home}/webappsNote that if you use Tomcat with the common build file, you need to have Metro already installed into Tomcat.There are two other properties files of interest in the root directory: glassfish-container.propertiesand no-container.properties. The glassfish-container.properties file sets up ant constantsthat are used to build and deploy a service in a GlassFish container. Here are the contents of theglassfish-container.properties file: #as.home=/Applications/NetBeans/glassfish-v2.1 as.home=C:/ProgramFiles/glassfish-v2.1 lib.home=${as.home}/lib" lib.endorsed=${as.home}/lib/endorsed" lib.glassfishv3=${as.home}/modules domain=domain1 deploy.dir=${as.home}/domains/${domain}/autodeployHere are the contents of the no-container.properties file: metro.home=/Users/carr/ws/wsit/wsit/dist/image/metro/lib lib.home=${metro.home} lib.endorsed=${metro.home} lib.glassfishv3=${metro.home} deploy.dir=/tmpThe no-container.properties file points directly to the image created when building Metro.This allows users to test the latest bits. In general, most people will not want to download Metro source, but they will wantto try building a service without deploying it to a container, that is, simply publishing the service endpoint usingthe Endpoint.publish() method. In that case, use the GlassFish or Tomcat settings to get the Metro code --the deploy.dir assignment will be ignored.Building a Service From Java Classes and Deploying To a ContainerLet's take a closer look at what's in the build.xml file and see how it's used. Let's begin byexamining the project that builds a Metro web service from a Java class and deploys the service to a container.First change to the from-java-container directory: cd examples/from-java-containerThe .README file in this directory shows the ant tasks necessary to build and deploy the service,to run the client, to do cleanup, and to undeploy the service. Here are the contents of the .README file: ant service-from-java-container ant client ant clean ant service-undeployBuilding and Deploying the ServiceThe first ant task in the .README file runs the service-from-java-container target.Here is the definition of that target in the build.xml file: <target name="service-from-java-container" depends="clean, setup, setup-war, service-compile, service-wsgen, service-war, service-deploy"/>The service-from-java-container target initially runs the following targets:clean - Removes any previously generated and/or compiled code.setup - Creates a build/classes directory.setup-war - Creates a build/war directory.service-compile - Compiles the pertinent Java classes.service-wsgen - Runs the wsgen command to generate portable artifacts forthe web service.service-war - Creates a WAR file for the compiled and generated code.service-deploy - Deploys the WAR file to the deploy directory of the container.Here is what the service-compile target looks like: <target name="service-compile" depends="setup"> <javac fork="true" srcdir="${basedir}/src" destdir="${build.classes.home}" includes="\*\*/service/\*\*,\*\*/common/\*\*"> <classpath refid="wsit.classpath"/> </javac> </target>The service-compile target runs the javac compiler on all Java classes found in directoriesnamed service and common (note that common is not used in this example).A Java class annotated with @WebService is found and compiled (not shown).Here is what the service-wsgen target looks like: <target name="service-wsgen" depends="setup"> <wsgen verbose="${wsgen.verbose}" keep="${wsgen.keep}" destdir="${build.classes.home}" sei="${service.wsgen.sei}" > <classpath path="${build.classes.home}"/> </wsgen> </target>The service-wsgen target invokes the wsgen command to generate server-side artifacts, such asJAXB marshaling code, for the web service. The target uses wsgen settings from the tools.propertiesand service.wsgen.sei variables defined in the build.properties file of the current directory.For example, here is the service.wsgen.sei setting in the build.properties file in thefrom-java-container directory: service.wsgen.sei=fromjava.service.AddNumbersImplThe service.wsgen.sei setting is the service endpoint interface (SEI) for the web service, that is,a Java class that contains a @WebService annotation.Here are the contents of the service-war target: <target name="service-war"> <war warfile="${service.war.file}" webxml="etc/web.xml"> <webinf dir="${etc.dir}" includes="sun-jaxws.xml"/> <zipfileset dir="${etc.dir}" includes="\*.wsdl, \*.xsd" prefix="WEB-INF/wsdl"/> <classes dir="${build.classes.home}"/> </war> </target>The service-war target creates a WAR file that contains the compiled and generated code. It also includes\*.xml files (and \*.wsdl and \*.xsd files - not used in this example). The name ofthe WAR file is defined in build.properties of the current directory, as follows: service.war.filename=wsit-enabled-fromjava.warHere is what the service-deploy target looks like: <target name="service-deploy"> <copy file="${service.war.file}" todir="${deploy.dir}"/> </target>The service-deploy target copies the WAR file to the deploy directory of the container.Creating the ClientThe second ant task in the from-java-container .README file runs the client target.The client target builds the client and then runs it. Building the client runs theclient-wsimport, client-compile, and client-cp-config targets in thebuild.xml file.Here is the definition of the client-wsimport target: <target name="client-wsimport" depends="setup"> <wsimport debug="${wsimport.debug}" verbose="${wsimport.verbose}" keep="${wsimport.keep}" extension="${wsimport.extension}" xendorsed="${wsimport.xendorsed}" destdir="${build.classes.home}" wsdl="${client.wsimport.wsdl}" package="${client.wsimport.package}" > <binding dir="${etc.dir}" includes="${client.wsimport.binding}"/> </wsimport> </target>The client-wsimport target invokes the wsimport command. The target picks upclient.wsimport.wsdl, client.wsimport.package, andclient.wsimport.binding settings in the build.properties file in the current directory(client.wsimport.binding is not used in this example).Here are the settings in the build.properties file: address=http://localhost:8080/wsit-enabled-fromjava/addnumbers client.wsimport.wsdl=${address}?wsdl client.wsimport.package=fromwsdl.clientThe target action retrieves the WSDL file of the deployed service and places the generated code in thefromwsdl.client package. You can implement finer-grained control of JAXB bindings by supplyinga client.wsimport.binding file.Here is the definition of the client-compile target: <target name="client-compile" depends="setup"> <javac fork="true" srcdir="${basedir}/src" destdir="${build.classes.home}" includes="\*\*/client/\*\*,\*\*/common/\*\*"> <classpath> <path refid="wsit.classpath"/> <pathelement path="${client.compile.classpath.extra}"/> </classpath> </javac> </target>The client-compile target runs the javac compiler on all the Java source code for the project thatit finds in the client and common directories under src.Here is the definition of the client-cp-config target: <target name="client-cp-config" depends="setup"> <copy todir="${build.classes.home}"> <fileset dir="${etc.dir}" includes="client-\*.xml"/> </copy> </target>The client-cp-config target copies any The client-cp-config target defines the main class and optionally defines a switch to controlwhether Metro dumps the HTTP messages that are sent and received. It also optionally passes values to the main class.The target uses the following settings from the build.properties file: client.main=fromjava.client.AddNumbersClient #client.http.dump=trueThe following ant tasks do final clean up by deleting the build directory and undeploying theservice from the container. ant clean ant service-undeployBuilding a Service From a WSDL File and Deploying To a ContainerNow let's examine the project that builds a Metro web service from a WSDL file and deploys the service to a container.Change to the from-wsdl-container directory: cd examples/from-wsdl-containerThe ant tasks for building a service from WSDL are similar to those for building a service froma Java class. The difference is that the service-wsimport target runs before the service-compiletarget, and the service-wsgen target does not run at all.The service-wsimport target generates code from a WSDL file similarly to the way the client-wsimporttarget does on the client-side in building a service from a Java class. However, in the service-wsimport case,the WSDL file is located in the file system as defined in the build.properties file, rather than accessedfrom the network. Here are the settings in the build.properties file in the from-wsdl-containerdirectory: service.wsimport.wsdl=etc/AddNumbers.wsdl service.wsimport.package=fromwsdl.serviceThe .README file in the from-wsdl-container directory shows the ant tasks to build a service froma WSDL file and deploy it to a container. With the exception of the initial task, the tasks are the same as for buildinga service from a Java class and deploying it to a container. The client tasks are exactly the same because the clientshould know nothing about the implementation of the web service.Here are the contents of the .README file: ant service-from-wsdl-container ant client ant clean ant service-undeployBuilding a Service From a Java Class and Publishing ItSo far we've examined projects that build a web service and deploy it to a container. Now let's examine projectsthat build a service and publish the web service endpoint.Change to the from-java-publish directory: cd examples/from-java-publishThe .README file shows the ant tasks to build and publish the service. Here is the initial task: ant service-from-java-publish &The & at the and of the command is the way to run a UNIX or LINUX process in the background.(Running the process in the background allows me to use the same shell for further commands. However, spawninganother shell works well too.)Here is the definition of the service-from-java-publish target in the build.xml file: <target name="service-from-java-publish" depends="clean, setup, service-compile, service-wsgen, service-cp-config, service-publish"/>As is the case for building a service from a Java class and deploying it to a container, theservice-compile target compiles the user-written source code for the web service.The service-wsgen target then runs the wsgen command on the SEI.The service-cp-config target copies service-\*.xml files from theetc directory. Those files are useful for configuration files such as JAX-WS handlers.However, they are not used here.The service-publish target is where this project differs from service-from-java-container.Here is the definition of the service-publish target: <target name="service-publish"> <java fork="true" classname="${service.main}"> <jvmarg value="${service.http.dump.do}"/> <classpath> <path refid="wsit.classpath"/> <pathelement location="${build.classes.home}"/> </classpath> <arg value="${service.main.arg1}"/> <arg value="${service.main.arg2}"/> </java> </target>The service-publish target runs service.main and passes it jvmargs andmain args. The values for these variables are specified in the build.properties file in thefrom-java-publish directory as follows: address=http://localhost:8888/echo service.wsgen.sei=foo.service.Echo service.main=common.GenericPublisher service.main.arg1=${address} service.main.arg2=${service.wsgen.sei}Notice that the service.main class is GenericPublisher. Most of the code to publish an endpointis the same for the various projects in this example. Because of this, I use a GenericPublisherto do the publishing. I share this class, using symbolic links, will all the projects that publish. The GenericPublisheris given the address at which to publish the service and the SEI to be published. The class uses reflection to instantiate theSEI.Here are the contents of the GenericPublisher class: package common; import javax.xml.ws.Endpoint; public class GenericPublisher { public static void main(String[] av) { final String address = av[0]; final String serviceImplementationBeanClass = av[1]; try { final Object serviceImplementationBean = Class.forName(serviceImplementationBeanClass).newInstance(); Endpoint.publish(address, serviceImplementationBean); } catch (Throwable t) { t.printStackTrace(); } } }The steps to run the client are identical to those in the other projects in this example.Building a Service From a WSDL File and Publishing ItChange to the from-java-publish directory: cd examples/from-wsdl-publishThe .README file shows the ant tasks to build and publish the service. Here is the initial task: ant service-from-wsdl-publish &Here is the definition of the service-from-wsdl-publish target in the build.xml file: <target name="service-from-wsdl-publish" depends="clean, setup, service-wsimport, service-compile, service-cp-config, service-publish"/>The first steps in this process are similar to the service-from-java-container. The main differences arethe last steps. Instead of creating a WAR file and deploying it in a container, this process publishes the endpointusing the GenericPublisher, as specified in the following build.properties file settings: tools.properties=build-common/tools.properties container.properties=build-common/no-container.properties service.wsimport.wsdl=etc/AddNumbers.wsdl service.wsimport.package=fromwsdl.service address=http://localhost:8080/fromwsdl/addnumbers service.main=common.GenericPublisher service.main.arg1=${address} service.main.arg2=fromwsdl.service.AddNumbersImpl client.wsimport.wsdl=${address}?wsdl client.wsimport.package=fromwsdl.client client.main=fromwsdl.client.AddNumbersClient client.http.dump=trueAgain, the client steps are identical.SummaryThis Tech Tip showed a build.xml file that can be used with Metro to create a web service froma Java class or from a WSDL file and deploy the service in a web container or standalone using theEndpoint.publish method.It is also possible to create dynamic clients using the JAX-WSDispatch APIand dynamic services using the JAX-WSProvider API.Much of the ant build file described in this tip should work for those cases, but I have not tested it or extended it.I also use NetBeans in combination withGlassFish to create and deploy Metro-based servicesand clients. But it is often useful to have some test cases handy that can be used quickly from the commandline in different configurations. And that's the value of the ant build file covered in this tip.Further ReadingFor more information, see the following resources:Metro ProjectWeb Services Interoperability Technologies (WSIT)Testing Interoperability Between Metro and .NETJAX-WS Reference ImplementationJAX-WS APIsGlassFish

by Harold Carr Metro is a high performance, extensible, easy to use web service stack. It combines the JAX-WS reference implementation withWeb Services Interoperability Technologies (WSIT),formerly...

JAX-RS

Jersey and Spring

by Paul SandozJersey is an open-source, production-ready referenceimplementation of JAX-RS, the Java API for RESTfulWeb Services (JSR-311). JAX-RS is an annotation-driven API that makes it easy to build Java-based RESTful webservices that adhere to the REST architectural style. The JAX-RS API is standardized by the Java Community Process.The JAX-RS API is currently at version 1.0 and Jersey is at version 1.0.2.Jersey provides additional value beyond the JAX-RS API. It provides its own APIs that supportAtom's XML format,MIME MultiPart message format ,JavaScript Object Notation (JSON),Web Application Description Language (WADL),as well asSpring framework integration. Jersey is shipped with GlassFish and is available from the GlassFish version 2 and version 3update centers.An earlier Tech Tip,Implementing RESTfulWeb Services in Java, introduced RESTful Web Services, JAX-RS, and Jersey. It also showed howyou can write RESTful web services that conform to the JAX-RS specification. Other tips on Jersey-related topics describedhow toconfigure JSON for RESTfulweb services in Jersey 1.0 and how toconsume RESTful web serviceswith the Jersey client API.In this tip, you will learn how to use Jersey's integrated support forSpring, a framework for building and running enterpriseJava applications. You'll learn how to configure Spring with Jersey and use Jersey's Spring-related features.The tip assumes that you are familiar with Spring concepts. If not, refer to theSpring Tutorial.Creating a Basic Web ApplicationTo demonstrate Jersey's Spring-related features, you'll first create a simple web application, one that does notuse Spring and then change it to use Spring. Let's use theMaven 2 software project management toolto build the simple web application. If you're not familiar with Maven, seeWelcome to Maven andBuildingWeb Applications with Maven 2.First, create a Maven 2 project by running the following Maven 2 archetype plugin in a command line: mvn archetype:generate -DarchetypeCatalog=http://download.java.net/maven/2In response, Maven 2 will prompt you to choose an archetype, that is, a Maven 2 project template, from the archetypeslisted in the archetype catalog, archetype-catalog.xml, at URL http://download.java.net/maven/2: Choose archetype: 1: http://download.java.net/maven/2 -> jersey-quickstart-grizzly (Archetype for creating a RESTful web application with Jersey and Grizzly) 2: http://download.java.net/maven/2 -> jersey-quickstart-webapp (Archetype for creating a Jersey based RESTful web application WAR packaging) Choose a number: (1/2):Choose 2, jersey-quickstart-webapp. You will then be prompted for a group ID and an artifact ID. Enterexample.jersey.spring for the group ID and example-spring-jersey for the artifact ID.Accept the default values for the other prompts.After you confirm the inputs, Maven 2 creates a new subdirectory called example-spring-jersey, which containsa template for the new Jersey-based web application. Figure 1 shows the expanded structure of theexample-spring-jersey directory.Figure 1. Expanded Structure of the example-spring-jersey directoryMaven 2 also creates a Project Object Model (POM) file, pom.xml, which contains an XML representation of theMaven project. You can find the pom.xml file in the example-spring-jersey directory.If you navigate below the example-spring-jersey directory tosrc/main/java/example/jersey/spring, you'll see a Java class named MyResource thatrepresents a resource used in the application. You'll also find a web.xml file for the web applicationin the src/main/webapp/WEB-INF directory.Let's build, deploy, and test the web application to see if it works. To build the application, go to theexample-spring-jersey directory and enter the following command: mvn clean installIn response, Maven 2 compiles the source code and creates an example-spring-jersey.war filefor the application.To deploy the application, GlassFish V3 Prelude must be running. Start GlassFish V3 Prelude if it isn't already running.To start GlassFish V3 Prelude, enter the following command: <GF_install_dir/bin>asadmin start-domain domain1where <GF_install_dir/bin> is the directory where you installed GlassFish v3 Prelude.Deploy the application to GlassFish v3 Prelude using the following command: asadmin deploy --force=true target/example-spring-jersey.warFinally, you can verify that the deployed application runs by using the command line tool,curl, as follows: curl -v http://localhost:8080/example-spring-jersey/webresources/myresourceIn response, you should see the following output in the command window: \* About to connect() to localhost port 8080 (#0) \* Trying 127.0.0.1... connected \* Connected to localhost (127.0.0.1) port 8080 (#0) > GET /example-spring-jersey/webresources/myresource HTTP/1.1 > User-Agent: curl/7.17.1 (i586-pc-mingw32msvc) libcurl/7.17.1 OpenSSL/0.9.7c zib/1.2.3 > Host: localhost:8080 > Accept: \*/\* >< HTTP/1.1 200 OK< X-Powered-By: Servlet/2.5< Server: Sun Java System Application Server 9.1_02< Content-Type: text/plain< Transfer-Encoding: chunked< Date: Thu, 02 Apr 2009 22:18:29 GMT <dependency> <groupId>com.sun.jersey.contribs</groupId> <artifactId>jersey-spring</artifactId> <version>${jersey-version}</version> </dependency>Create a Spring Application Context Configuration: The Spring application context configuration filespecifies an application's configuration for initialization by Spring. You need to create a Spring application contextconfiguration file for the web application. Create a file applicationContext.xml and put it in thesrc/main/resources directory. The file should have the following content: <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <context:component-scan base-package="example.jersey.spring"/> </beans>This configuration directs Spring to use autowiring with Spring-based annotations and to scan for Spring-based resourcesin the Java package example.spring.jersey. Autowiring is a feature in Spring that allows it to introspectbean classes for dependencies so that you do not have to explicitly specify bean properties or constructor arguments.Modify the web.xml File: Replace the contents of the web.xml file withthe content shown here.The following code in the updated web.xml file declares the Spring application context configuration,created earlier as a servlet context parameter: <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param>The updated content also declares two listeners. The first configures Spring and the second configuresSpring for use with the request scope for Spring beans. <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener>Then, the file declares the Jersey Spring servlet, which supports the Jersey integration with Spring. <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class> </servlet>Modify the Root Resource Class: Modify the MyResource.java file in thesrc/main/java/example/jersey/spring directory with the following content: package example.jersey.spring; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; // The Java class will be hosted at the URI path "/myresource" @Path("/myresource") @Component @Scope("request") public class MyResource { // The Java method will process HTTP GET requests @GET // The Java method will produce content identified by the MIME Media // type "text/plain" @Produces("text/plain") public String getIt() { return "Hi there!"; } }The @Component annotation declares that the class is a Spring bean class.The @Scope("request") annotation declares that instances of this class will be instantiatedwithin the scope of the HTTP request. This highlights a difference between the default scopes for JAX-RS or Jerseyand Spring. The default scope for JAX-RS is per request. By comparison, the default scope for Spring is a singleton,that is, one instance per web application. See Supported Scopes for more information about thescopes that Jersey supports.The MyResource root resource class is functionally equivalent to the root resource class that you originallycreated, but it's now Spring-enabled.Verify that the Spring-enabled web application deploys and executes by entering the following commands in a command line: mvn clean install asadmin deploy --force=true target/example-spring-jersey.war curl -v http://localhost:8080/example-spring-jersey/webresources/myresourceAfter the Spring-enabled web application is successfully deployed, you should see outputsimilar to the following in the server.log(<GF_install_dir>/glassfish/domains/domain1/logs/server.txt): [PWC1412: WebModule[/example-spring-jersey] ServletContext.log():Initializing Spring root WebApplicationContext|#] [INFO| Root WebApplicationContext: initialization started|] [INFO| Refreshing org.springframework.web.context.support.XmlWebApplicationContext@53ecec: display name [Root WebApplicationContext]; startup date [Mon Apr 06 14:37:02 PDT 2009]; root of context hierarchy|#] [INFO| Loading XML bean definitions from class path resource [applicationContext.xml]|#] [INFO| Bean factory for application context [org.springframework.web.context.support.XmlWebApplicationContext@53ecec]: org.springframework.beans.factory.support.DefaultListableBeanFactory@c0267a|#] [INFO| Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@c0267a: defining beans [myResource,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor]; root of factory hierarchy|#] [INFO| Root WebApplicationContext: initialization completed in 891 ms|#] [INFO| Loading application example-spring-jersey at /example-spring-jersey|#] [INFO| Deployment of example-spring-jersey done is 4500 ms|#] [INFO| Registering Spring bean, myResource, of type example.jersey.spring.MyResource as a root resource class|#]Notice the final line that begins "Registering Spring bean". This is output from Jersey. Jersey knows that theclass MyResource is a root resource class and also a Spring bean class. No Jersey-specific configuration wasrequired to register root resource classes, as was the case in the web.xml for the original version of theweb application.Because Spring is used to register Spring beans, in this case using autowiring, Jersey leverages Spring to performregistration rather that requiring duplicate registration. It is possible to intermix Spring-managed and Jersey-managedroot resource classes by using Jersey's registration mechanism. It does not matter if both Spring and Jersey find the sameclass -- only one reference to the class will be managed appropriately.Supported ScopesJersey supports the following Spring scopes:Request. Scopes a single Spring bean definition to the lifecycle of a single HTTP request, that is, each HTTP request hasits own instance of a Spring bean created from a single Spring bean definition. This scope requires that you declare the SpringRequestContextListener servlet context in the web.xml file for the web application.Singleton. Scopes a single Spring bean definition to a single object instance per web application.Prototype. Scopes a single Spring bean definition to multiple object instances. A new Spring bean instance is created foreach request for that specific bean.You can inject Jersey artifacts into fields of Spring bean instances according to the scoping rules. If the scope isprototype, then the scoping rules for request apply. If Jersey does not recognize the scope, then it assumes a scopeof singleton for the purpose of injection.For example, you can modify the MyResource class in the Spring-enabled Web application to include an@QueryParam for injection. Here is what the modified class looks like: package example.jersey.spring; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; // The Java class will be hosted at the URI path "/myresource" @Path("/myresource") @Component @Scope("request") public class MyResource { @QueryParam("x") String x; // The Java method will process HTTP GET requests @GET // The Java method will produce content identified by the MIME Media // type "text/plain" @Produces("text/plain") public String getIt() { return "Hi there! " + x; } }In response, Jersey should inject the information into the Spring bean in request scope, that is, per request.To test that, you can redeploy and execute the updated application by entering the following commands in a command linewindow: mvn clean install asadmin deploy --force=true target/example-spring-jersey.war curl -v http://localhost:8080/example-spring-jersey/webresources/myresource?x=curlThe application should return "Hi there! curl" in the output. If it does, this verifies that Jersey can correctlyinject information into the Spring bean per request.SummaryThis tip showed you how to use some of Jersey's Spring-related features. But there are other useful elements toJersey's support for Spring. Some of the these are:You can take advantage of the JAX-RS support for hierarchical URI path matching to further match a URI path thatwas not already matched by a root resource. This means that you can include a subresource locator method in a resourceto return an instance of a newly created Spring bean class. You use the Jersey ResourceContext classto obtain the instance.You can inject Spring beans into JAX-RS-based methods. You do this with the Jersey @Inject annotation.You can use Jersey Spring-based Aspect-Oriented Programming (AOP).You can have Spring instantiate a resource class, but have Jersey manage the resource class's lifecycle.Further ReadingFor more information on Jersey and Spring, see the following resources:Jersey ProjectGettingStarted With JerseyJersey-Spring 1.0.2 API OverviewJersey-Spring Container Servlet PackageResourceContext Interface@Inject AnnotationAbout the AuthorPaul Sandoz is the co-spec lead and implementation lead for JSR 311: Java API for RESTful Web Services. He has participatedin the W3C, ISO, and ITU-T standards organizations and contributed various performance-related technologies and improvementsto the GlassFish web services stack, particularly in standardization, implementation, integration, and interoperability ofFast Infoset.2009 JavaOne Conference, June 2-5, San Francisco \*\* Register Now\*\*Stay on top of everything new and different, both inside and around Java technology. Register by April 22, 2009,and save $200 off a Conference Pass or Conference Plus Pass. Register now athttp://java.sun.com/javaone.

by Paul Sandoz Jersey is an open-source, production-ready reference implementation of JAX-RS, the Java API for RESTfulWeb Services (JSR-311). JAX-RS is an annotation-driven API that makes it easy to...

quiz

Tech Tips Quiz

Over the years, the Enterprise Java Technologies Tech Tips have covered a wide variety of enterprise Java technology topics.Here's a short quiz that tests your knowledge of some topics covered in recent Tech Tips. You can find the answers at the endof the quiz.You are developing an application that uses the Jersey 1.0.2 Client API to consume a RESTful web service. You createa Client object for the RESTful web service client. What do you need to create next so that theClient object can be used to issue web service requests?a. A ClientPipe object.b. A WebResource object.c. A ServiceRequest object.d. A ClientFactory object.e. None of the above.The following code snippet appears in a program that uses JAXB 2.0 to marshal an XML document: import javax.xml.bind.\*; import a.JustAType; import com.sun.xml.bind.marshaller.NamespacePrefixMapper; NamespacePrefixMapper m = new PreferredMapper(); marshal(jc, e, m); public static class PreferredMapper extends NamespacePrefixMapper { @Override public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) { return "mappedNamespace" + namespaceUri; } }What does the getPreferredPrefix() method in the PreferredMapper class do?a. Returns the preferred prefix, mappedNamespace to be declared at the root element of the marshalled XML.b. Returns the preferred namespace prefix, jc, and namespace URI, mappedNamespacee, to be declared at the rootelement of the marshalled XML. c. Returns the preferred prefix, mappedNamespacea, to be declared at the root element of the marshalled XML.d. Returns a list of preferred namespace prefixes, jc, e, and m, to be declaredin elements of the marshalled XML.e. None of the above.The javafx.servlet.sip.SipFactory interface provides utility methods to create a Session InitiationProtocol (SIP) request in an enterprise application. Which of the following statements about the SipFactoryinterface is true?a. A SipFactory instance can be injected into a Java EE component such as an EJB or MJB using the@SIP annotation.b. A SipFactory instance cannot be used in a Converged Enterprise Application.c. SipFactory instances that belong to multiple SIP applications can be injected into a Java EE component,whether the applications are co-located in the same .ear file or not.d. A SipFactory is specific to a SIP application and there can be only one SipFactory instancefor each SIP application.Metro supports the WS-Trust specification. Which of the following is not true about the WS-Trust support in Metro:a. Supports token refactoring.b. Supports token issuance and token validation protocols.c. Supports the Security Token Service (STS) frameworkd. Supports issuing SAML 1.0, SAML 1.1 and SAML 2.0 tokens, by default.e. Supports the issuing of symmetric proof keys, public proof keys, and no proof keys.Fill in the blank: When SOAP attachments are used in a SOAP message, the SOAP message is accompanied by a MIME headerand possibly ________ _________.a. Cipher referencesb. STS tokensc. Boundary partsd. User profilese. Signature valuesAnswersYou are developing an application that uses the Jersey 1.0.2 Client API to consume a RESTful web service. You createa Client object for the RESTful web service client. What do you need to create next so that theClient object can be used to issue web service requests?a. A ClientPipe object.b. A WebResource object.c. A ServiceRequest object.d. A ClientFactory object.e. None of the above.b. A WebResource object. After you create a Client instance, you can start using it. However, toissue requests, you need to create a WebResource object, which encapsulates a web resource for the client.You use the WebResource object to build requests to send to the web resource and to process responses returned fromthe web resource. For example, you can use the WebResource object for HTTP GET, PUT,POST, and DELETE requests. For more information about using the Jersey 1.0.2 Client API,see the February 26, 2009 Tech Tip,Consuming RESTful Web Services Withthe Jersey Client API.The following code snippet appears in a program that uses JAXB 2.0 to marshal an XML document: import javax.xml.bind.\*; import a.JustAType; import com.sun.xml.bind.marshaller.NamespacePrefixMapper; NamespacePrefixMapper m = new PreferredMapper(); marshal(jc, e, m); public static class PreferredMapper extends NamespacePrefixMapper { @Override public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) { return "mappedNamespace" + namespaceUri; } }What does the getPreferredPrefix() method in the PreferredMapper class do?a. Returns the preferred prefix, mappedNamespace to be declared at the root element of the marshalled XML.b. Returns the preferred namespace prefix, jc, and namespace URI, mappedNamespacee, to be declared at the rootelement of the marshalled XML. c. Returns the preferred prefix, mappedNamespacea, to be declared at the root element of the marshalled XML.d. Returns a list of preferred namespace prefixes, jc, e, and m, to be declaredin elements of the marshalled XML.e. None of the above.c. Returns the preferred prefix, mappedNamespacea, to be declared at the root element of the marshalled XML.JAXB 2.0 (or later) provides a service provider interface (SPI) named com.sun.xml.bind.marshaller.NamespacePrefixMapperthat you can use to specify helpful namespace prefixes for marshalling. You implement the SPI and pass it to theMarshaller. One of the methods in the NamespacePrefixMapper class is getPreferredPrefix(),which returns a list of namespace URIs that should be declared at the root element. In the code snippet,the getPreferredPrefix() method in the PreferredMapper class returns the preferred prefix,in this case, mappedNamespacea to be declared at the root element of the marshalled XML, as follows: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <mappedNamespacea:JustAnElement xmlns:mappedNamespacea="a"> <foo>true</foo> </mappedNamespacea:JustAnElement>To learn more about customizing namespace prefixes during marshalling, see the December 2, 2008 Tech TipCustomizing JAXB.The javafx.servlet.sip.SipFactory interface provides utility methods to create a Session InitiationProtocol (SIP) request in an enterprise application. Which of the following statements about the SipFactoryinterface is true?a. A SipFactory instance can be injected into a Java EE component such as an EJB or MJB using the@SIP annotation.b. A SipFactory instance cannot be used in a Converged Enterprise Application.c. SipFactory instances that belong to multiple SIP applications can be injected into a Java EE component,whether the applications are co-located in the same .ear file or not.d. A SipFactory is specific to a SIP application and there can be only one SipFactory instancefor each SIP application.d. A SipFactory is specific to a SIP application and there can be only one SipFactory instancefor each SIP application. The SipFactory instance is available in the servlet context of a SIP Applicationas an attribute of javax.servlet.sip.SipFactory. The servlet specification defines specific context attributesthat are used to store and retrieve information specific to SIP servlets and interfaces from the context. In the case ofJava EE components such as EJBs and MDBs, which are outside the scope of the servlet context, the SipFactoryis available as a resource. You can inject the resource into a Java EE component such as an EJB or MJB using the@Resource annotation. For more information about the SipFactory interface, SIP requests, and theiruse in converged enterprise applications, see the March 13, 2009 Tech Tip,Converged EnterpriseApplications.Metro supports the WS-Trust specification. Which of the following is not true about the WS-Trust support in Metro:a. Supports token refactoring.b. Supports token issuance and token validation protocols.c. Supports the Security Token Service (STS) frameworkd. Supports issuing SAML 1.0, SAML 1.1 and SAML 2.0 tokens, by default.e. Supports the issuing of symmetric proof keys, public proof keys, and no proof keys.a. Supports token refactoring. Metro is a high performance, extensible,easy-to-use web services stack. It combines the JAX-WS reference implementation with Project Tango. Project Tango, also calledWeb Services Interoperability Technology or WSIT, implements numerous WS-\* standards to enable interoperability with otherimplementations and to provide Quality of Service (QOS) features such as security, reliability, and transaction support.WS-Trust is a WS-\* specification that provides extensions to the WS-Security specification. Metro supports the WS-Trustspecification. In supporting WS-Trust, Metro: Supports token issuance and token validation protocols. Supports the STS framework. Supports building an STS as an independent web service. Supports client and service authentication and security with issued tokens from an STS within the general frameworkof WS-Security and WS-SecurityPolicy. Provides a general framework for building an STS as a web service for issuing security tokens. Supports authentication and secure communication between a client and an STS in the same way as for a regular web service. Supports issuing SAML 1.0, SAML 1.1 and SAML2.0 tokens, by default. Supports the issuing of symmetric proof keys, public proof keys, and no proof keys. Can be extended to support the issuing of other types of tokens. Allows for plugging in additional authorization mechanisms that control the issuing of tokens according to theuser's identity and the targeted service. Allows for plugging in user mappings that control the user identity/attributes carried in the SAML token issued byn STS for different services.However, it does not support token refactoring. For more information about WS-Trust support in Metro, see theOctober 14, 2008 Tech TipUsing WS-Trust Support in Metro to SecureWeb Services.Fill in the blank: When SOAP attachments are used in a SOAP message, the SOAP message is accompanied by a MIME headerand possibly ________ _________.a. Cipher referencesb. STS tokensc. Boundary partsd. User profilese. Signature valuesc. Boundary parts. When SOAP attachments are used in a SOAP message, the SOAP message is accompanied by a MIME header andpossibly multiple boundary parts. This is known as a SOAP message package. The primary SOAP envelope is generally conveyedin the first MIME part. The attachments are carried in other MIME parts and are referenced from the SOAP envelope. Learnmore about SOAP message attachments and how they can be secured with Metro in the September 29, 2008 Tech TipSecuring Attachments With Metro 1.3.2009 JavaOne Conference, June 2-5, San Francisco \*\* Register Now\*\*Stay on top of everything new and different, both inside and around Java technology. Register by April 22, 2009,and save $200 off a Conference Pass or Conference Plus Pass. Register now athttp://java.sun.com/javaone.

Over the years, the Enterprise Java Technologies Tech Tips have covered a wide variety of enterprise Java technology topics.Here's a short quiz that tests your knowledge of some topics covered in...

Enterprise Java technology

Converged Enterprise Applications

by Prasad SubramanianThe February 29, 2008 Tech Tip,Adding Voice to Java EE With SIP Servlets,introduced Session Initiation Protocol (SIP),a signaling protocol that is used to set up, modify, and terminate a session between two endpoints. It also introduced variousSIP-related concepts such as a SIP container -- a server-side container of SIP components or services -- and a SIPservlet -- a servlet that runs in a SIP container and that supports the SIP protocol. The tip mentioned that together, SIP and SIPservlets, are behind many popular telecommunications-based applications that provide services such as Voice-over-IP (VoIP),instant messaging, presence and buddy list management, as well as web conferencing. In addition, the tip presented a sample webapplication that uses SIP servlets and HTTP servlets to provide VoIP phone service.SIP and SIP servlets are also important in the enterprise. Combined with Java EE technology, SIP servlets can be used to addrich media interactions to enterprise applications. For example, a Java EE-conforming enterprise application that supports SIPcould process voice calls or calls in other media. In such an application, an Enterprise JavaBeans (EJB) technology componentcould set up a SIP-related call and a SIP servlet could invoke an EJB component or a connector resource.The SIP Servlet API v1.1 specification (JSR 289) defines thecontract between SIP servlets and a Java EE-conforming enterprise application. JSR 289 makes it easier for application developersto use the Java EE model for developing applications that process SIP requests and responses.One of the concepts introduced in the earlier tip is that of a converged application, that is, an application that includesboth SIP and HTTP servlets. In this tip, you'll learn about converged enterprise applications and how the SIP Servlet API v1.1specification simplifies the development of converged enterprise applications. You'll also find asample converged enterprise application that demonstrates the concepts and techniques covered in this tip.What's a Converged Enterprise Application?A converged enterprise application is an enterprise application that has a SIP servlet application bundled within it.An enterprise application is typically packaged in an enterprise archive file whose extension is .ear. The packagemay include an application.xml file, which describes the content of the modules within the enterprise application.Here, the term module refers to the web application and any EJB or connector archive files bundled within the application.Note that including an application.xml in an enterprise application package is optional. However, even if anapplication.xml file is not included, it is possible to bundle a SIP application within the enterprise application.In this case, the SIP Application is bundled in the same way as other applications such as web applications or the wayEJB modules are bundled in a descriptor-less enterprise application.A converged enterprise application is also packaged in an enterprise archive file with a .ear extension.The bundled SIP application is described as a web module in the application.xml file. The following code snippetis an example of how a bundled SIP application is described in an application.xml file: <?xml version="1.0" encoding="UTF-8"?> <application version="5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd"> <display-name>ConvergedEnterprise</display-name> <module> <web> <web-uri>ConvergedSipApplication.war</web-uri> <context-root>/ConvergedSipApplication</context-root> </web> </module> <module> <ejb>TalkBack.jar</ejb> </module></application>Converged Enterprise Applications and SIPAs mentioned earlier, the SIP Servlet API v1.1 specification makes it easier for application developers to use the Java EE modelfor developing applications that process SIP requests and responses. For example, consider an EJB component such as a MessageDriven Bean (MDB). If the MDB receives a message, it could use the APIs defined in SIP Servlet API v1.1 to invoke a SIP request.Similarly, a SIP servlet that receives an INVITE request could invoke an EJB component from the SIP servlet'sdoInvite() method to do some complex processing logic. Or a connector resource could be invoked from within theSIP Servlet to access an external subsystem such asa Home Subscriber Server (HSS) forauthentication or a media server to process media.Let's examine some aspects of SIP Servlet API v1.1 as it relates to SIP servlets and Java EE components.SIP Servlet-Java EE Component InterfaceThe SIP Servlet API v1.1 specification defines the interface between Java EE components and SIP servlet applications.Typically, you invoke a SIP request from a Java EE component such as an EJB MDB or invoke an EJB orconnector resource from a SIP servlet.You use the javax.servlet.sip.SipFactory interface to invoke a SIP request from a Java EE component.This interface provides utility methods to create a SIP request in an enterprise application. The methods are summarizedin Table 1. Note that the methods in bold are the ones that are used to create a SIP Request.Table 1: SipFactory MethodsMethod SignatureDescriptioncreateAddress(java.lang.String addr)Returns an Address object corresponding to the specified string.createAddress(URI uri)Returns an Address object with the specified URI and no display name.createAddress(URI uri, java.lang.String displayName)Returns a new Address object with the specified URI and display name.createApplicationSession()Returns a new SipApplicationSession object.createApplicationSessionByKey(java.lang.String sipApplicationKey) Returns a new SipApplicationSession object identified by the specified SipApplicationKey.createAuthInfo() Creates a new AuthInfo object that can be used to provide authentication information on servlet initiated requests.createParameterable(java.lang.String s) Creates a new Parameterable object parsed from the specified string.createRequest(SipApplicationSession appSession, java.lang.String method, Address from, Address to)Returns a new request object with the specified request method, From, and To headers.createRequest(SipApplicationSession appSession, java.lang.String method, java.lang.String from, java.lang.String to)Returns a new request object with the specified request method, From, and To headers.createRequest(SipApplicationSession appSession, java.lang.String method, URI from, URI to)Returns a new request object with the specified request method, From, and To headers.createSipURI(java.lang.String user, java.lang.String host)Returns a new SipApplicationSession object identified by the specified SipApplicationKey.createURI(java.lang.String uri) Returns a URI object corresponding to the specified string, which should represent an escaped SIP, SIPS, or tel URI. A SipFactory instance is specific to a SIP Application and there can only be one SipFactory instance foreach SIP Application. The SipFactory instance is available in the servlet context of that SIP Application as anattribute of javax.servlet.sip.SipFactory. Recall that the servlet context as defined in the servlet specificationalso applies to SIP servlets. The servlet specification defines specific context attributes that are used to store and retrieveinformation specific to SIP servlets and interfaces from the context. In the case of Java EE components such as EJBs and MDBs,which are outside the scope of the servlet context, the SipFactory is available as a resource. You can inject theresource into a Java EE component such as an EJB or MJB using the @Resource annotation. The syntax of this injection lookslike this: @Resource(name="sip/app-name/SipFactory") SipFactory sf-app;where app-name is the name of the SIP application whose SipFactory is being injected. Note that there could be more thanone SIP application bundled in the enterprise application. So you need to specify which SipFactory instanceto inject into the Java EE component. The app-name is derived based on certain rules. For a description of the rulessee the blog Sailfin in detail: Part 1 app-name.A key constraint here is that only SipFactory instances that belong to SIP applications which are co-locatedin the .ear file can be injected into a Java EE component.Let's look at an example. The following code snippet injects the SipFactory instance for the SIP applicationwhose application.xml file was shown earlier. The SipFactory instance is injected as a resourceinto the EJB component in the TalkBack.jar file. @Stateless public class TalkBackBeanBean implements TalkBackBeanLocal { @Resource(name="sip/ConvergedEnterprise/ConvergedSipApplication/SipFactory") SipFactory sf; @Resource(name="sip/ConvergedEnterprise/ConvergedSipApplication/SipSessionsUtil") SipSessionsUtil ssu; public String findWho() { SipApplicationSession sas = ssu.getApplicationSessionByKey("CSA", false); return (String) sas.getAttribute("newReg"); }The app-name in the code snippet above is ConvergedEnterprise/ConvergedSipApplication becausethere is no explicit app-name defined in the sip.xml deployment descriptor. This follows Case I in theapp-name derivation rules.Accessing a Java EE component from a SIP ServletThere are two ways to access a Java EE component from a SIP Servlet. The first way is to use annotations.Java EE annotations are supported within a SIP Servlet. For instance, you could use an @EJBannotation to inject an EJB into a SIP Servlet or use a @Resource annotation to inject a connector resource.The following SIP servlet example demonstrates this approach. Here an @EJB annotation is used to access a beandefined in the TalkBack.jar file. The syntax of the @EJB annotation in the SIP servlet is the sameas for HTTP servlets. In this simple example, the SIP servlet invokes the TalkBackBean method in the EJB andreturns either a success message or an error message based on the return value from the EJB. public class InviteServlet extends SipServlet { @EJB(name="TalkBackBean") private TalkBackBeanLocal tbBean; //Reference to context - The ctx Map is used as a central storage for this app javax.servlet.ServletContext ctx = null; /\* \* Processes the INVITE request \*/ @Override protected void doInvite(SipServletRequest req) throws ServletException, IOException { System.out.println("In the INVITE servlet"); SipServletResponse resp = null; String responseMessage = tbBean.findWho(); // if the bean returns a non null value, then its a success. if(responseMessage != null) { resp = req.createResponse(200, "SUCCESS"); } else { resp = req.createResponse(500, "Error"); } resp.send(); }The second way to access a Java EE component from a SIP servlet is to specify the to-be-injected EJBin the <ejb-ref> element of a sip.xml or sun-sip.xml file.The sun-sip.xml file is a Sailfin-specific deployment descriptor file, which is functionally equivalentto the sun-web.xml file for web applications. Recall that Sailfin is the SIP servlet containerimplementation in GlassFish being developed in theSailFin project.You can also specify a connector resource to be injected in the <resource-ref> elementof these files. This is made possible through the support provided in the sip.xml andsun-sip.xml files for elements such as <ejb-ref>, <resource-ref>, and<resource-env-ref>.The following example demonstrates the second approach. Here an EJB is specified in an <ejb-ref> elementin a sip.xml file. The EJB can then be looked up using the ejb-ref-name in the JNDI context. <ejb-local-ref> <ejb-ref-name>TalkBackBean</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <local>sample.talkback.TalkBackBeanLocal</local> <ejb-link>TalkBack.jar#TalkBackBeanBean<Figure 1. SIP Test Agent Window Click the New Request button under the Message Creation window. In response, you should see various dialogboxes open for a SIP request as shown in Figure 2.Figure 2. SIP Request Dialog Boxes Select INVITE in the Method drop-down in the Request dialog box. Then click the Send button below the Message Previewwindow. In response, you should see a response message that includes 200 OK as shown inFigure 3. This indicates that the application successfully invoked an EJB from within a SIP servlet.Figure 3. SIP Response Message For more information on adding the SIP development and test plugins to NetBeans and adding Sailfin as a server toNetBeans, see the Hands On Lab,Adding Convergenceof media to your Java EE Application using NetBeans IDE and Sailfin. The Hands On Lab also has details on how to usethe SIP Test Agent.SummaryThe SIP Servlet API 1.1 specification formalizes the interfaces and interactions between the SIP servlets and Java EEapplications. It enables users to create converged enterprise applications that can handle voice and data traffic usingSIP servlets.About the AuthorPrasad Subramanian is a staff engineer at Sun Microsystems and is the engineering lead forProject Sailfin.2009 JavaOne Conference, June 2-5, San Francisco \*\* Register Now\*\*Stay on top of everything new and different, both inside and around Java technology. Register by April 22, 2009,and save $200 off a Conference Pass or Conference Plus Pass. Register now athttp://java.sun.com/javaone.

by Prasad Subramanian The February 29, 2008 Tech Tip, Adding Voice to Java EE With SIP Servlets, introduced Session Initiation Protocol (SIP),a signaling protocol that is used to set up, modify, and...

web services

Consuming RESTful Web Services With the Jersey Client API

by Jakub PodlesakJersey 1.0 is an open-source, production-ready referenceimplementation of JAX-RS, the Java API for RESTfulWeb Services (JSR-311). Jersey makes it easy to create RESTful web services using Java technology.An earlier Tech Tip,Implementing RESTfulWeb Services in Java, introduced RESTful Web Services, JAX-RS, and Jersey. It also showed how using Java technologyyou can write RESTful web services that conform to the JAX-RS specification. Another tip,Configuring JSON for RESTfulWeb Services in Jersey 1.0, showed how to configure data inJSON (JavaScript Object Notation) using Jersey 1.0.In this tip, you will learn how to use theJersey 1.0.2 Client API to consume HTTP-based RESTful Web Services. The Jersey 1.0.2 client APIis an easy-to-use, high level, Java technology API that can help you write clients for any HTTP-based RESTfulweb service. The API is built on the uniform interface concept, one of the key principles of REST.The uniform interface concept means that whatever URIs a REST-based application accesses, the interface to thoseURIs should be the sameJersey Client API BasicsTo start working with the Jersey client API, you need to create an instance of the com.sun.jersey.api.client.Clientclass. The simplest way to do that is as follows: import com.sun.jersey.api.client.Client; Client client = Client.create();The Client class is the main configuration point for building a RESTful web service client.You use it to configure various client properties and features and indicate which resource providers to use.Creating an instance of a Client is an expensive operation, so try to avoid creating an unnecessarynumber of client instances. A good approach is to reuse an existing instance, when possible.After you create a Client instance, you can start using it. However, to issue requests, you needto create a WebResource object, which encapsulates a web resource for the client. For example, the following codecreates a WebResource object for a web resource whose URI is http://example.com/base: import com.sun.jersey.api.client.WebResource; WebResource webResource = client.resource("http://example.com/base");You use the WebResource object to build requests to send to the web resource and to process responsesreturned from the web resource. For example, you can use the WebResource object for HTTPGET, PUT, POST, and DELETE requests.GET Request: Use the get() method in the WebResource class to submit anHTTP GET request to the web resource: String s = webResource.get(String.class);This means that if the URI for the WebResource object is http://example.com/base, an HTTP GET request is submittedto the resource whose URI is http://example.com/base. If you're familiar withcurl, the command line HTTP tool, you'll see that: String s = webResource.get(String.class);corresponds to the following curl command: curl http://example.com/baseYou can specify query parameters in the get() request. For example, the following code specifiestwo query parameters in the get() request: MultivaluedMap queryParams = new MultivaluedMapImpl(); queryParams.add("param1", "val1"); queryParams.add("param2", "val2"); String s = webResource.queryParams(queryParams).get(String.class);This corresponds to the following curl command: curl http://example.com/base?param1=val1&param2=val2You can also specify the acceptable MIME type for the response. For example, the following code specifies an acceptableMIME type of text: String s = webResource.accept("text/plain").get(String.class);This corresponds to the following curl command: curl -HAccept:text/plain http://example.com/baseIn addition, you can get the HTTP status code for the request. Here, for example, is a request that returns a text entityand a status code: ClientResponse response = webResource.accept("text/plain").get(ClientResponse.class); int status = response.getStatus(); String textEntity = response.getEntity(String.class);The ClientResponse object represents an HTTP response in the client.PUT Request: Use the put() method in the WebResource class to submit anHTTP PUT request to the web resource. For example, the following request puts a text entity foo:barinto a web resource: ClientResponse response = webResource.type("text/plain").put(ClientResponse.class, "foo:bar");This corresponds to the following curl command: curl -XPUT -HContent-type:text/plain --data "foo:bar" http://example.com/baseYou can also specify query parameters in the put()request. You do this in a way that is similar to specifyingquery parameters for a get() request. In the following example, the same query parameters that were used in theprevious get() method example are specified in a put() request: MultivaluedMap queryParams = new MultivaluedMapImpl(); queryParams.add("param1", "val1"); queryParams.add("param2", "val2"); ClientResponse response = webResource.queryParams(queryParams).put(ClientResponse.class, "foo:bar");This corresponds to the following curl command: curl -XPUT -HContent-type:text/plain --data "foo:bar" http://example.com/base?param1=val1&param2=val2POST Request: A POST request is a syntactic combination of a GET request and a PUT request, that is, you canuse a POST request to send an entity to a web resource and receive another entity. Use the post() methodin the WebResource class to submit an HTTP POST request to the web resource. For example, the followingcode submits a POST request with query parameters and URL-encoded form data: MultivaluedMap formData = new MultivaluedMapImpl(); formData.add("name1", "val1"); formData.add("name2", "val2"); ClientResponse response = webResource.type("application/x-www-form-urlencoded").post(ClientResponse.class, formData);This corresponds to the following curl command: curl -d name1=val1 -d name2=val2 http://example.com/baseDELETE Request: Use the delete() method in the WebResource class to submit anHTTP DELETE request to the web resource. For example, the following request deletes the resource whose URI ishttp://example.com/base/user/123: ClientResponse response = webResource.path("user/123").delete(ClientResponse.class);This corresponds to the following curl command: curl -XDELETE http://example.com/base/user/123Note that the WebResource.path() method, which can also be used in all the HTTP request methods, allows you tospecify an additional path for the requested web resource. Another WebResource method, header(),allows you to add an HTTP header to your request.Configuring the Jersey ClientBefore submitting requests, you might need to configure the client. This can involveregistering providers. You also have the option of adding filters.See theJersey 1.0.2 Client API for an overview of all possible options.Registering Providers: In JAX-RS, a provider is an implementation of a JAX-RS extension.A provider class is marked with a @Provider annotation. The Jersey server presents an infrastructurefor providers. In implementing JAX-RS, Jersey includes standard provider classes.The Jersey client API reuses the same provider infrastructure as the Jersey server. However, you need to explicitlyregister all non-standard providers because no automatic classpath scan takes place on the client side.To register a provider, you need to add its provider class to the ClientConfig object for theClient instance. The ClientConfig class declares the common property names, features, properties,provider classes, and singleton provider instances that can be used by a Client object. For example, thefollowing code registers a JSON provider class for use by a Client object: ClientConfig config = new DefaultClientConfig(); config.getClasses().add(JSONRootElementProvider.class); Client client = Client.create(config);Notice the use of the DefaultClientConfig class. It declares the default client configuration.Adding Filters: Another option you have in configuring a client is to add filters to the client instance.A filter dynamically intercepts requests and responses targeted to a resource class and can be used to modify therequest or response. The Jersey client API provides a number of classes that implement filters. One of them isLoggingFilter, which implements a logging filter. You can use a logging filter to track communicationbetween the client and a server application, something that can be valuable in debugging. Here is how to add alogging filter to the client: import com.sun.jersey.api.client.filter.LoggingFilter client.addFilter(new LoggingFilter());An Example of a Jersey-Based ClientAccompanying this tip is an example application that uses the Jersey client API to access the popularTwitter web service. The example demonstrates the ability of theJersey Client API to consume real-world, HTTP-based web services. You can download the example application as aTwitter client ZIP archive.If you expand the archive, you can examine the source code for the client. You can also download a runnableTwitter client JAR fileto test the application and see how it works. Note that you need Java SE Runtime Environment (JRE) 6 to runthe application.Twitter: Twitter is a service that allows you to exchange short text messages with friends,coworkers, family members, and others. The messages are designed to answer the question, "What are you doing?"Here is an example of some messages displayed through Twitter.Twitter Messages Twitter also provides a public Twitter API that you canuse to programmatically produce or consume Twitter messages and access other aspects of the service. If you usethe Twitter API, one thing you need to take into account is Twitter's authentication and security mechanismand requirements.Twitter Authentication and Security: Twitter uses a Basic HTTP authentication schema. This means thatif you access Twitter through its API, you need to add a special Authorization header to your request.Then you will probably also want to secure the communication using the Secure Sockets Layer (SSL). You can do thissimply with the following code: ClientConfig config = new DefaultClientConfig(); SSLContext ctx = SSLContext.getInstance("SSL"); ctx.init(null, myTrustManager, null); config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(hostnameVerifier, ctx)); Client client = Client.create(config);Examining the Client: Download theTwitter client ZIP archiveand expand it. Navigate to the TwitterClient class in thesrc\\main\\java\\com\\sun\\jersey\\techtips\\twitter directory. This is the Jersey-based client for the application.As you examine the source code in the TwitterClient class, notice especially the following:Code that creates the Client and WebResource objects: import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.WebResource; private static final String BaseURI = "https://twitter.com"; private final WebResource wr; Client client = Client.create(config); wr = client.resource(BaseURI);Code that configures the client: import com.sun.jersey.api.client.config.ClientConfig; import com.sun.jersey.api.client.config.DefaultClientConfig; ClientConfig config = new DefaultClientConfig(); config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(hv, ctx)); config.getClasses().add(JAXBContextResolver.class);Code that issues a get request: public List<StatusBean> getFriendsTimelineJson() { return wr.path("statuses/friends_timeline.json") .header(AUTHENTICATION_HEADER, authentication) .accept(MediaType.APPLICATION_JSON_TYPE) .get(new GenericType<List<StatusBean>>() { }); }Notice the addition of an Authentication header to the request.Running the Example ApplicationTo run the example application, do the following:If you do not have JRE 6 installed, download and install it .Download theTwitter client JAR fileIssue the following command from the command line: java -jar jersey-twitter-client-1.0-SNAPSHOT-jar-with-dependencies.jarIn response, you will be prompted for your Twitter user name and password. Respond to the prompts as appropriate.You should see then Twitter messages with timestamps. Here is an example:Simple Jersey (http://jersey.dev.java.net) based twitter clientTwitter username:mytwitterPassword:Hello mytwitter!Status will get updated every 60 secs.Enter !exit to finish the session.Arun Gupta (1238705837), at: Mon Feb 23 00:04:40 +0000 2009: #slumdog is a favorite ... have not seen the movie yet but would be great if it's the first Indian movie to win ... fingers crossed!LarryLary (1238103969), at: Mon Feb 23 00:07:33 +0000 2009: Gonna go for a walk. Need some fresh air.kmollo (1239025876), at: Mon Feb 23 01:43:34 +0000 2009: enjoying everyone's '15 Albums That Changed Your Life' lists. I have been so bored, it's nice to have some 'new' music to check out!iFab @fauntleroy (1239103887), at: Mon Feb 23 02:02:20 +0000 2009: It's a beautiful dayJessicaxG (1239248068), at: Mon Feb 23 02:36:34 +0000 2009: Shop. Shop. Shop. Another way to avoid things I need to do.DoughJoe (1239571723), at: Mon Feb 23 03:55:39 +0000 2009: Slumdog grabs it all> Congratulations to Kate Winslet on her best actress Oscar.Posted at: Tue Feb 24 16:54:17 +0000 2009>!exitbyeNotice that you can also enter your own messages in the client.Further ReadingFor more information on Jersey, see the following resources:Jersey 1.0.2 Client APIJersey ProjectConfiguring JSONfor RESTful Web Services in Jersey 1.0ImplementingRESTful Web Services in JavaAbout the AuthorJakub Podlesak is a member of the Jersey project team. Previously, he participated in the development ofMetro, the GlassFish web services stack, as a member ofthe WS-Policy team. Read his blog.2009 JavaOne Conference, June 2-5, San Francisco \*\* Register Now\*\*Stay on top of everything new and different, both inside and around Java technology. Register by April 22, 2009,and save $200 off a Conference Pass or Conference Plus Pass. Register now athttp://java.sun.com/javaone.

by Jakub Podlesak Jersey 1.0 is an open-source, production-ready reference implementation of JAX-RS, the Java API for RESTfulWeb Services (JSR-311). Jersey makes it easy to create RESTful web services...

Enterprise Java technology

Enterprise Tech Tips Crossword

Enterprise Tech Tips CrosswordOver the years, theEnterprise Java Technologies Tech Tips have covered a wide variety ofenterprise Java technology topics. Here's a crossword puzzle that tests your knowledge of some topics covered in recentTech Tips. Each clue lists a tip that contains the answer.This crossword was created with EclipseCrossword - www.eclipsecrossword.com1  234            5                                                        6                                                      7        89          10      1112                                                13                                                                    14                    15          16                        17    18                                                  AcrossJAXB binding compiler[Customizing JAXB]Session bean type that can implement a web service[Referencing Multiple Web Services From An Application Client]JPA interface for accessing a databaseExtended Persistence Context in Stateful Session Beans]SIP application package extension[Adding Voice to Java EE With SIP Servlets]SSL certificate objective[Using SSL with GlassFish v2]The world's most popular database[Combining Groovy, Grails, MySQL, and the Java Persistence API]Scripting engine used by Phobos[Building An Ajax-Enabled Web Application Using Phobos and jMaki]SIP-related protocol that specifies end user capabilities[Adding Voice to Java EE With SIP Servlets]Creating an XML document from a Java object tree[Customizing JAXB]Down"Convention over ____________"[True Abstraction: Composite UI Components in JSF 2.0 -- Part 1]Authority that can be trusted by a client and service that have no direct trust relationship[Using WS-Trust Support in Metro to Secure Web Services]JAX-RS production-quality Reference Implementation[Configuring JSON for RESTful Web Services in Jersey 1.0]Yiddish expert or Apache build framework[Using JAX-WS with Maven]jMaki event handler based on publish/subscribe mechanism[Working with jMaki Events]WS\* security specification provider[Using WS-Trust Support in Metro to Secure Web Services]SOAP Messages with Attachments (abbrv.)[Securing Attachments With Metro 1.3]REST resource identifier[Configuring JSON for RESTful Web Services in Jersey 1.0]Open-source web application framework that leverages Groovy[Combining Groovy, Grails, MySQL, and the Java Persistence API]GlassFish web services stack[Using WS-Trust Support in Metro to Secure Web Services]Ticket-granting part of a Key Distribution Center[Building Kerberos-Based Secure Services Using Metro]Here is the solution to the puzzle.

Enterprise Tech Tips Crossword Over the years, theEnterprise Java Technologies Tech Tips have covered a wide variety ofenterprise Java technology topics. Here's a crossword puzzle that tests your...

Metro

Customizing JAXB

by Martin GrebacJava Architecture for XML Binding (JAXB) provides a fastand convenient way to bind between XML schemas and Java representations, making it easy for Java developers to incorporateXML data and processing functions in Java applications. As part of this process, JAXB provides methods for unmarshallingXML instance documents into Java content trees that represent the structure and content of XML source documents, and thenmarshalling Java content trees back into XML instance documents.JAXB also provides a way to generate XML schema from Java objects. You can learn more about JAXB inChapter 17: Binding between XML Schema and Java Classesin the Java EE5 Tutorial.In this tip, you'll learn several ways of customizing or extending the default behavior of JAXB.A samples package accompanies the tip. The package includes two files, JAXBSample.javaand schema.xsd that demonstrate some of the techniques covered in this tip. The tip also points to resources thatmore fully cover the topic.The tip is based on JAXB 2.0 or later. You can download a nightly build of JAXB from theJAXB Download page. This tip shows the use of JAXB from a command line. However, JAXB is also available withthe NetBeans IDE.Customizing Namespace Prefixes During MarshallingMarshalling is the act of creating an XML document from a JAXB-derived Java object tree. When you marshall an XML documentusing JAXB 1.0, a Marshaller object, a JAXB object that controls the process of marshalling, provides namespacedeclarations in the resulting XML document. The Marshaller does this only when necessary, that is, only when thedeclared namespace prefixes are used in a program. Sometimes the Marshaller produces a lot of namespace declarationsthat look redundant, for example: <?xml version="1.0"?> <root> <ns1:element xmlns:ns1="urn:foo"> ... </ns1:element> <ns2:element xmlns:ns2="urn:foo"> ... </ns2:element> <ns3:element xmlns:ns3="urn:foo"> ... </ns3:element> </root>JAXB 2.0 changes this behavior. If you use JAXB 2.0 (or later) to marshal an XML document, theMarshaller declares all statically known namespace Uniform Resource Identifiers (URIs), that is, thoseURIs that are used as element or attribute names in JAXB annotations. JAXB may also declare additional namespaces in themiddle of an XML document, for example when a qualified name (QName) that is used as an attribute or element valuerequires a new namespace URI, or when a Document Object Model (DOM) node in a content tree requires a new namespace URI.This behavior might produce an XML document that has a lot of namespace declarations with automatically-generatednamespace prefixes. The problem is that automatically-generated namespace prefixes such as ns1, ns2, and ns3,are not user friendly -- they typically do not help people understand the marshalled XML.Fortunately, JAXB 2.0 (or later) provides a service provider interface (SPI) namedcom.sun.xml.bind.marshaller.NamespacePrefixMapper that you can use to specify morehelpful namespace prefixes for marshalling. You implement the SPI and pass it to the Marshaller.The main methods in the NamespacePrefixMapper class are shown in Table 1.Table 1: NamespacePrefixMapper MethodsMethodDescriptionpublic abstract String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix);Returns a list of namespace URIs that should be declared at the root element.public String[] getPreDeclaredNamespaceUris();Returns a list of namespace URIs or namespace prefix-namespace URI pairs that should be declared at the root element.public String[] getPreDeclaredNamespaceUris2();Returns a list of namespace prefix-namespace URI pairs that represent namespace bindings available on ancestor elements (that need not be repeated by JAXB.)public String[] getContextualNamespaceDecls();Returns a namespace prefix-namespace URI pair that should be declared at the root element.The program in the JAXBSample.java file illustrates the use of these methods. The program marshalls the sameXML document three times, first without the use of a NamespacePrefixMapper class and then with two differentNamespacePrefixMapper implementations.Follow these steps to build and run the program:Compile the schema.xsd file: xjc schema.xsdThis step generates the binding classes necessary for compilation of the program.Compile the binding classes generated in the previous step: javac -cp $JAXB_HOME/lib/jaxb-impl.jar:. a/\*.javawhere $JAXB_HOME is the directory where you installed JAXB.Compile and execute the JAXBSample class: javac -cp $JAXB_HOME/lib/jaxb-impl.jar:. JAXBSample.java java -cp $JAXB_HOME/lib/jaxb-impl.jar:. JAXBSampleHere's what you should see as output: Mapper: not set. <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ns2:JustAnElement xmlns:ns2="a"> <foo>true</foo> </ns2:JustAnElement> ----------------------- Mapper: PreferredMapper <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <mappedNamespacea:JustAnElement xmlns:mappedNamespacea="a"> <foo>true</foo> </mappedNamespacea:JustAnElement> ----------------------- Mapper: DeclareOnTopMapper <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <mappedNamespacea:JustAnElement xmlns:mappedNamespacea="a" xmlns:mappedNamespace b="b"> <foo>true</foo> </mappedNamespacea:JustAnElement> ----------------------- Mapper: PreDeclaredMapper <xml version="1.0" encoding="UTF-8" standalone="yes"?> <mappedNamespacea:JustAnElement xmlns:mappedNamespacea="a"> <foo>true</foo> </mappedNamespacea:JustAnElement> -----------------------When the JAXBSample program marshalls the XML document the first time, it does it without usinga NamespacePrefixMapper class. As a result, the Marshaller automaticallygenerates a namespace prefix, in this case, ns2. <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ns2:JustAnElement xmlns:ns2="a"> <foo>true</foo> </ns2:JustAnElement>The second marshalling done by the JAXBSample program uses a NamespacePrefixMapper classas follows: NamespacePrefixMapper m = new PreferredMapper(); marshal(jc, e, m); public static class PreferredMapper extends NamespacePrefixMapper { @Override public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) { return "mappedNamespace" + namespaceUri; } }The getPreferredPrefix() method in the PreferredMapper class returnsthe preferred prefix, in this case, mappedNamespacea to be declared at the root element of the marshalledXML. <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <mappedNamespacea:JustAnElement xmlns:mappedNamespacea="a"> <foo>true</foo> </mappedNamespacea:JustAnElement>The third marshalling done by the JAXBSample program uses a NamespacePrefixMapper classas follows: m = new DeclareOnTopMapper(); marshal(jc, e, m); public static class DeclareOnTopMapper extends PreferredMapper { @Override public String[] getPreDeclaredNamespaceUris() { return new String[] {"a", "b"}; } }The getPreDeclaredNamespaceUris() method in the DeclareOnTopMapper classreturns a list of namespace URIs, in this case, a and b, that should be declared at the root element. <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <mappedNamespacea:JustAnElement xmlns:mappedNamespacea="a" xmlns:mappedNamespace b="b"> <foo>true</foo> </mappedNamespacea:JustAnElement>The fourth marshalling done by the JAXBSample program uses a NamespacePrefixMapper classas follows: m = new PreDeclaredMapper(); marshal(jc, e, m); public static class PreDeclaredMapper extends PreferredMapper { @Override public String[] getContextualNamespaceDecls() { return new String[] {"a", "mappedNamespacea"}; } }The getContextualNamespaceDecls() method in the PreDeclaredMapper classreturns a namespace prefix and namespace URI, in this case, a and mappedNamespacea, that should be declaredat the root element. <xml version="1.0" encoding="UTF-8" standalone="yes"?> <mappedNamespacea:JustAnElement xmlns:mappedNamespacea="a"> <foo>true</foo> </mappedNamespacea:JustAnElement>There are other ways to customize the way namespaces are handled in JAXB. In particular there are various ways to remove unwantednamespace declarations in marshalled XML. You'll find most of these in theMetro and JAXB forum. Additional techniques aredocumented on web sites such asDigital Karate andjava.net - jaxb users on Nabble.Also expect enhancements to NamespacePrefixMapper, such as allowing namespace rejection.If you have a specific use case with or without a solution, or a suggestion for improvement to JAXB, please post it to theMetro and JAXB forum. You canalso submit suggestions for enhancements to JAXB through theIssue Tracker.Customizing Schema TranslationThe xjc schema compiler, also called the binding compiler, is an important part of a JAXB implementation.The compiler binds a source XML schema to a set of schema-derived program elements.The binding is described by an XML-based binding language in a binding file.The binding compiler produces a set of packages containing Java source files and JAXB property files.In most cases, the default bindings generated by the binding compiler are sufficient. However, there are caseswhere you might want to modify the default bindings. For example, you might want to provide more meaningfulpackage names than are generated by default. You can modify the default bindings by using custom binding declarationswhich are passed to the JAXB binding compiler. You can make these binding declarations as inline annotations in a sourceXML schema or declare them in an external binding customizations file.In addition, you can define binding customizations in different scopes (although not all binding customizations can be definedin each scope). The scopes are:Global: A binding customization defined in global scope is applicable to all schema elements in which this customization is definedand all other schemas that are imported into the schema. You specify a binding declaration in global scope with the<globalBindings> element.Schema. A binding customization defined in schema scope is only applicable to the schema in which the customization is defined.You specify a binding declaration in schema scope with the <schemaBindings> element.Definition: A customization value in binding declarations of a type definition and global declaration has definition scope.A definition scope covers all schema elements that reference the type definition or the global declaration.Component: A customization value in a binding declaration has component scope if the customization value applies only to theschema element that was annotated with the binding declaration.See Customizing JAXB Bindings in the Java EE5 Tutorialfor a fuller description of these scopes.Binding customizations are defined in the JAXB specification -- you can rely on these no matter which JAXB implementation yourapplication runs with. However, specific JAXB implementations may provide additional customizations. For example, the JAXBReference Implementation (RI) provides additional customizations that are not defined by the JAXB specification. You can learn aboutthese in Java Architecture for XML BindingVendor Customizations. Note that to use vendor-specific extensions you need to launch the xjc binding compiler withthe -extension option.Customizing Through XJC PluginsUsing an xjc plugin is yet another way of customizing the default behavior of the binding compiler. You can use an existing plugin,such as theXJC Fluent API Plugin, which enables the bindingcompiler to chain methods, or the XJC CamelcaseAlways Plugin, which enables the binding compiler to generate names in camel case. You can find a list of xjc plugins forJAXB 2.0 on the JAXB2 Commons page. There are some plugins, suchas the episode plugin, that are part of the JAXB RI. You can find these plugins in the jaxb-ri/xjc/src/com/sun/tools/xjc/addon/directory in jaxb sources. Note that you first need to join thejaxb sources project, this gives you CVS access to the JAXB RI 2.0 source code.To use any of these plugins, specify the classpath for the plugin when you launch the xjc compiler: xjc -cp plugin.jar -helpIf none of the existing xjc plugins suits your needs, consider writing your own. It's more difficult than using an existing plugin,but it can give you more flexibility. However, beware of vendor lockin. For instructions on how to write an xjc plugin see the blogWriting a plug-in for the JAXB RI isreally easy. In short, here's what you need to do:Extend the com.sun.tools.xjc.Plugin class.Put a service file in the META-INF/services/com.sun.tools.xjc.Plugin directory.Package everything in a JAR file.Further ReadingFor more information on customizing JAXB see the following resources:JAXB Project pageMetro and JAXB forumUnofficial JAXB GuideIn addition, the sample applications in the samples directory of theJAXBbinary download can be helpful,as well as the Using JAXBchapter in The Java Web Services Tutorial, andChapter 17: Binding between XML Schema and Java Classesin the Java EE5 Tutorial.About the AuthorMartin Grebac is a staff engineer at Sun Microsystems and the JAXB implementation lead. He is involved in tool-related activitiessuch as Metro plugins for the NetBeans IDE or Eclipse IDE, and runtimeintegration such as the integration of the Grails framework inGlassFish v2. Read hisblog.

by Martin Grebac Java Architecture for XML Binding (JAXB) provides a fast and convenient way to bind between XML schemas and Java representations, making it easy for Java developers to incorporateXML...

quiz

Tech Tips Quiz

Over the years, the Enterprise Java Technologies Tech Tips have covered a wide variety of enterprise Java technology topics.Here's a short quiz that tests your knowledge of some topics covered in recent Tech Tips. You can find the answers at the endof the quiz.True or false, you can attach validators, listeners, or a converter to composite userinterface components in JavaServer Faces (JSF) 2.0 technology?a. Trueb. FalseWhich of the following methods is used to guard against using stale data for computation in the Java Persistence API (JPA)on a versioned entity?a. Persistence.nonrepeat()b. EntityManager.lock()c. LockMode.set()d. None of the aboveWhat is Phobos?a. A framework for enabling interoperable web services.b. A lightweight, scripting-friendly, web application environment that runs on the Java platform.c. A container for JavaScript widgets.d. An debugger for the NetBeans IDE that provides advanced analysis features.e. An MBean generator.Which of the following mechanisms are available through the NetBeans IDE tosecure Metro-based web services:a. Username Authentication with Symmetric Keysb. SAML Authorization over SSLc. STS Issued Endorsing Tokend. All of the abovee. None of the aboveA Jersey 1.0-based web application returns status information about print jobs. The applicationuses JAXB beans to model the printer status information. The application transforms the status datafrom its JAXB specification to JSON notation. Here is printer status data as specified in a JAXB bean: @XmlRootElement public class StatusInfoBean { public String status = "Idle" public int tonerRemaining = 25; }If the application uses Jersey 1.0 to transform the status data into the mapped type of JSON notation,what will the JSON-formatted data look like?a.{"StatusInfoBean":{"status":"Idle","tonerRemaining":"25"}}b.{"status":"Idle", "tonerRemaining":"25"}c.{"StatusInfoBean":{"status":{"$":"Idle"},"tonerRemaining":{"$":"25"}}}d.{"status":{StatusInfoBean":[{"status":"Idle","tonerRemaining":"25"}]AnswersTrue or false, you can attach validators, listeners, or a converter to composite userinterface components in JavaServer Faces (JSF) 2.0 technology?a. Trueb. Falsea. True. This feature in JSF 2.0 allows you to turn any collection of page markup into a JSF user interface (UI)component -- with attached validators, converters, action listeners, and value change listeners -- for useby page authors. Unlike composite components created with other approaches such as Facelets, compositecomponents in JSF 2.0 technology support all the features of a real UIComponent.To learn more about composite UI components in JSF 2.0, see the August 29, 2008 Tech TipTrueAbstraction: Composite UI Components in JSF 2.0 -- Part 1 and the September 15, 2008 Tech TipTrue Abstraction: Composite UI Components in JSF 2.0 -- Part 2.Which of the following methods is used to guard against using stale data for computation in theJava Persistence API (JPA) on a versioned entity?a. Persistence.nonrepeat()b. EntityManager.lock()c. LockMode.set()d. None of the aboveb. EntityManager.lock(). Stale data means data that is no longer current. Guarding againstusing stale data for computation in the Java Persistence API (JPA) on a versioned entity means preventingsituations such as the following:Transaction T1Transaction T2 tx1.begin(); d1 = findDepartment(dId); //d1's original name is "Engrg" d1.setName("MarketEngrg"); tx1.commit(); tx2.begin(); e1 = findEmp(eId); d1 = e1.getDepartment(); if(d1's name is "Engrg") e1.raiseByTenPercent(); tx2.commit();

Over the years, the Enterprise Java Technologies Tech Tips have covered a wide variety of enterprise Java technology topics.Here's a short quiz that tests your knowledge of some topics covered in...

Enterprise Java technology

Configuring JSON for RESTful Web Services in Jersey 1.0

by Jakub PodlesakNote: The API for configuring JSON in Jersey has changed with the recently released 1.0.2 version. Please see http://blogs.sun.com/japod/entry/configuring_json_for_restful_web.Jersey 1.0 is an open-source, production-ready referenceimplementation ofJAX-RS, the Java API for RESTful Web Services (JSR-311).Jersey makes it easy to create RESTful web services in Java.In an earlier Tech Tip,ImplementingRESTful Web Services in Java, Paul Sandoz and I introduced RESTful Web Services, JAX-RS, and Jersey, and showed how towrite RESTful web services in Java that conform to the JAX-RS specification.In this tip you will learn how to configure data in JSON(JavaScript Object Notation) using Jersey 1.0. JSON is a lightweight data-interchange format that is based on theobject notation of the JavaScript language. Because of it's simple text format, JSON provides a good alternative to otherdata interchange formats such as XML and is particularly attractive as a data interchange format for RESTful web services.In this tip you will build a Jersey-based web application that provides information about printer status. Theapplication returns the information in JSON format. To build the application, you will use theMaven 2 software project management tool.For more information about Maven, seeWelcome to Maven andBuildingWeb Applications with Maven 2.Creating a Jersey-Based Web Application With Maven 2The first step in creating a Jersey-based web application with Maven 2 is to create a Maven 2 project. You can do thisby running the following Maven 2 archetype plugin: mvn archetype:generate -DarchetypeCatalog=http://download.java.net/maven/2In response, Maven 2 will prompt you to choose an archetype, that is, a Maven 2 project template, from the archetypeslisted in the archetype catalog, archetype-catalog.xml, at URL http://download.java.net/maven/2: Choose archetype: 1: http://download.java.net/maven/2 -> jersey-quickstart-grizzly (Archetype for creating a RESTful web application with Jersey and Grizzly) 2: http://download.java.net/maven/2 -> jersey-quickstart-webapp (Archetype for creating a Jersey based RESTful web application WAR packaging) Choose a number: (1/2):Choose 1 (jersey-quickstart-grizzly). You will then be asked to enter a groupid and some other inputs for theweb application. You may use the following values: Define value for groupId: : com.example Define value for artifactId: : printer-status-webapp Define value for version: 1.0-SNAPSHOT: : Define value for package: com.example: : Confirm properties configuration: groupId: com.example artifactId: printer-status-webapp version: 1.0-SNAPSHOT package: com.example Y: :After you confirm the inputs, Maven 2 creates a new subdirectory called printer-status-webapp, whichcontains a template for your new Jersey-based web application. Figure 1 shows the expanded filestructure of the printer-status-webapp subdirectory.Figure 1. Web Application Template Structure Created By Maven 2Maven 2 also creates a Project Object Model (POM) file, which contains an XML representation of the Maven project.You can find the pom.xml file in the printer-status-webapp subdirectory.Adding REST ResourcesIf you navigate below the printer-status-webapp subdirectory to src/main/java/com/example, you'llsee a Java class named MyResource. This class identifies the URI for a resource that represents a simple message. package com.example; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; // The Java class will be hosted at the URI path "/myresource" @Path("/myresource") public class MyResource { // TODO: update the class to suit your needs // The Java method will process HTTP GET requests @GET // The Java method will produce content identified by the MIME Media // type "text/plain" @Produces("text/plain") public String getIt() { return "Got it!"; } }Notice the JAX-RS annotations in the file. The @Path annotation identifies the URI path for which theMyResource class will serve requests. Recall that an important concept in REST is the existence of resources,each of which can be referred to using a global identifier, that is, a URI. In order to manipulate these resources,components of the network, clients and servers, communicate using a standardized interface such as HTTP and exchangerepresentations of these resources. The @GET annotation indicates that the getIt() method respondsto HTTP GET requests. The @Produces annotation indicates that the getIt() method returns plain text.To demonstrate JSON functionality in Jersey, let's add some additional REST resources.In order to do so, you need to enable JSON support in the application.Edit the pom.xml file, and uncomment the following part: <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-json</artifactId> <version>${jersey-version}</version> </dependency>You also need to update the jersey-version property in the pom.xml file to the currentlyavailable stable version, 1.0: <properties> <jersey-version>1.0</jersey-version> </properties>You're now ready to add JSON resources. To do that, let's create someJava Architecture for XML Binding (JAXB) beans to model statusinformation for a printer. Then you'll make the beans accessible as REST resources.First, in the src/main/java/com/example subdirectory, create a file StatusInfoBean.java withthe following code: package com.example; import java.util.Collection; import java.util.HashSet; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class StatusInfoBean { public String status = "Idle"; public int tonerRemaining = 25; public final Collection<JobInfoBean> jobs = new HashSet<JobInfoBean>(); }Next, in the src/main/java/com/example subdirectory create a file JobInfoBean.java with thefollowing code: package com.example; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "job") public class JobInfoBean { public String name; public String status; public int pages; // just to make JAXB happy public JobInfoBean(){}; public JobInfoBean(String name, String status, int pages) { this.name = name; this.status = status; this.pages = pages; } }To make the beans accessible as REST resources, you need to update the MyResource.java file inthe src/main/java/com/example subdirectory as follows: package com.example; import com.sun.jersey.spi.resource.Singleton; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.Produces; @Singleton @Path("/status") public class MyResource { StatusInfoBean statusInfoBean = new StatusInfoBean(); {{ statusInfoBean.jobs.add(new JobInfoBean("sample.doc", "printing...", 13)); }} @GET @Produces("application/json") public StatusInfoBean getStatus() { return statusInfoBean; } @PUT @Consumes("application/json") public synchronized void setStatus(StatusInfoBean status) { this.statusInfoBean = status; } }Notice that the getStatus() method returns data in JSON format to the clientand the setStatus() method processes data in JSON format sent by the client: @Produces("application/json") public StatusInfoBean getStatus() {...} @Consumes("application/json") public synchronized void setStatus(StatusInfoBean status) {...}Running the ApplicationYou can run the web application with the following Maven 2 lifecycle command in theprinter-status-webapp subdirectory: mvn clean compile exec:javaThe command cleans out all Maven 2-generated files and compiles the Java source. It also starts theGrizzly container with the web application running within it. C:\\printer-status-webapp>mvn clean compile exec:java [INFO] Scanning for projects... [INFO] Searching repository for plugin with prefix: 'exec'. [INFO] ------------------------------------------------------------------------ [INFO] Building printer-status-webapp [INFO] task-segment: [clean, compile, exec:java] [INFO] ------------------------------------------------------------------------ [INFO] [clean:clean] [INFO] [resources:resources] [INFO] Using default encoding to copy filtered resources. Downloading: http://download.java.net/maven/2//com/sun/jersey/jersey-server/1.0/ jersey-server-1.0.pom ... [INFO] [compiler:compile] [INFO] Compiling 4 source files to C:\\printer-status-webapp\\target\\classes [INFO] Preparing exec:java [INFO] No goals needed for project - skipping [INFO] [exec:java] Starting grizzly... Jersey app started with WADL available at http://localhost:9998/application.wadl Hit enter to stop it...Open your browser and point it to http://localhost:9998/status. You will see the following: {"status":"Idle","tonerRemaining":"25","jobs":{"name":"sample.doc","status":"printing...","pages":"13"}}This confirms that the Jersey-based web application returns data in JSON format.Improving the ApplicationAlthough the application returns data in JSON format, there are some improvements you might want to make.For example, if you add another printer job and rerun the application, it would return something like the following: {"status":"Idle","tonerRemaining":"25", "jobs":[{"name":"sample.ps","status":"printing...","pages":"13"},{"name":"second.pdf","status":"waiting in queue","pages":"2"}]}The jobs object in the JSON data is an array, something that wasn't evident in the output for a single printer job.You might want to change the application so that the result is seen as an array even if it contains just a single element.Otherwise it could cause some problems when the JSON is processed by the client.There is another thing you might consider changing. The values for tonerRemaining and pages arecurrently listed as strings. You probably want to represent those results as numbers.To make these improvements, create a file named MyJAXBContextResolver.java inthe src/main/java/com/example subdirectory with the following content: package com.example; import com.sun.jersey.api.json.JSONJAXBContext; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Provider; import javax.xml.bind.JAXBContext; @Provider public class MyJAXBContextResolver implements ContextResolver<JAXBContext> { private JAXBContext context; private Class[] types = {StatusInfoBean.class, JobInfoBean.class}; public MyJAXBContextResolver() throws Exception { Map props = new HashMap<String, Object>(); props.put(JSONJAXBContext.JSON_NOTATION, JSONJAXBContext.JSONNotation.MAPPED); props.put(JSONJAXBContext.JSON_ROOT_UNWRAPPING, Boolean.TRUE); props.put(JSONJAXBContext.JSON_ARRAYS, new HashSet<String>(1){{add("jobs");}}); props.put(JSONJAXBContext.JSON_NON_STRINGS, new HashSet<String>(1){{add("pages"); add("tonerRemaining");}}); this.context = new JSONJAXBContext(types, props); } public JAXBContext getContext(Class<?> objectType) { return (types[0].equals(objectType)) ? context : null; } }Restart the application with: mvn clean compile exec:javaNote that clean is optional here.You should now see the returned JSON with the results shown as an array -- even for a single print job -- and with thetonerRemaining and pages results as numbers. {"status":"Idle","tonerRemaining":25,"jobs":[{"name":"sample.doc","status":"printing...","pages":13}]}JSON Configuration ParametersIf you examine the content of the MyJAXBContextResolver class, you'll notice that it includes the following line: props.put(JSONJAXBContext.JSON_NOTATION, JSONJAXBContext.JSONNotation.MAPPED);The option JSONJAXBContext.JSON_NOTATION specifies the type of JSON notation that Jersey 1.0 will generatefrom the JAXB beans in the web application. In this case, it specifies that the mapped type of JSON notation will be used.The mapped notation is the default JSON notation in Jersey 1.0. For this notation, Jersey 1.0 takes a JAXB bean specificationsuch as this: @XmlRootElement public class StatusInfoBean { public String status = "Idle"; public int tonerRemaining = 25; }And generates the following JSON data: {"status":"Idle", "tonerRemaining":"25"}The following lines in MyJAXBContextResolver specify configuration properties for the default mapped notation: props.put(JSONJAXBContext.JSON_ROOT_UNWRAPPING, Boolean.TRUE); props.put(JSONJAXBContext.JSON_ARRAYS, new HashSet<String>(1){{add("jobs");}}); props.put(JSONJAXBContext.JSON_NON_STRINGS, new HashSet<String>(1){{add("pages"); add("tonerRemaining");}});In addition to these three properties, a fourth configuration property, JSONJAXBContext.JSON_ATTRS_AS_ELEMSis available. Table 1 describes the four configuration properties for the mapped notation.Table 1: Configuration Properties for the Mapped NotationPropertyTypeDescriptionExampleJSONJAXBContext.JSON_ROOT_UNWRAPPINGBooleanIf set to true (default value), root elements corresponding to the XML root element will be stripped out.Boolean.TRUEJSONJAXBContext.JSON_ARRAYSCollection<String>Contains elements which should be treated as array. Such elements will be delimited with braces.new HashSet<String>(1){{add("jobs");}}JSONJAXBContext.JSON_NON_STRINGSCollection<String>Contains elements which should not be delimited with double-quotes.Jersey currently supports the JSONJAXBContext.JSON_XML2JSON_NS property to configure namespacemapping for the Jettison convention.JSONNotation.BADGERFISH. This specifies theBadgerFish convention. For the BadgerFish convention, Jersey 1.0generates the following JSON data for the StatusInfoBean: {"StatusInfoBean":{"status":{"$":"Idle"},"tonerRemaining":{"$":"25"}}}Further ReadingImplementingRESTful Web Services in JavaBetter JSON Available InJerseyWelcome to MavenBuilding Web Applications with Maven 2About the AuthorJakub Podlesak is a member of the Jersey project team. Previously, he participated in the development of Metro,the GlassFish v2 web services stack, as a member of the WS-Policy team.

by Jakub Podlesak Note: The API for configuring JSON in Jersey has changed with the recently released 1.0.2 version. Please see http://blogs.sun.com/japod/entry/configuring_json_for_restful_web. Jersey 1...

web services

Using WS-Trust Support in Metro to Secure Web Services

by Jiandong GuoMetro is a high performance, extensible, easy-to-useweb services stack. It combines the JAX-WS reference implementation with Project Tango. Project Tango, also calledWeb Services Interoperability Technology or WSIT, implements numerous WS-\* standards to enable interoperability withother implementations and to provide Quality of Service (QOS) features such as security, reliability, and transactionsupport. Metro is available in the open source, enterprise-readyGlassFish v2 application server as well as in themodular GlassFish v3application server. Metro also runs in the Tomcat web container.In addition, it has been successfully used inother application servers.In an earlier Tech Tip, SecuringWeb Services Using WSIT, I introduced Metro's support (through WSIT) for web services security. This support implementsthe following web services security specifications published by the Organization for the Advancement of Structured InformationStandards (OASIS) consortium: WS-Security, WS-SecurityPolicy, WS-SecureConversation, and WS-Trust. The following tip focuseson the support in Metro for WS-Trust. You will learn the basics of WS-Trust and its Security Token Service (STS) framework.You'll also learn about the support in Metro for WS-Trust and STS. And you'll see how easy it is to take advantageof this support to secure a web service using Metro and the NetBeans IDE.A sample application package accompanies the tip. The package includes sample applicationsthat demonstrate how to enable web service security using STS-issued tokens associated with various types of proof keyssuch as a symmetric proof key, a public proof key, or no proof key.If would want to learn about other aspects of Metro security, see the September, 2008 Tech TipSecuring Attachments With Metro 1.3 and the March 2008 Tech TipSecure Conversationsfor Web Services With Metro.WS-Trust and WSITWS-Trust is a WS-\* specificationthat provides extensions to theWS-Securityspecification. WS-Security provides the basic framework for message level security in web services. WS-Trust buildson that base to specify a framework for broker trust across different security domains. It specifically deals with theissuing, renewing, and validating of security tokens, as well as with ways to establish, assess the presence of, and brokertrust relationships between participants in a secure message exchange.In essence, WS-Trust specifies the following:A general framework for token exchanges.A model for brokering trust in web services.A Security Token Service (STS) framework.Protocols for issuing, renewing, validating, and canceling security tokens.For a web service and its client to communicate securely there needs to be a trust relationship established between theservice and the client. If the service and client are in the same security domain they can have a direct trust relationship.In this type of relationship the service and client can authenticate each other directly. In WSIT, you specify authenticationrequirements in a security policy which you attach to the Web Services Definition Language (WSDL) file for the service. Forexample, the following X509Token assertion in a security policy specifies that an X509 certificate from the client is requiredfor the client to authenticate to the service: <sp:X509Token sp:IncludeToken= "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/ IncludeToken/AlwaysToRecipient"> <wsp:Policy> <sp:RequireThumbprintReference /> <sp:WssX509V3Token10 /> </wsp:Policy> </sp:X509Token>In this case, the service understands the client's identity as represented by its certificate.However, if the client and the service are in different security domains they have no direct trust relationship. In that case,you can use an STS to authenticate the client. The STS is an authority trusted by the client and the service. You can also usean STS to issue a security token, that is, a collection of claims such as name, role, and authorization code, for the client toaccess the service.In you use an STS, you need to change that assertion in the security policy to indicate that the client must callan STS first to get a security token. The security token is usually a Security Assertion Markup Language (SAML) token.Here's what the changed X509Token looks like: <sp:IssuedToken sp:IncludeToken= "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/ IncludeToken/AlwaysToRecipient"> <sp:Issuer> <Address xmlns="http://www.w3.org/2005/08/addressing"> http://localhost:8080/jaxws-sts/sts </Address> <Metadata xmlns= "http://schemas.xmlsoap.org/ws/2004/09/mex"> <MetadataSection> <MetadataReference> <Address xmlns= "http://www.w3.org/2005/08/addressing"> http://localhost:8080/jaxws-sts/sts </Address> </MetadataReference> </MetadataSection> </Metadata> </sp:Issuer> </sp:IssuedToken>The first <Address> element in the changed X509Token specifies the endpoint of the STS. The second<Address> element, the one under the <Metadata> element, specifies the address for obtaining theWSDL of the STS using standard WS MetadataExchange (WS-MEX) protocols.An STS itself is a web service -- a web service that issues security tokens. It makes assertions based on evidencethat it trusts, to whoever trusts it (or to specific recipients). To communicate trust, an STS requires proof, such asa signature, to prove knowledge of a security token or set of security tokens. An STS can generate tokens or it can rely ona separate STS to issue a security token with its own trust statement (note that for some security token formats this canjust be a reissuance or cosignature). This forms the basis of trust brokering.WS-Trust in MetroHere is a summary of the WS-Trust support in Metro:Supports token issuance and token validation protocols.Supports the STS framework.Supports building an STS as an independent web service.Supports client and service authentication and security with issued tokens from an STSwithin the general framework of WS-Security and WS-SecurityPolicy.Provides a general framework for building an STS as a web service for issuingsecurity tokens.Supports authentication and secure communication between a client and an STS in the same way as fora regular web service.Supports issuing SAML 1.0, SAML 1.1 and SAML2.0 tokens, by default.Supports the issuing of symmetric proof keys, public proof keys, and no proof keys.Can be extended to support the issuing of other types of tokens.Allows for plugging in additional authorization mechanisms that control the issuing oftokens according to the user's identity and the targeted service.Allows for plugging in user mappings that control the user identity/attributes carried in theSAML token issued by an STS for different services.In Metro, you use <sp:IssuedToken> policy assertions in the service's WSDL to enable security with an STS.No run-time API is required.You secure the STS itself in the same way that you secure a regular web service.Issued Tokens and Proof KeysIn many cases, an <sp:IssuedToken> policy assertion may need to require a proof key to protectcommunications between the client and the service. A proof key indicates proof of possession of the token associatedwith the requested security token. There are two types of proof keys: symmetric or asymmetric. A symmetric proof keyis computed and verified with symmetric key algorithms. An asymmetric proof key is computed and verified withasymmetric key algorithms. You can specify the requirement of the proof key type inthe service's security policy in the WSDL. You do this in the <KeyType> entry in the<sp:IssuedToken> policy assertion. Here's an example assertion: <sp:IssuedToken sp:IncludeToken= "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"> <sp:RequestSecurityTokenTemplate> <t:TokenType xmlns= "http://schemas.xmlsoap.org/ws/2005/02/trust"> http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1 </t:TokenType> <t:KeyType xmlns= "http://schemas.xmlsoap.org/ws/2005/02/trust"> "http://schemas.xmlsoap.org/ws/2005/02/trust/SymmetricKey </t:KeyType> <t:KeySize xmlns= "http://schemas.xmlsoap.org/ws/2005/02/trust">256 </t:KeySize> </sp:RequestSecurityTokenTemplate> <wsp:Policy> <sp:RequireDerivedKeys/> <sp:RequireInternalReference/> </wsp:Policy> </IssuedToken>In this example, the <KeyType> entry specifies a symmetric key. As an alternative tospecifying a symmetric or asymmetric proof key, you can also specify a public proof key or no proof key.Here is how these three cases are handled.Symmetric Proof Key. In this case, the STS creates an associated symmetric proof key while creatingthe issued SAML assertion. The symmetric key needs to be distributedto both the client and the service that the client talks to. The STS sends the key to the client in a<RequestedProofToken> element in the response message from the STS to the client. Another copy of thekey is embedded in a <KeyInfo> property of the <SubjectConfirmation> element inthe issued SAML assertion. The service retrieves the key after it gets the SAML assertion in the request message fromthe client.Public Proof Key. A public proof key is used for privacy reasons if the client doesn't want the STS to controlor issue the secret key. In this case, the client either supplies an X509 certificate or an ephemeral RSA public key inthe request message to the STS. The client certificate or the public key is embedded ina <KeyInfo> property of the <SubjectConfirmation> element in the issued SAML assertionpassed to the service.In Metro, an ephemeral RSA key pair is always created for use if the <KeyType> is set toPublicKey and <KeySize> is set to a value (the values must be multiples of 1024). If<KeyType> is set to PublicKey and <KeySize> is not set, then a clientcertificate must be supplied to the STS as an authentication token or supporting token.No Proof Key. In this case, the issued token is mainly used as a supporting token for authentication/authorizationpurpose. If you choose to have no proof key with an issued token, the token must always be signed and encrypted in transport.Enabling WS-Trust-Based Security With Metro and NetBeansThe NetBeans IDE offers an easy way to enable secure conversations in Metro for a web service. One of the ways it does thisis by providing a set of security profiles that specify the mechanism to be used in securing conversations. The profiles are:Username Authentication with Symmetric KeysMutual Certificates SecurityTransport Security (SSL)Message Authentication over SSLSAML Authorization over SSLEndorsing CertificateSAML Sender Vouches with CertificatesSAML Holder of KeySTS Issued TokenSTS Issued Token with Service CertificateSTS Issued Endorsing TokenSTS Issued Supporting TokenFour of these profiles secure web services with STS-issued tokens:STS Issued TokenSTS Issued Token with Service CertificateSTS Issued Endorsing TokenSTS Issued Supporting TokenYou specify one of these mechanisms when you configure security for a web service using the NetBeans IDE.You do this by expanding the Web Services node in the Projects window. Then right-click on web servicein the Web Services node and select Edit Web Services Attributes as shown in Figure 1.Figure 1. Configuring Security for a Web Service in NetBeansFor each of these profiles, you can configure the proof key type for the issued tokens by specifyinga key type in the Configuration panel, as illustrated in Figure 2.Figure 2. Configuring a Proof Type Key for a Web Service in NetBeansNot all proof key types can be used with each of the profiles. Here are the general rules:STS Issued Token. In this case the issued token is used as the primary protection token so it must associated witha proof key of SymmetricKey or PublicKey type.STS Issued Token with Service Certificate. In this case, the issued token is used to protect the request messageand the service certificate for the response message. A proof key of SymmetricKey or PublicKeyis required.STS Issued Endorsing Token. In this case, the service certificate is used to protect the message. The issued tokenis used for client authentication and the integrity of the message with an endorsing signature. A proof key ofSymmetricKey or PublicKey is required.STS Issued Supporting Token. In this case the issued token provides user information for authentication/authorizationpurposes. No proof key is required.Once you choose one of the profiles to secure a web service, an IssueToken policy assertion is createdin the service WSDL.You can also use the NetBeans IDE to create an Metro-based STS. For more details, seeSection 12.8.Configuring A Secure Token Service (STS) in the Metro User's Guide.To further customize the STS, see my blog entryCreate customer STS withWSIT.Running the SamplesA sample application package accompanies the tip. The package includes sample applicationsthat demonstrate how to enable web service security using STS-issued tokens associated with a symmetric proof key,a public proof key, and no proof key. To install and run the samples do the following:If you haven't already done so, downloadNetBeans IDE 6.5 Betaand GlassFish V2 Update Release 2 (v2 ur2).Start the NetBeans IDE.If GlassFish v2 is not one of the NetBeans application servers, add it as follows:Right-click the Servers node inthe Services window.Select Add Server.Select GlassFish v2.Click the Next button.Click the Browse button and browse to the location that you installed GlassFish v2.Click the Choose button.Click the Next button.Set the Admin Password to the default, adminadmin, unless you chose a different password for GlassFish.Click the Finish button.Update the Metro JAR files in GlassFish v2 to Metro 1.3.1 versions as follows:Download Metro 1.3.1.Copy the webservices-rt.jar file and the wsservices-tools.jar file from Metro 1.3.1 to<GF_Install>\\lib, where <GF_Install> is the GlassFish v2 ur2 installation directory.Copy the webservices-api.jar file from Metro 1.3.1 to <GF_Install>\\lib\\endorsed.Add testing certificates to GlassFish as described inSection 12.5.Configuring Keystores and Truststores in the Metro Users Guide.Download the sample application package and extract its contents. You should now see a newly extracted directorytrust_samples.Open the STS project in the NetBeans IDE as follows:Select Open Project from the File menu.Browse to the trust_samples directory from the sample application download.Select STS in the Open Project window.Click the Open Project Folder button.STS is a project for an STS that will be used by the sample applications. The STS was created using theNetBeans IDE with the Mutual Certificates Security profile. You can see the security configuration for the STS service,STSService, by expanding the Web Services node for the STS project in the Projects window.Then right-click on STSService in the Web Services node and select Edit Web Services Attributes as shown inFigure 3.Figure 3. STSService Security ConfigurationRunthe STS project as follows:Right-click the STS node in the Projects window.Select Run.In response, the STS service is deployed to the GlassFish v2 application server andthe WSDL file for the web service is published to http://localhost:8080/STS/STSService?wsdl.Open the CalculatorServiceIT project with the NetBeans IDE as follows:Select Open Project from the File menu.Browse to the trust_samples directory from the sample application download.Select CalculatorServiceIT in the Open Project window.Click the Open Project Folder button.CalculatorServiceIT is a simple calculator service created using the NetBeans IDE withan STS Issued Token profile for security. The service was configured using a symmetric proof keyas shown in Figure 4.Figure 4. CalculatorServiceIT Security Configuration.Run the CalculatorServiceIT project as follows:Right-click the CalculatorServiceIT node in the Projects window.Select Run.In response, the CalculatorServiceIT service is deployed to the GlassFish v2 application server andthe WSDL file for the web service is published tohttp://localhost:8080/CalculatorServiceIT/CalculatorITService?wsdl.If you examine the WSDL file, you'll notice that it includes an <sp:IssuedToken> policy assertionwith a <KeyType> entry that specifies a symmetric proof key. <ns2:IssuedToken ns2:IncludeToken= "http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"> ... <ns2:RequestSecurityTokenTemplate> <ns6:KeySize>256</ns6:KeySize> <ns7:KeyType> http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey </ns7:KeyType> <ns8:TokenType> http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1 </ns8:TokenType> </ns2:RequestSecurityTokenTemplate> </ns2:IssuedToken>In other words, the NetBeans IDE generates the appropriate WSDL specifications for a secure conversationbased on the security profile and secure conversation selection that were made when the web service was created.Open the CalculatorClientIT project with the NetBeans IDE as follows:Select Open Project from the File menu.Browse to the trust_samples directory from the sample application download.Select CalculatorClientIT in the Open Project window.Click the Open Project Folder button.CalculatorClientIT is the client for the CalculatorServiceIT service.Run the CalculatorClientIT project as follows:Right-click the CalculatorClientIT node in the Projects window.Select Run.In response, you should see the following in your browser: Servlet ClientITServlet at /CalculatorClientIT Result = 3Open the CalculatorServiceET as follows:Select Open Project from the File menu.Browse to the sc_samples directory from the sample application download.Select CalculatorServiceET in the Open Project window.Click the Open Project Folder button.CalculatorServiceET is a service that was created with an STS Issued Endorsing Token profileusing a PublicKey proof key. This is illustrated in Figure 5.Figure 5. CalculatorServiceET Security ConfigurationRun the CalculatorServiceET project as follows:Right-click the CalculatorServiceET node in the Projects window.Select Run.In response, the CalculatorServiceET service is deployed to the GlassFish v2 application server andthe WSDL file for the web service is published tohttp://localhost:8080/CalculatorServiceET/CalculatorETService?wsdl.If you examine the WSDL file, you'll notice that it includes an <sp:IssuedToken> policy assertionwith a <KeyType> entry that specifies a PublicKey proof key type. <ns2:IssuedToken ns2:IncludeToken= "http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"> ... <ns2:RequestSecurityTokenTemplate> <ns7:KeyType> http://docs.oasis-open.org/ws-sx/ws-trust/200512/PublicKey </ns7:KeyType> <ns8:TokenType> http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1 </ns8:TokenType> </ns2:RequestSecurityTokenTemplate> </ns2:IssuedToken>Open the CalculatorClientET project with the NetBeans IDE as follows:Select Open Project from the File menu.Browse to the trust_samples directory from the sample application download.Select CalculatorClientET in the Open Project window.Click the Open Project Folder button.CalculatorClientET is the client for the CalculatorServiceET service.Run the CalculatorClientET project as follows:Right-click the CalculatorClientET node in the Projects window.Select Run. Servlet ClientETServlet at /CalculatorClientET Result = 9Open the CalculatorServiceST project as follows:Select Open Project from the File menu.Browse to the sc_samples directory from the sample application download.Select CalculatorServiceST in the Open Project window.Click the Open Project Folder button.CalculatorServiceST is a service that was created with an STS Issued SupportingToken profile using no proof key. This is illustrated in Figure 6.Figure 6. CalculatorServiceST Security Configuration.Run the CalculatorServiceST project as follows:Right-click the CalculatorServiceST node in the Projects window.Select Run.In response, the CalculatorServiceST service is deployed to the GlassFish v2 application server andthe WSDL file for the web service is published tohttp://localhost:8080/CalculatorServiceST/CalculatorServiceSTService?wsdl.If you examine the WSDL file, you'll notice that it includes an <sp:IssuedToken> policy assertionwith a <KeyType> entry of Bearer. This indicates that there is no proof key associatedwith the assertion. <ns2:IssuedToken ns2:IncludeToken= "http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"> ... <ns2:RequestSecurityTokenTemplate> <ns6:KeySize>256</ns6:KeySize> <ns7:KeyType> http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer </ns7:KeyType> <ns8:TokenType> http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1 </ns8:TokenType> </ns2:RequestSecurityTokenTemplate> </ns2:IssuedToken>Open the CalculatorClientST project with the NetBeans IDE as follows:Select Open Project from the File menu.Browse to the trust_samples directory from the sample application download.Select CalculatorClientST in the Open Project window.Click the Open Project Folder button.CalculatorClientST is the client for the CalculatorServiceST service.Run the CalculatorClientST project as follows:Right-click the CalculatorClientST node in the Projects window.Select Run.In response, you should see the following in your browser: Servlet ClientSTServlet at /CalculatorClientST Result = 55About the AuthorJiandong Guo is a staff engineer and a senior member of the Application Server Web Services Security Group.He has lead the development of implementations and solutions based on WS-SecureConversation and WS-Trust in the Tango project.

by Jiandong Guo Metro is a high performance, extensible, easy-to-use web services stack. It combines the JAX-WS reference implementation with Project Tango. Project Tango, also calledWeb Services...

web services

Securing Attachments With Metro 1.3

by Ashutosh ShahiMetro is a high performance, extensible, easy-to-useweb services stack. It combines the JAX-WS reference implementation with Project Tango. Project Tango, also calledWeb Services Interoperability Technology or WSIT, implements numerous WS-\* standards to enable interoperability withother implementations and to provide Quality of Service (QOS) features such as security, reliability, and transactionsupport. Metro is available in the open source, enterprise-readyGlassFish v2 application server as well as in themodular GlassFish v3application server. Metro also runs in the Tomcat web container.In addition, it has been successfully used inother application servers.Metro 1.3 was recently released. With this release,Metro now supports the OASIS specification version of all the major WS-\* specifications that it implements. EarlierMetro releases supported the OASIS submission version of these specifications. As a result, Metro is now interoperablewith the Microsoft .NET Framework 3.5, which also supports the same version of the specifications. The earlier releases ofMetro were interoperable with the Microsoft .NET Framework 3.0 . Metro is tested for interoperability with .NET releases ona continuous basis and is a primary release criteria. See theMetro Specifications section in theMetro User's Guide for a complete list of the specifications and their versions supported in Metro.The WS-SecurityPolicy v1.2 specification from OASIS now includes an assertion for integrity and confidentialityprotection of SwA (SOAP Messages with Attachments) attachments. This assertion is also a supported feature in Metro 1.3.In this tip, you will learn how to secure an SwA attachment using Metro 1.3 and NetBeans IDE 6.5 (currently available asa Beta release). The new features in the Metro 1.3 release are available in NetBeans IDE 6.5 through a web services plugin.A sample application package accompanies the tip. The sample application demonstratesa web service and client that securely exchange an SwA attachment using Metro 1.3.If would want to learn about other aspects of Metro security, see the March 2008 Tech TipSecure Conversations for Web Services With Metro and the March 2007 Tech TipSecuring Web Services Using WSIT.An Example of SwA and SecuritySecuring attachments is described in theWSS:SwAProfile specification. It describes how to use the OASIS Web Services Security: SOAP Message Security specification withSwA. More specifically, the WSS:SwA Profile specification describes how a web service consumer can secure SOAP attachmentsusing SOAP Message Securityfor attachment integrity, confidentiality, and origin authentication, and how a receiver may process such a message.SwA defines a multi-part MIME structure for packaging attachments with SOAP messages. The structure contains a primarySOAP envelope in its root part and one or more attachments in additional MIME parts. Some of these attachments may havea content type corresponding to XML, but do not contain the primary SOAP envelope to be processed. The WSS:SwA specificationconsiders all attachments as opaque, in other words, arbitrary binary data, whether they are XML or some other content type.Here is a sample multi-part MIME SOAP message, where the attachment is integrity protected through signing (line numbers havebeen added for reference): 1 --uuid:be998ab6-f21a-4ae7-9436-fac806d24efa 2 Content-Type: text/xml 3 4 <?xml version='1.0' encoding='UTF-8'?>" 5 <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" 6 xmlns:ds="http://www.w3.org/2000/09/xmldsig#" 7 xmlns:exc14n="http://www.w3.org/2001/10/xml-exc-c14n#" 8 xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" 9 xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 10 <S:Header> 11 . 12 . 13 <wsse:Security S:mustUnderstand="1"> 14. 15. 16 <ds:Signature Id="_1"> 17 <ds:SignedInfo> 18 . 19 . 20 <ds:Reference URI="cid:9e0f3a51-dcfe-48f4-806f-70a9c8c3a482@example.jaxws.sun.com"> 21 <ds:Transforms> 22 <ds:Transform Algorithm="http://docs.oasis-open.org/wss/oasis-wss-SwAProfile-1.1#Attachment-Content-Signature-Transform"/> 23 </ds:Transforms> 24 <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> 25 <ds:DigestValue>PSrQnx9L+3Vh1ORMk6EWwvY+Mn8=</ds:DigestValue> 26 </ds:Reference> 27 . 28 </ds:SignedInfo>> 29 <ds:SignatureValue>...</ds:SignatureValue> 30 . 31 . 32 </ds:Signature> 33 </wsse:Security> 34 </S:Header> 35 <S:Body wsu:Id="_5006"> 36 <ns2:uploadFile xmlns:ns2="http://service.techtip/"> 37 <fileName>java.jpg</fileName> 38 <fileContent>cid:6a28e859-a93e-4d1f-a8b0-ce5a06b246cf@example.jaxws.sun.com</fileContent> 39 </ns2:uploadFile> 40 </S:Body> 41 </S:Envelope> 42 --uuid:be998ab6-f21a-4ae7-9436-fac806d24efa 43 Content-Id: 1 --uuid:f4fde266-9bd6-4b8d-a946-a98e4d11f4e5 2 Content-Type: text/xml 3 <?xml version='1.0' encoding='UTF-8'?> 4 <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" 5 xmlns:ds="http://www.w3.org/2000/09/xmldsig#" 6 xmlns:exc14n="http://www.w3.org/2001/10/xml-exc-c14n#" 7 xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" 8 xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 9 xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> 10 <S:Header> 11 . 12 . 13 <wsse:Security S:mustUnderstand="1"> 14 . 15 . 16 <xenc:EncryptedKey Id="_5007"> 17 <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/> 18 <ds:KeyInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="keyInfo"> 19 . 20 . 21 </ds:KeyInfo> 22 <xenc:CipherData> 23 <xenc:CipherValue>...</xenc:CipherValue> 24 </xenc:CipherData> 25 <xenc:ReferenceList> 26 <xenc:DataReference URI="#_5008"/> 27 </xenc:ReferenceList> 28 </xenc:EncryptedKey> 29 <xenc:EncryptedData Id="_5008" MimeType="image/jpeg" Type="http://docs.oasis-open.org/wss/oasis-wss-SwAProfile-1.1#Attachment-Content-Only"> 30 <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/> 31 <xenc:CipherData> 32 <xenc:CipherReference URI="cid:0d3ed794-8492-4c7d-9d85-2568c37d1687@example.jaxws.sun.com"> 33 <xenc:Transforms> 34 <ds:Transform Algorithm="http://docs.oasis-open.org/wss/oasis-wss-SwAProfile-1.1#Attachment-Ciphertext-Transform"/> 35 </xenc:Transforms> 36 </xenc:CipherReference> 37 </xenc:CipherData> 38 </xenc:EncryptedData> 39 . 40 . 41 </wsse:Security> 42 </S:Header> 43 <S:Body wsu:Id="_5006"> 44 <ns2:uploadFile xmlns:ns2="http://service.techtip/"> 45 <fileName>java.jpg</fileName> 46 <fileContent>cid:0d3ed794-8492-4c7d-9d85-2568c37d1687@example.jaxws.sun.com</fileContent> 47 </ns2:uploadFile> 48 </S:Body> 49 </S:Envelope> 50 --uuid:f4fde266-9bd6-4b8d-a946-a98e4d11f4e5 51 Content-Id:<0d3ed794-8492-4c7d-9d85-2568c37d1687@example.jaxws.sun.com> 52 Content-Type: application/octet-stream 53 Content-Transfer-Encoding: binary 54 Encrypted image data Here--- 55 --uuid:f4fde266-9bd6-4b8d-a946-a98e4d11f4e5-- 56Line 32 shows an <xenc:CipherReference> element inside the <xenc:EncryptedData>element (Line 29). The <xenc:CipherReference> element refers to the attachment Content-ID to be encrypted.The MimeType attribute in the <xenc:EncryptedData> element indicates the Content-Type of the MIMEattachment before encryption (in this case, image/jpeg). After encrypting the attachment, the Content-Type isset to application/octet-stream.Sample ApplicationThe sample application demonstrates a web service and client that securely exchange an SwA attachment using Metro 1.3.The application includes two projects: FileUpload and FileUploadClient. The FileUpload project provides aFileUpload web service that stores binary files on the server. The FileUploadClient project includesa servlet that acts as a client to the FileUpload web service.The servlet sends a binary file to theFileUpload service in a secured manner, as mandated by the policy of the service. The binaryfile is sent as an SwA attachment to the service's uploadFile() method. The policy for the web servicemandates that the attachment must be integrity and confidentiality protected "on the wire", that is, as theattachment is sent from the client to the service.Running the SampleTo run the sample, perform the following steps:Download the sample application and extract its contents. You should now see a newlyextracted directory <sample_install_dir>/sample, where <sample_install_dir> is thedirectory where you installed the sample application. For example, if you extracted the contents to C:\\ ona Windows machine, then your newly created directory should be at C:\\sample.If you haven't already done so, installNetBeans IDE 6.5 Beta (or a later release),and GlassFish V2UR2.GlassFish V2UR2 is also available in the NetBeans IDE 6.5 Beta download bundle, so you can install the IDE and theapplication server together.Download Metro 1.3. Then add it to yourGlassFish v2 UR2 installation as follows:Open a command line and enter the command: java -jar metro-1_3.jar. This will create a metro directory and fill it with the Metro 1.3 content.Change to the metro directory by entering the command: cd metroEnter the command: ant -Das.home=<AS_HOME> -f metro-on-glassfish.xml install where <AS_HOME> is where you installed GlassFish. It you set AS_HOME as an environment variable, you don't need to specify -Das.home in the command. This command copies the two Metro JAR files into your GlassFish installation's lib directory and makes the necessary classpath alterations in the domain configuration file, domain.xml. It also updates the classpath for the utility script files,wsimport and wsgen.Configure GlassFish to record message dumps, as follows:Open the file <AS_HOME>/domains/domain1/config/domain.xml in a text editor.Add the following <jvm-options> element: <jvm-options>-Dcom.sun.xml.ws.transport.http.HttpAdapter.dump=true</jvm-options>Start NetBeans IDE 6.5.Open the FileUpload and FileUploadClient projects. Open each project as follows:Click Open Project in the Projects tab.Navigate to the appropriate project folder. You can find the folders for the two projects in thesample directory of the sample application.Set the policy for the service as follows (note that these steps have already been done for the FileUpload project):Expand the Web Services node under the FileUpload project in the Projects view.Right-click the FileUpload service and select Edit Web Service Attributes. This will open a window that displays the Quality of Service attributes for the FileUpload service, as shown in Figure 2.Figure 2. Service Policy For FileUploadSet Version Compatibility to .NET 3.5/Metro 1.3.Check the Secure Service check box and select Mutual Certificates Security from the Security Mechanism drop-down list.Check the Use Development Defaults checkbox. This selects the default keystore and certificates to be used. If you don't check this checkbox, you will need to specify your own certificates.Scroll down to uploadFile operation, and expand the Input Message item.Click the Message Parts button. This opens a Message Parts window that specifies which parts of the message should be secured, as shown in Figure 3.Figure 3. Securing Message PartsClick the Add Attachments button in the Message Parts window to sign and encrypt the SwA attachments. Ensure that the Sign and Encrypt options for the Body and Attachment(s) are checked.Click the OK button in the two open windows to save the configuration.Right-click the FileUpload Project and select Run. This deploys the service and opens a browser to display the WSDL forthe service, as shown in Figure 4.Figure 4. The WSDL for the Web ServiceOpen the uploadClient class in the FileUploadClient project, as follows: Expand the FileUpload project in the Project tab on the NetBeans IDE.Expand the Source Packages node.Right-click FileUploadClient below the techtip.client source package and select Open. As Figure 5 shows, FileUploadClient is a servlet which accesses theFileUpload web service. The code to access the service is in the processRequest() method.Figure 5. The FileUploadClient ClassSet the policy for the client (note that these steps have already been done for the FileUploadClient project):Expand the Expand Web Service Reference node in the FileUploadClient project.Right-click the FileUpload service and select Edit Web Service Attributes. This will open a window that displays the Quality of Service attributes for the FileUpload service, as shown in Figure 6.Figure 6. Service Policy For FileUpload Service ClientCheck the Use Development Defaults checkbox in under Security. This selects the default certificates to be used.Click the OK button to save the changes.Right-Click the FileUploadClient project and select Run. This opens a browser window that indicates whether the file upload wassuccessful, as illustrated in Figure 7.Figure 7. A Successful File UploadIn addition, you should see the attachment, java.jpg, in the target server location, that is, the location that you specified in the UPLOAD_LOC variable within the FileUpload class. Here is the graphic image in the file: You can view the message flows to ensure that the attachment was secured by examining the log file for theapplication server located at <AS_HOME>/domains/domain1/logs/serverFurther ReadingSecure Conversations for Web Services With MetroSecuring WebServices Using WSITMetro User's Guide. See especially,Section 7: Metro Example Using a Web Container and NetBeans IDE, and Section 12:Using WSIT Security.About the AuthorAshutosh Shahi is a member of the Web Services Security group at Sun Microsystems. He currently works on implementationof WS-\* technologies related to security in the Metro Web Services stack from Sun. Before joining Sun, Ashutosh workedon the development of Apache Axis, an open source SOAP engine from Apache.

by Ashutosh Shahi Metro is a high performance, extensible, easy-to-use web services stack. It combines the JAX-WS reference implementation with Project Tango. Project Tango, also calledWeb Services...

JavaServer Faces (JSF) technology

True Abstraction: Composite UI Components in JSF 2.0 -- Part 2

by Ed BurnsPart 1 of this Tech Tipintroduced a powerful new feature inJavaServer Faces (JSF) 2.0 technology: composite userinterface (UI) components. This feature allows you to turn any collection of page markup into a JSF UIcomponent -- with attached validators, converters, action listeners, and value change listeners -- for use by page authors.In Part 1, you learned you how create a composite UI component and use it in a web application. In Part 2,you will learn how to add functionality to the composite component that you created. Note thatthere are many more things you can accomplish with composite UI components than are covered in this two-part tip.Also understand that the tip is based on a pre-release version of the JSF 2.0 specification, and an immature implementationof the composite component feature. So don't use the code you develop in this tip in a production JSF 2.0 application withoutfirst modifying it to conform to the final version of the JSF 2.0 specification.The tip assumes that you're already familiar withJava EE 5 web tier technologies, especially withJSF 1.2. A good place to learn about JSF 1.2, is the bookJavaServer Faces 1.2: The Complete Reference.Looking Back at Part 1This part of the tip assumes that you have created the composite UI as described in Part 1. Recall that in Part 1you created a using page named index.xhtml. You then added a composite component tag,<ez:loginPanel>, to the using page. Then you created a composite component by creating a filenamed loginPanel.xhtml in the /resources/ezcomp directory of your project and including<composite:interface> and <composite:implementation> tags in theloginPanel.xhtml file. The <composite:interface> and<composite:implementation> tags are new tags in JSF 2.0 and are used to declare the usage contractand implementation of the composite component.To view the application, you pointed your browser to http://localhost:8080/jsf-example01/. Figure 1displays the composite component rendered in the page.Figure 1. The Composite Component Rendered on the PageAdd Functionality: Make the Composite Component Emit an EventNow that you have created a composite UI, you'll want to add some true component behavior to it. So let's do that by addingsome text fields to the login panel component and allow the page author to declare that the component emits aloginEvent event. The page author can listen for this event and take appropriate action.Step 1. Add the implementationLet’s create a very simple, nontemplated, unlocalized, nonaccessible, login panel UI. Naturally, if you wanted to, youcould create a fully localized and accessible UI, using the features users have come to expect with JSF. You could alsocreate a templated UI, using the features users have come to expect with Facelets. All of this is a part of the JSF 2.0specification.Delete the following line in the loginPanel.xhtml file: <p>This is the composite component.</p>and replace it with the following: <table> <tr> <td>Username: <h:inputText id="username" /> </td> </tr> <tr> <td>Password: <h:inputSecret id="password" /></td> </tr> <tr> <td><h:commandButton value="Login" id="loginEvent" /></td> </tr> </table>The new code represents a simple table that contains JSF components for the username and password fields, and forthe login button.Step 2. Expose the parts of the implementation that you want to be the composite component contractIn general, the process of creating a composite component follows this pattern: You do the implementation, make itlook the way you want, then create an abstraction that allows the page author to easily work with the component.Correctly using the abstraction can greatly reduce the conceptual burden on the page author.In this case, the minimum you could expose to the page author is the fact that the login button was pressed.To expose that event, insert the following line into the <composite:interface> section ofloginPanel.xhtml: <composite:actionSource name="loginEvent" />This declares that the composite component contains a component that implements thejavax.faces.component.ActionSource2 interface, and therefore any features exposed by that interfaceare accessible to the user of the composite component. In this case,<composite:actionSource name="loginEvent"> refers to<h:commandButton value="Login" id="loginEvent" /> in the loginPanel.xhtmlfile.The loginPanel.xhtml file should now look like this: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:ez="http://java.sun.com/jsf/composite"> <h:head> <title>This will not be present in rendered output</title> </h:head> <h:body> <composite:interface> <composite:actionSource name="loginEvent"/> </composite:interface> <composite:implementation> <table> <tr> <td>Username: <h:inputText id="username" /> </td> </tr> <tr> <td>Password: <h:inputSecret id="password" /></td> </tr> <tr> <td><h:commandButton value="Login" id="loginEvent" /></td> </tr> </table> </composite:implementation> </h:body> </html>Step 3. Make the using page take advantage of the exposed featuresNow that you've added some function to the composite component, you need to go back to the using page and make it usethe new function.Insert the following line inside the <ez:loginPanel> element in the index.xhtml file. <f:actionListener for=loginEvent type="example01.LoginActionListener" />The for attribute says that this listener is for the action event on the composite component(<composite:actionSource>) named "loginEvent".Note that the use of an actionListener attribute on <ez:loginPanel> is not yet supported,it will probably be supported in the final release of JSF 2.0.Add the following line of code to index.xhtml below the line<p><h:commandButton value="reload"/></p>: <p><h:outputText value="#{loginActionMessage}" /></p>When the login event happens, a value is stored in request scope and then printed. A login component in a productionapplication would likely do more.Here is what the index.xhtml file should now look like: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:ez="http://java.sun.com/jsf/composite/ezcomp"> <h:head> <title>Example 01</title> <style type="text/css"> .grayBox { padding: 8px; margin: 10px 0; border: 1px solid #CCC; background-color: #f9f9f9; } </style> </h:head> <h:body> <p>Usage of Login Panel Component</p> <ui:debug hotkey="p" rendered="true"/> <h:form> <div id="compositeComponent" class="grayBox" style="border: 1px solid #090;"> <ez:loginPanel> <f:actionListener for="loginEvent" type="example01.LoginActionListener" /> </ez:loginPanel> </div> <p><h:commandButton value="reload" /></p> <p><h:outputText value="#{loginActionMessage}" /></p> </h:form> </h:body> </html> Add some Java code to the ActionListener to process the login. Do this by expanding theSource Packages node in the jsf-example01 project. Then open theLoginActionListener.java file and insert the following code into the body of theprocessAction method. FacesContext context = FacesContext.getCurrentInstance(); context.getExternalContext().getRequestMap().put("loginActionMessage" "Login event happened");The updated content of the LoginActionListener.java file is as follows: package example01; import javax.faces.component.UIComponent; import javax.faces.component.ValueHolder; import javax.faces.context.FacesContext; import javax.faces.event.AbortProcessingException; import javax.faces.event.ActionEvent; import javax.faces.event.ActionListener; public class LoginActionListener implements ActionListener { public void processAction(ActionEvent event) throws AbortProcessingException { FacesContext context = FacesContext.getCurrentInstance(); context.getExternalContext().getRequestMap().put("loginActionMessage", "Login event happened"); } } Because this action listener is implemented in Java, you must rebuild and redeploy the application after makingany changes to the Java file.Note however that Sun’s JSF 2.0 implementation snapshot, Mojarra, has the ability for any JSF artifact,including ActionListener implementations, to be implemented inGroovy. You do not have to rebuild and redeploy theapplication if the ActionListener is implemented in Groovy.See Ryan Lubke’s blog Groovy + Mojarrato learn how to use Groovy with JSF.After the application is redeployed, reload the browser page and press the Login button. You should see the pagecontent shown in Figure 2.Figure 2. The Login Event Recorded on the PageAdd Functionality: Extract Values From the Composite ComponentYou have now dynamically created a composite component, defined the implementation, declared the interface, and used thecomponent in the using page. In this final example, you'll learn one way to leverage the composite component fromwithin the ActionListener implementation.Step 1. Expose the values in the contractIn this step, you'll continue to follow the best practice of information hiding by exposing only the minimum amountof information necessary for the page author to use the component. Any useful login panel must determine what usernameand password values were entered by the user. To enable the login component to get this information, you need to exposethose values to the page author. You do this by adding some entries in the <composite:interface>section of the loginPanel.xhtml file.Add the following lines to the <composite:interface> section of loginPanel.xhtml: <composite:valueHolder name="username" /> <composite:valueHolder name="password" />This tells the page author that the composite component has two inner components that implementjavax.faces.component.ValueHolder. It means that any attached objects valid for ValueHoldermay be attached to the composite component. Note that the values of the name attribute must match the givenid values in the <composite:implementation> section.Step 2. Use the exposed values in the LoginActionListenerReplace the implementation of the processAction() method in LoginActionListener.java filewith the following code: public void processAction(ActionEvent event) throws AbortProcessingException { FacesContext context = FacesContext.getCurrentInstance(); UIComponent source = event.getComponent(); ValueHolder username, password; username = (ValueHolder) source.findComponent("username"); password = (ValueHolder) source.findComponent("password"); String message = "Login event happened" + " userid: " + username.getValue() + " password: " + password.getValue(); context.getExternalContext().getRequestMap().put("loginActionMessage", message); }The username and password assignments in the updated implementation of theprocessAction() method takes advantage of three characteristics of JSF:In JSF 2.0, every composite component implements javax.faces.NamingContainer.Since the beginning of JSF, the semantics of the findComponent() method on UIComponentstate that if the argument componentId does not match any child components, then look to the closestancestor component that implements NamingContainer and ask it to find the component.Since the beginning of JSF, an ActionListener is passed an ActionEvent whose sourceproperty is the component that fired the event. That component will be a child of the composite component.The line that begins String message = "..." constructs a message by extracting the value from theusername and password fields, and places it in request scope. The message is then printed by the<h:outputText> tag in the using page.Figure 3 shows what gets displayed if you enter a value in the username and password fields and thenpress the Login button.Figure 3. The Login Event With Captured Username and Password ValuesYou have now dynamically created a composite component, defined the implementation, declared the interface, and usedthe component in the using page. The composite component publishes a loginEvent. The ActionListenerfor that event can query its source for other published components within the composite component, and values can be extractedfrom those components.SummaryJSF 2.0 provides a new taglib for creating composite components. This taglib, combined with the inclusion of Faceletstemplating into JSF 2.0, gives you the ability to create composite components, declare the usage contract of compositecomponents, and allow the page author to use those components exactly as if they were true JSF UIComponents.Further ReadingTrueAbstraction: Composite UI Components in JSF 2.0 -- Part 1JavaServer Faces (JSF) 2.0 technologyJavaServer Faces 1.2: The Complete ReferenceJSF 2.0 New Feature Preview Series(Part 4): Resource RelocationGroovy + MojarraAbout the AuthorEd Burns is a senior staff engineer at Sun Microsystems. Ed has worked on a wide variety of client and server-side webtechnologies since 1994, including NCSA Mosaic, Mozilla, the Sun Java Plugin, Jakarta Tomcat and, most recentlyJavaServer Faces. Ed is currently the co-spec lead for JavaServer Faces. He is the coauthor ofJavaServer Faces 1.2: The Complete Reference andthe author of Secrets of the Rockstar Programmers.Enterprise Tech Tips SurveyWe'd like your feedback on the Enterprise Tech Tips -- what you like, what you don't like, what you'd like to see in futuretips. Please go to the survey and give usyour feedback. Your responses will help us make the Tech Tips better serve your needs. The survey period is September 15through September 30.

by Ed Burns Part 1 of this Tech Tip introduced a powerful new feature inJavaServer Faces (JSF) 2.0 technology: composite userinterface (UI) components. This feature allows you to turn any collection...

JavaServer Faces (JSF) technology

True Abstraction: Composite UI Components in JSF 2.0 -- Part 1

by Ed BurnsThis Tech Tip introduces a powerful new feature inJavaServer Faces (JSF) 2.0 technology: composite userinterface (UI) components. This feature allows you to turn any collection of page markup into a JSF UIcomponent -- with attached validators, converters, action listeners, and value change listeners -- for use by page authors.In this tip you'll learn you how create a composite UI component and use it in a web application. In doing so, you'llsee some of the things that the feature can do. But there are many more things you can accomplish with compositeUI components. Also understand that the tip is based on a pre-release version of theJSF 2.0 specification, and an immature implementation of the composite component feature. So don't use the codeyou develop in this tip in a production JSF 2.0 application without first modifying it to conform to the final versionof the JSF 2.0 specification.The tip assumes that you're already familiar withJava EE 5 web tier technologies, especially withJSF 1.2. A good place to learn about JSF 1.2, is the bookJavaServer Faces 1.2: The Complete Reference.Abstraction and Composite UI ComponentsAbstraction, that is, generalizing the information content of a concept so that it retains only the information that isrelevant for a particular purpose, is a central concept in software development. But how good are software technologiesin expressing abstractions? This tip provides an answer to that question for one technology: JSF. Theanswer is "not as good as it could be."In spite of its flaws, object-oriented (OO) software continues to be the most popular way that software professionalsdo abstraction. From the outset, JSF has claimed to build on OO principles to bring the OO brand of abstraction to theworld of web applications. The user-facing aspect of OO in JSF is the UIComponent ("user" heremeans the person using JSF to develop a web application). Unfortunately, the act of creating abstractions usingUIComponent is more complex than necessary.Several approaches have been taken to solve this problem, the most successful is the templating approach used byFacelets. This approach involves creating an XHTML pagethat contains template text and other JSF components, then treating the XHTML page as a component to be used in otherpages. When you create a component in this way the component is called a composite component. Faceletscomposite components are useful, but they do not act as true UIComponents in the page. For example, youcan't attach validators, listeners, or a converter to them.A real UIComponent must be able to support these operations. What is needed is a way to create compositecomponents that support all the features of a real UIComponent. This feature should be as simple as possible,require zero or minimal configuration, should support fast iterative development (without redeployment of the web application),and support all the features people have come to expect from JSF. And those are the objectives of thecomposite UI feature of JSF 2.0.Install the Software Required to Build and Run the ExamplesIn this tip you're going to build and run a number of examples that use the composite UI feature. However, before youdo that, you'll need to do a little setting up. The machine you're working on must be connected to the Internet and havethe proper proxy and firewall settings for all the software used in this tip. In addition, you need to install and configurethe required software as follows:If you haven't already done so, download and install the following:NetBeans IDE 6.1. Choose either the "All" or "Web and Java EE" download bundle.GlassFish v2 application server.If you download the "Web and Java EE" download bundle, it also downloads the latest stable release of GlassFish,GlassFish v2 Update Release 2 (UR2)If you downloaded GlassFish v2 separately, register it in NetBeans as follows:Right-click on the Servers node in the Services window.Select Add Server.Select GlassFish V2 as the Application Server.Click the Next button.Click the Browse button and browse to the location that you installed GlassFish v2.Click the Choose button.Click the Next button.Set the Admin Password to the default, adminadmin, unless you chose a different password for GlassFish v2.Click the Finish button.Install the Mevenide2-Netbeans plugin, which provides support in NetBeans for Maven 2 projects, as follows:Start NetBeans IDE 6.1.Select Plugins from the Tools menu.Select the Available plugins tab in the Plugins window.Select the Maven plugin.Click the Install button.Download and install Maven.Don't worry if you're not familiar with Maven, you won't need to learn it to build and run the examples inthis tip.Update the GlassFish install with the Sun’s JSF 2.0 implementation snapshot,mojarra-2.0.0-SNAPSHOT-glassfish-updater.Downloadthe snapshot, then install it.To install the snapshot in a UNIX platform, enter the following command from the command line: sudo java -jar <glassfish-jsf-update.jar> <glassfish_inst_ dir>where <glassfish-jsf-update.jar> is the fully-qualified path of the snapshot, and <glassfish_inst_ dir>is the directory where you installed GlassFish v2. For example, sudo java -jar /Users/edburns/Projects/JavaEE/workareas/mojarra-HEAD/dist/mojarra-2.0.0- SNAPSHOT-glassfish-updater.jar /Applications/NetBeans/glassfish-v2ur2You'll be prompted to enter a password.On non-UNIX platforms, you don't prefix the java command with sudo. For example: java -jar C:\\CompUITip\\mojarra-2.0.0-SNAPSHOT-glassfish-updater.jar C:\\glassfish-v2ur2Also on non-UNIX platforms, you may need to open your command shell with "Run as Administrator", and entera password. In any case, you will need to accept the license agreement. After you accept, you'll see a message similar to the following in the console: Updating glassfish at /Applications/NetBeans/glassfish-v2ur2 with new JSF jars.Verify that the JSF implementation has been updated in GlassFish. To do that, start GlassFish v2 as follows:Expand the Servers node in the Services window.Right-click on GlassFish V2.Select Start from the pop-up menu.Once the server starts, please visit the admin console GUI. By default, this is http://localhost:4848/. Doing so will cause the JSF module to be loaded. You should see a message similar to the following in the GlassFish V2 output window in the NetBeans 6.1 IDE: Initializing Mojarra (2.0.0-SNAPSHOT) for context ''Install the updated javaee.jar file into the local Maven repository by entering the following commands onthe command line: <maven_dir>/bin/mvn -cpu install:install-file -DgroupId=200808-techtip -DartifactId=javaee-api -Dversion=200808-techtip -Dpackaging=jar -Dfile=glassfish install directory/lib/javaee.jar <maven_dir>/bin/mvn -cpu install:install-file -DgroupId=200808-techtip -DartifactId=jsf-api -Dversion=200808-techtip -Dpackaging=jar -Dfile=glassfish install directory/lib/jsf-api.jar where <maven_dir> is the directory where you installed Maven. These commands will install the updatedjavaee.jar and jsf-api.jar files into your local Maven repository.This step is necessary because the examples depend on those JAR files being accessible to Maven.Verify that the JAR files were correctly installed into the local Maven repository. On UNIX platforms,enter the following command: find ~/.m2/repository/200808-techtip -printThe correct results from the find command should include the following JAR files:Right-click on Web Pages and choose New then Other. This opens the New File window.In the New File window, select the Web category and the XHTML file type as shown in Figure 2.Figure 2. Creating an XHTML FileThen click the Next button.This opens a name and location page. Enter index in the XHTML File Name field and click the Finish button.This creates an XHTML file named index.xhtml.Expand the Web Pages node. Right-click on index.xhtml and select Open.Replace the content in the index.xhtml file with the following code: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets"> <h:head> <title>Example 01</title> <style type="text/css"> .grayBox { padding: 8px; margin: 10px 0; border: 1px solid #CCC; background-color: #f9f9f9; } </style> </h:head> <h:body> <p>Usage of Login Panel Component</p> <ui:debug hotkey="p" rendered="true"/> <h:form> <div id="compositeComponent" class="grayBox" style="border: 1px solid #090;"> </div> <p><h:commandButton value="reload" /></p> </h:form> </h:body> </html> If you're familiar with Facelets, you'll notice that this is a Facelets page. For JSF 2.0, Facelets is the preferred way todeclare JSF Pages. JSP is supported for backwards compatibility, but not all JSF 2.0 features will be available for viewsusing JSP as their page declaration language. In Facelets, pages are authored exclusively in XHTML. JSF UI componentlibraries are brought into a page by declaring an XML namespace, as shown below: xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets">This page uses the jsf/html, the jsf/core, and the jsf/facelets taglibs.Notice the <h:head> and <h:body> tags in the page. These are two new tags in JSF 2.0.The <h:head> tag represents the head element of an HTML page. The <h:body> tagrepresents the body element of an HTML page You can learn more about these tags in Ryan Lubke's blogJSF 2.0 New Feature Preview Series(Part 4): Resource Relocation.Rebuild the application by right-clicking on jsf-example01 in the Projects window and selecting Build.In response, Maven builds a war file and exploded war version of the application. The war file is locatedat <sample_install_dir>/200808-enterprise-tech-tip/code/example01/target/jsf-example01.war.The exploded war is in<sample_install_dir>/200808-enterprise-tech-tip/code/example01/target/jsf-example01/.Deploy the built application. There are several ways to do this. The following way works well with the Maven plugin for theNetBeans IDE. Create a .javaee-passwordfile file in your home directory. The contents of the file mustbe AS_ADMIN_PASSWORD=adminadmin. Then use the asadmin deploydir command in thebin subdirectory of the GlassFish installation directory to deploy the exploded war.For example: ./asadmin deploydir --user admin --passwordfile /Users/edburns/.javaee-passwordfile --contextroot jsf-example01 /example01/target-jsf-example01 Deploying the application in this way enables you to add XHTML files to the example without redeploying the application.Given the dynamic nature of composite components, this greatly increases your ability to stay in theflow state. The NetBeans Maven plugin automaticallycopies any XHTML files in your Web Pages section to the deployed application. All you have to do is click the Save button.Point your browser to http://localhost:8080/jsf-example01/ to view the running application.Step 2. Add the composite component tag to the using pageNow that you've created the using page (index.xhtml), it’s time to add the composite component tag toit as follows:Add the following content to the <div> element in the using page: <ez:loginPanel> </ez:loginPanel>Save the file and reload the browser page. You should see a descriptive error that says something like the following: The prefix "ez" for element "ez:loginPanel" is not bound.You get this message because you have not yet defined the "ez" prefix.Add the namespace in which the composite component will reside to the <html> element in the using page.Specify the namespace as follows: xmlns:ez="http://java.sun.com/jsf/composite/ezcomp"Save the file and reload the browser. You should no longer see the previous error message. If you view the page source,you'll see the <ez:loginPanel> element. The Facelets implementation in Mojarra simply renders anycomponent that is not fully defined. Any tag library beginning with http://java.sun.com/jsf/composite/ is assumed to bea composite component library.The using page should now look like this: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:ez="http://java.sun.com/jsf/composite/ezcomp"> <h:head> <title>Example 01</title> <style type="text/css"> .grayBox { padding: 8px; margin: 10px 0; border: 1px solid #CCC; background-color: #f9f9f9; } </style> </h:head> <h:body> <p>Usage of Login Panel Component</p> <ui:debug hotkey="p" rendered="true"/> <h:form> <div id="compositeComponent" class="grayBox" style="border: 1px solid #090;"> <ez:loginPanel> </ez:loginPanel> </div> <p><h:commandButton value="reload" /></p> </h:form> </h:body> </html> Step 3. Create the composite componentThe design of JSF 2.0 is influenced by the philosophy of convention over configuration, popularized by Ruby on Rails.To realize composite components, this philosophy is combined with the resource loading feature, described in Ryan Lubke’sblog JSF 2.0 New Feature PreviewSeries (Part 2.1): Resources.Here's how the approach works in the example application. The JSF runtime takes the name of the composite componenttag in the using page, that is,loginPanel, and appends .xhtml to it, arriving at loginPanel.xhtml. This value isthe resource-name. The namespace short-name that prefixes the composite component tag, ez:,has an entry in the <html> element, that is,xmlns:ez="http://java.sun.com/jsf/composite/ezcomp". The content afterhttp://java.sun.com/jsf/composite/ in this case, ezcomp, is the library-name.The library-name and resource-name are used to create a Resource instance.JSF 2.0 has a method that creates a UIComponent from a Resource. Due to these conventions, any.xhtml file in a resource library can be accessed as a composite component.There are several ways to create a resource library, as shown inRyan’s Blog. Here is one way to do it.In the same directory as the using page (index.xhtml),you will see a directory named resources. In thisdirectory is a sub-directory named ezcomp. The name of thesubdirectory (in this case, ezcomp) must correspond to theend part of the composite xmlns for the namespace short-name thatprefixes the composite component tag.To create these directories, you can right-click on Web Pages in the Project window and select New then Folder.In the same way that you created the index.xhtml file for the using page, create a new XHTML file namedloginPanel.xhtml inside the ezcomp directory.Open the loginPanel.xhtml and replace its contents with the following code: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:composite="http://java.sun.com/jsf/composite"> <h:head> <title>This will not be present in rendered output</title> </h:head> <h:body> <composite:interface> </composite:interface> <composite:implementation> <p>This is the composite component.</p> </composite:implementation> </h:body> </html>Notice the <composite:interface> and <composite:implementation> tags. These are newin JSF 2.0 and are used to declare a composite component. In the final version of JSF 2.0, these tags will be optional, butfor now they are required.The <composite:interface> tag declares the usage contract of the composite component. Everything the pageauthor needs to know to use the composite component is included in this section. TheThere isn't much special about what you've done so far. Facelets has always had this kind of templating feature,and in fact that’s what the example is leveraging. In the next issue of the Enterprise Tech Tips, you will learn how toadd functionality to the composite component you've created.SummaryJSF 2.0 provides a new taglib for creating composite components. This taglib, combined with the inclusion of Faceletstemplating into JSF 2.0, gives you the ability to create composite components, declare the usage contract of compositecomponents, and allow the page author to use those components exactly as if they were true JSF UIComponents.Further ReadingJavaServer Faces (JSF) 2.0 technologyJavaServer Faces 1.2: The Complete ReferenceJSF 2.0 New Feature Preview Series(Part 2.1): ResourcesAbout the AuthorEd Burns is a senior staff engineer at Sun Microsystems. Ed has worked on a wide variety of client and server-side webtechnologies since 1994, including NCSA Mosaic, Mozilla, the Sun Java Plugin, Jakarta Tomcat and, most recentlyJavaServer Faces. Ed is currently the co-spec lead for JavaServer Faces. He is the coauthor ofJavaServer Faces 1.2: The Complete Reference andthe author of Secrets of the Rockstar Programmers.

by Ed Burns This Tech Tip introduces a powerful new feature inJavaServer Faces (JSF) 2.0 technology: composite userinterface (UI) components. This feature allows you to turn any collection of page...

Phobos

Building An Ajax-Enabled Web Application Using Phobos and jMaki

by Roberto ChinniciPhobos is a lightweight, scripting-friendly, web applicationenvironment that runs on the Java platform. Using Phobos, you can take advantage of the benefits offered byscripting languages and leverage the power of the Java platform. Being scripting-friendly, Phobos providesa programming environment that fosters rapid application development. The primary language supported by Phobos is JavaScript,which Phobos supports using the Mozilla Rhino scripting engine.Scripting languages can be powerful and convenient. They also enable an interactive form of development in whichyou can progressively refine the behavior of an application until it is ready for deployment and use. This is especiallyimportant in developing Ajax-enabled web applications. These applications typically require a lot ofinteractive in-browser testing and refinement. In addition to enabling an interactive mode of development, Phobos allowsscripting developers to call into any Java code at any time. As a scripting developer, you can reuse APIs,libraries, and frameworks that run on the Java platform. Using Phobos offers a "best of both worlds" approach,in which you can write "soft" -- often changing code -- in a scripting language, and write"hard" -- rarely modified code -- in a compiled language such as the Java programming language.In this tip, you'll use Phobos and jMaki to create a simple Ajax-enabled web application. The jMaki frameworkis a lightweight framework for creating Web 2.0 applications using standards-based technologies such asCSS, HTML, and JavaScript. For an introduction to jMaki, see the January 27, 2007 Tech TipIntroduction to jMaki.You will build the application using the NetBeans IDE anddeploy the application to the GlassFish application server.The tip assumes that you have NetBeans IDE 6.1and theGlassFish v2ur2 application serverinstalled. You can install them together by installing theWeb & Java EEversion of NetBeans IDE 6.1.A package that contains the code for the sample application accompanies the tip.The code examples in the tip are taken from the source code of the sample (which is included in the package).The Phobos FrameworkThe key to understanding how a Phobos application works is to become familiar with the underlying framework.In Phobos, whenever a request comes in to the servlet container, the container invokes the Phobos servlet. The Phobosservlet then delegates the handling of the request to the Phobos framework, which is written in JavaScript. The frameworkattempts to match the request URI with a certain number of predefined patterns. When a match is found, the frameworkinvokes the script or controller associated with that pattern.In Phobos there are many ways to handle a HTTP request. The simplest way is by writing a plain script which has accessto two predefined variables called request and response. These variables hold a reference tothe HttpServletRequest and HttpServletResponse that the servlet container creates. Theuser-written script can then perform the appropriate request-handling logic and produce a response.Although scripts are in principle sufficient to cover every task, it is better to follow a more structuredapproach based on the MVC (model-view-controller) pattern. In Phobos, all three components are written in JavaScript.The controller is a JavaScript class hosted inside a script whose name must match that of the controller. The view is anEmbedded JavaScript (EJS) file, that is, a file that contains HTML with embedded JavaScript statements and expressions.The definition of the model is left to the application. Typically, the model consists of a mix of JavaScript and Javaobjects.To learn more about the Phobos framework, seeAn Overview of Phobos.The ApplicationThis tip uses Phobos to reimplement the PHP application that Ludovic Champenois presented in theJune 16, 2008 Tech Tip Using jMaki withPHP on OpenSolaris.See "The Sample Application" section of that tip for a description of the application.Figure 1 shows a web page displayed by that application.Figure 1. A Web Page from the PHP ApplicationNotice that the PHP application uses MySQL as the database. However, the Phobos version of the application usesJavaDB, rather than MySQL. You'll find the Java DB database bundled with GlassFish v2ur2.Install the Phobos Plugins in NetBeans IDE 6.1Before building the application, you need to add support for Phobos to the NetBeans 6.1 IDE. This supportis provided by Phobos-related plugins which include functionality such as a new Phobos project typeand a syntax-aware editor for EJS pagesTo install the Phobos plugins:Select Plugins in the Tools menu of the IDE. This opens the Plugins window.Click the Available Plugins tab if it's not already selected.Check the checkboxes for the EJS and NetBeans 6 Phobos support plugins in the Phobos categoryas shown in Figure 2.Figure 2. Selecting the Phobos PluginsClick the Install button. If it is not already installed, NetBeans will also install the jMaki Ajax Support plugin.Configure the Java DB DatabaseNext, let's create a new database for the application.Start Java DB as follows:Click the Services tab in the NetBeans IDE.Expand the databases node. You should see Java DB in the list of databases.Right-mouse click on Java DB and select Start Server.Create a Java DB database as follows:Right-mouse click on Java DB and select Create Database. This will open a Create Java DB Database window.Enter the database name, data. This is the database name preconfigured in Phobos.(See the section Connecting to the Database for more information about databaseconfiguration parameters that are predefined in Phobos.) Also, enter a user name, APP, and a password, APP.(These parameters, as well as the type of database to access, are fully configurable and customizable.You can specify different parameters or a different database type when you develop the application or laterwhen the application is deployed.)Click the O.K. button.Expand the Drivers node. You should see a driver for jdbc:derby://localhost:1527/data as shownin Figure 3. This is the driver for the data database.Figure 3. Driver ListCreate a Project for the Web ApplicationNow that you have added the Phobos plugins to the NetBeans IDE and created and configured a Java DB database, it's timeto create the application. Start by creating a new project in the NetBeans IDE, as follows:Select New Project in the File menu of the IDE. This opens the New Project window.Select Web for the category and Web Application for the project in the New Project windowand click the Next button. This opens the Name and Location panel.Enter PhobosSample in the name field and select an appropriate location for the project.Then click the Next button. This opens the Server and Settings panel.Ensure that GlassFish V2 is selected as the server and Java EE 5 as the Java EE version.Then click the Next button. This opens the Frameworks panel.Select jMaki Ajax Framework and Phobos Runtime as a Web Application Extension in theFrameworks field. When you select the jMaki Ajax framework, the panel displays a CSS Layout section. ChooseNo CSS Style in the CSS Layout section, as shown in Figure 4.Figure 4. Selecting the Phobos and jMaki FrameworksClick the Finish button to create the project.Expand the new PhobosSample project in the Projects tab. Figure 5 shows thatin addition to familiar elements that comprise a web application project, such as web pages and configuration files, thePhobosSample project includes Phobos-specific elements that reside in the Phobos Application folder.Figure 5. PhobosSample ProjectCustomize the Scripts for the ApplicationA Phobos application contains a set of scripts that are executed in response to web requests. Additionally, it containsEJS pages that are used as views. These pages contain code snippets written in JavaScript that areexecuted when the page is rendered. This allows dynamic content to be generated.The application you created contains a predefined model/view pair. If you run the application as it currently exists,you will see the web page displayed in Figure 6. You can see this default page by right-clickingPhobosSample in the Projects tab and selecting Run.Figure 6. Default Page Displayed by a Phobos ApplicationYou need to customize the model and view to produce the results you want for the application. That requires you toupdate a number of pregenerated scripts. In addition, you need to create some other scripts to do things such asconnect to the database. The remainder of the tip focuses on these scripting actions.Connect to the DatabaseFor the application to work, it needs to connect to the database. In Phobos, you implement the connection using a startupscript. This is a special script that the Phobos runtime executes when the web application is initialized. The scriptinitializes the database layer, connects to the database, and checks that the table required by the application exists. Ifthe table does not exist, the script creates it.Note that these actions were performed by the setup.php page in the PHP version of the application.In the Phobos version of the application, there is no need to manually point the browser to a setup page because theapplication will do that automatically at startup.To create the startup script:Right-mouse click on the module package under Phobos Application and select New then Other. This open a New Filewindow.Select Scripting as the category and Phobos Script as the file type, then click the Next button.This opens a Name and Location panel.Enter application as the script file name. Ensure that the full name of the resource inthe Created File field is web/WEB-INF/application/module/application.js.Click the Finish button to create the script file. You will see the new file, application.js,added under the module package.Open the application.js file.The library.common.define function call that wraps the code below it is the Phobos way of creating a package.You can think of that line as being equivalent to the statement package module.application; in the Javaprogramming language.The JavaScript language does not have a native package construct. Because of that , Phobos (and any other JavaScript library)had to define its own construct.The body of the package defines and exports the onStartup function. That function is invoked by the Phobosruntime when the application starts up. The onStartup function selects the client database as the preferreddatabase and initializes it. Its configuration parameters are predefined in Phobos as follows: application.datasource.client = { dataSourceClassName: "org.apache.derby.jdbc.ClientConnectionPoolDataSource", username: "APP", password: "APP", properties: { serverName: "localhost", portNumber: "1527", connectionAttributes: ";create=true", databaseName: "data" } } As you can see, the databaseName is data, which matches the name of the database you createdearlier in the NetBeans IDE. If you want to use a different database, you need to copy the code shown above, paste it intothe application module, and edit it to suit your needs.The rest of the code in the application.js script tries to connect to the database and execute a SQL query.If it fails, it executes an SQL CREATE statement to create the table that holds the product information. This codeuses the Phobos db library (library.db), which wraps JDBC inside a more JavaScript-friendly layer. You can getmore details about this library in thePhobos Library Documentation.Run the application again to ensure that the added code is correct and to test that the application can connect tothe database. If everything is correct, you'll see the same page as before -- the contents of the page won't change untilyou modify the main controller for the application. In case of an error, you should see a Phobos error page with a completestack trace.Change the Main PageIf the application can connect to the database, it's time to start implementing the rest of the code, starting with the mainpage. This page is the equivalent of the index.php page in the PHP version of the application.However, there are some notable differences. Unlike PHP, Phobos uses a full MVC framework, so the application logic is splitbetween view and controller.Let's update the view first -- it's the main.ejs file in the view package under Phobos Application in theproject. The contents of the view are similar to those of the index.php page in the PHP version. The maindifference is that instead of using PHP snippets inside the <?php ?> sections, the view uses JavaScript snippetsenclosed within <% %>.Replace the code in the main.ejs file with the following: <html> <head> <title>Phobos Sample Application</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <link rel="stylesheet" href="style.css"> </head> <body> <br>Using the following form, you can add products that will be inserted in a JavaDB database, and displayed using the jMaki Ajax framework in the table below.<br> <br><br> <form action="#" > Product Name : <input id="name" name="name" type="text"><br> Product Category :<input id="category" name="category" type="text"><br> Product Price : <input id="price" name="price" type="text"><br> </form> <% library.jmaki.insert({ component: "yahoo.button", value: { label : 'add a product' } }); %> <br> <b><center>List of Products:</center></b><br><br> <% library.jmaki.insert({ component: "yahoo.dataTable", args: {columns : [ { 'label' : 'name', 'id' : 'name'}, { 'label':'category', 'id' : 'category'}, { 'label': 'price ', 'id' : 'price'} ]}, service: library.httpserver.makeUrl("/main/listProducts") }); %> </body> </html> As you paste the contents into the file, the NetBeans IDE highlights the JavaScript sections (by default, it uses alight-green color) to point out that the sections render dynamic content. This differentiates these sections fromthe rest of the page, which is rendered as entered.Notice the library.jmaki.insert function in the main.ejs file. This function is used in Phobos toinsert jMaki widgets. If you compare the function to theaddWidget function in the index.php file of the PHP version of the application, you'll see thatthe arguments to both are similar. They also resemble the arguments that the jMaki JSP tag library expects. This makes thetransition from PHP to Phobos straightforward.One important difference between the way the Phobos version and the PHP version use jMaki widgets is that in Phobos thevalues and arguments (args) passed to the widget are real JavaScript objects, not strings. This highlightsone of the most interesting features in Phobos. The client (that is, the scripts running inside the browser) and theserver share a common language, JavaScript. This makes it easier to share data between the two tiers and eliminates a lotof translation work. In particular, JavaScript Object Notation (JSON) becomes a native format supported by both tiers,and so, is a particularly appealing data format.Another thing to point out in the EJS page is the call to the library function,library.httpserver.makeUrl("/main/listProducts"). Phobos views are stored in a separate directory treefrom static content, so that referencing other resources or even controllers from a view is error-prone. Thelibrary.httpserver.makeUrl function helps here because it allows you to specify an absolute URL as an argument.The URL is then replaced with the correct URL at runtime. In the example, the URL points to the main controller andtriggers invocation of the listProducts method when it is accessed.Add jMaki GlueBecause the application uses jMaki, you need to create a jMaki Glue file, glue.js, that "glues"the widgets on the page together using a publish-subscribe event model. Replace the contents of the glue file,resources/glue.js, which you can find under Web Pages in the project, with the following: // uncomment to turn on the logger jmaki.debug = false; // uncomment to show publish/subscribe messages jmaki.debugGlue = false; // map topic for the add Product button jmaki.subscribe("/yahoo/button/onClick", function(args) { // get the values of the 3 fields in the form: var name= document.getElementById("name").value; var category= document.getElementById("category").value; var price= document.getElementById("price").value; //do an ajax request to the add server side logic, with the correct params: jmaki.doAjax({ url : "addProduct", method : "POST", content : { name : name, category : category, price : price }, callback: function(req) { //in this call back, we just add a new row to the local jMaki table if (jmaki.trim(req.responseText) == "OK") jmaki.publish ('/yahoo/dataTable/addRow', { value: { name : name, category : category, price : price } }); else alert ("error adding a row: "+req.responseText); } }); }); Update the ControllerThe modified view relies on some additional behavior from the controller, the listProducts action, whichyou need to implement. However, first, let's rewrite the generatedcontroller code to use more stylish, easier to read JavaScript. Replace the code in themain.js file in the controller package below Phobos Application with the following: library.common.define(controller, "main", function() { function Main() { } Main.prototype.show = function() { model = {}; library.view.render("main.ejs"); } // export the controller class this.Main = Main; }); Notice the similarity between this code and the code in the application.js file defined earlier. A controlleris itself a module, but defined under the controller node in the project. A controller module definesa controller class, representedin JavaScript by a constructor function -- in this case Main. In addition, a controller class has one or moreaction methods, which in JavaScript are usually defined using the constructor prototype. The entire code is idiomatic,so it may appear strange at first.You modified some code, so let's test it by running the application again. When you run the application, you should seethe page displayed in Figure 7. Although part of the page renders properly, it also displays some errormessages.Figure 7. The Application Page Displaying ErrorsThe reason for these errors is that the application is trying to insert some jMaki widgets into the page, but the resourcesfor those widgets are not in the application. The easiest way to fix the problem is to do the following:Open the main.ejs view.Open the jMaki palette in the NetBeans IDE.Expand the jMaki Yahoo item in the jMaki palette.Drag and drop the jMaki Yahoo Button and Data Table widgets onto the page.Figure 8 shows the part of the code generated by the drag and drop.Figure 8. Code Generated by Dragging and Dropping jMaki Yahoo WidgetsThe jMaki palette automatically inserts some JavaScript snippets that call the library.jmaki.insert function.You can safely delete these snippets because the page already contains that code. A side benefit of dragging and droppingthe widgets is that the necessary resources are added to the project. You can find the added resourcesunder the Web Pages/resources/yahoo folder in the project.Run the application again. As Figure 9 shows, the resource-related error messages have disappearedand the button near the top of the page is rendered correctly. However, at the bottom of the page, where the table shouldbe, there is still an error message.Figure 9. The Application Page Displaying a Failed to Load Data ErrorThe error message is an indicator that the listProducts method in the controller has not yet been defined.Define it now by adding the following code inside the main.js script: Main.prototype.listProducts = function() { library.httpserver.sendJSON({rows: module.persistence.fetchProducts()}); } Add a Persistence LayerIn keeping up with the incremental nature of development in Phobos, let's now implement a persistence layer. This allowsyou to test the listProducts functionality in the browser. To do this, create a persistence.jsmodule. You can follow the same process you did to create the application.js module, that is, thestartup script.After you create the persistence.js module, replace its contents with the following code: library.common.define(module, "persistence", function() { this.fetchProducts = function() { var sql = new library.db.SqlHelper(); var products = []; library.db.using(sql, function() { products = sql.select({table: "products", columnMapping: columnMapping}); }); return products; }; this.addProduct = function(product) { var sql = new library.db.SqlHelper(); library.db.using(sql, function() { sql.insert({table: "products", values: product, propertyMapping: propertyMapping, prepare: true}); }); }; var columnMapping = { ID: "id", NAME: "name", CATEGORY: "category", PRICE: "price" }; var propertyMapping = { id: "ID", name: "NAME", category: "CATEGORY", price: "PRICE" }; }); As is the case in the startup script, the persistence module uses the Phobos db library to avoid having to directlyinteract with JDBC. The fetchProducts and addProducts functions are exported from the moduleby adding them to this object, which in this context is the module itself. The code to add a new product is simple.The code does not validate the input data. Neither does it handle exceptions, which are simply passed backto the caller. A production application would include many more checks to make sure no illegal or malicious data is sent to thedatabase.The two mapping objects at the bottom deserve an explanation. Because Java DB converts all column names to uppercase,if you retrieve data from the database you would find properties with the names NAME, CATEGORY, and PRICE. But if youexamine the main.ejs page, you'll notice that it expects properties called name, category and price, respectively.It is easier to do the conversion in the database layer by specifying two mappings of column names toproperty names and back. This approach is also useful when you want to map names written in camel case that are commonlyused in JavaScript, for example, streetAddress, to underscore-rich names that database professionals typically use,such as STREET_ADDRESS.Now that the persistence layer is completed, you can test the addProducts controller action by pointing the browserto the URL http://localhost:8080/PhobosSample/main/listProducts. You should see the following text in the browser:{rows:[]}.This is an expected result because the database table is currently empty.Add the ProductsWhen a user of the application clicks on the add a Product button to add a product, the application sends an Ajax POSTrequest to theaddProduct method of the main controller. It's now time to implement this method by adding the followingcode to the main.js controller script: Main.prototype.addProduct = function() { var params = library.httpserver.parseRequestParameters(); if (params.name) { module.persistence.addProduct({name: params.name, category: params.category, price: params.price}); library.httpserver.sendOk(); } else { library.httpserver.sendNotFound(); } } This function uses the parseRequestParameters library function to parse the body of the POST request intoa JavaScript object. The function then extracts the data from that object and passes it to the database layer.Here, because all the property names match, the function could have been designed to pass the params objectdirectly. However, in general, it is safer to insulate the web-facing layer from the database layer. This avoidsexposing the database to attacks by malicious clients.Test the ApplicationThe application is complete and ready for testing. Run it and try adding a few products. You should see the updatesimmediately reflected in the UI as shown in Figure 10.Figure 10. Adding Products to the DatabaseYou can also directly point the browser to the listProducts action at http://localhost:8080/PhobosSample/main/listProducts.This will display the data in JSON format: {"rows":[{"id":"1","category":"car","price":"15000","name":"fiat"},{"id":"2","category":"car","price":"18000","name":"subaru"}]} SummaryThis tip showed you how to build an Ajax-enabled application using Phobos and jMaki with the help of the NetBeans IDE.For persistence, the application used a simple JDBC wrapper library provided with Phobos. If the data model were more complex,the application could have used a full-featured Java persistence library such as the Java Persistence API (JPA) orHibernate. Because of the excellent interoperability between JavaScript and the Java programming language, developers canuse the language most appropriate for each task without compromising productivity.Further ReadingAn Overview of PhobosProject PhobosAbout the AuthorRoberto Chinnici is a senior staff engineer at Sun Microsystems. He currently serves as the specification lead for theJava Platform, Enterprise Edition (Java EE) 6. Roberto is a long-standing advocate of scripting and dynamic languageson any platform and the creator of Phobos.

by Roberto Chinnici Phobos is a lightweight, scripting-friendly, web application environment that runs on the Java platform. Using Phobos, you can take advantage of the benefits offered byscripting...

Java Persistence

Combining Groovy, Grails, MySQL, and the Java Persistence API

by Carol McDonaldWith the addition of support for scriptinglanguages in the Java platform, there has been a lot of interestin combining into web applications scripting languages such as Groovy, Java technologies such as the Java PersistenceAPI (JPA), and databases such as MySQL. Last year I wrote a Tech Tip titledCombining JavaServer FacesTechnology, Spring, and the Java Persistence API that showed how you can use JavaServer FacesTechnology, Spring, and the JPA to create an application that displays an online catalog of pets.In this tip, I'll show you how to create an online catalog application using the Groovy language, the Grails framework,the MySQL database, and the Java Persistence API.A package that contains the code for the sample application accompanies the tip. The code examplesin the tip are taken from the source code of the sample (which is included in the package). In this tip, you'll useNetBeans IDE 6.5 Milestone 1to build the application and deploy it on the GlassFishapplication server. The NetBeans IDE is a modular, standards-based, integrated development environment (IDE) writtenin the Java programming language. The latest NetBeans IDE offering, NetBeans IDE 6.5 Milestone 1 (or M1 for short),offers many new features including support for Groovy and Grails.GlassFish is a free, open source application server that implements the newest features in the Java EE 5 platform.A Summary of the Languages, Technologies, and Frameworks in the Sample ApplicationIf you're not familiar with Groovy, Grails, MySQL, or the Java Persistence API, here are brief descriptions:Groovy is an agile and dynamic language for theJava Virtual Machine1. It compiles to Java bytecode and combines popular features fromlanguages such as Smalltalk, Python, and Ruby.Grails is an open-source web application framework that leveragesthe Groovy language and complements Java Web development. It aims to bring the "coding by convention" paradigmto Groovy. Grails is a Model-View-Controller based framework that simplifies the development of web applications byreducing the need for configuration files and by generating a lot of the things needed in a database-backed web application.MySQL is the world's most popular open-source database. It offersconsistently fast performance, high reliability and ease of use.The Java Persistence API provides a (plain oldJava object) POJO-based persistence model for Java EE and Java SE applications. It handles the details of how relationaldata is mapped to Java objects, and it standardizes Object/Relational (O/R) mapping.The Sample ApplicationThe sample application displays an online catalog of pets sold in a pet store. Figure 1 shows theCatalog Listing page, which allows a user to page through a list of items in a store.Figure 1. Catalog Listing PageExamining the ApplicationEarlier I mentioned that Grails is a Model-View-Controller based framework that simplifies the development of web applications.The online catalog application uses Grails and so it follows the MVC pattern, that is, the application isolates its data,the "Model", from the user interface, the "View", and from the code that manages the communicationbetween the model and the view, the "Controller". Let's first look at the Model for the application.The ModelThe Model not only represents the data for the application, but it also represent persistent data, that is, datathat persists beyond the life of the application. In other words, the Model represents an application's persistentbusiness domain objects. The application uses JPA to manage that persistence. In JPA, an entity instance -- an instance ofan entity object -- represents a row of data in a database table.If you examine the source code for the application, you'll find the following two classes in the model directory:Item and Address. Item is an entity class -- a typical JPA entity object -- thatmaps to an item table in a database. The table stores information about items in the catalog. Here is partof the source code for the Item class: package model; import java.io.Serializable; ... @Entity @Table(name = "item") public class Item implements Serializable { private static final long serialVersionUID = 1L; @Id private Long id; private String name; private String description; private String imageurl; private String imagethumburl; private BigDecimal price; @ManyToOne(optional = false) @JoinColumn(name = "address_id") private Address address; // getters and setters ... }Address is an entity class that maps to an address table in the database. The table storesaddresses associated with items in the catalog. Here is part of the source code for the Address class: package model; import java.io.Serializable; ... @Entity public class Address implements Serializable { private static final long serialVersionUID = 1L; @Id private Long id; private String street1; private String street2; private String city; private String state; private String zip; private BigDecimal latitude; private BigDecimal longitude; private BigInteger version; @OneToMany(fetch = FetchType.EAGER, cascade = { CascadeType.ALL }, mappedBy = "address") private Collection<Item>items = new ArrayList(); // getters and setters ... }The Item class has a many-to-one relationship with the Address class, meaning thatthere can be multiple items in the catalog associated with the same address, but multiple addresses cannot be associatedwith the same item. This relationship is specified by the @ManyToOne annotation in the Item classand the @OneToMany(mappedBy = "address") annotation in the Address entity class.Using JPA Entities With Grails and MySQLTo use the JPA entities for the application with Grails and MySQL, you first need to create a Grails applicationand then modify some files in the Grails application directory structure.We'll use NetBeans IDE 6.5 M1 to create a Grails application. If you haven't already done so,download NetBeans IDE 6.5 Milestone 1and download Grails.Start NetBeans IDE 6.5 Milestone 1. Select New Project from the File menu. Then select Groovy in the Categorieswindow and Grails in the Projects window as shown in Figure2.Figure 2. Creating a Grails Project in NetBeans IDE 6.5 M1Click the Next button and name the project, for instance, MyGrailsApp. Accept the default project locationor browse to select a different location. Leave the Set as Main Project checkbox checked and click the Finish button.In response, NetBeans creates the Grails project and a standard directory structure for a Grails application.Figure 3 shows the Grails directory structure for the online catalog application.Figure 3. Grails Directory Structure for the Online Catalog ApplicationAfter you have your directory structure in place, do the following:Put your entity files in the app_name\\src\\java directory, where app_name is the name of your Grailsapplication. The Item and Address entity files for the online catalog application are in thecatalog\\src\\java\\model directory.Get the MySQL jdbc driver,mysql-connector-java-5.1.6-bin.jar and put it in the app_name\\lib directory.You can find the mysql-connector-java-5.1.6-bin.jar file for the online catalog application in thecatalog\\lib directory.Modify the DataSource.groovy file in the app_name\\grails-app\\conf directory to use MySQLas the database and specify the GrailsAnnotationConfiguration configuration class to use the annotationsin the JPA entities. The code marked in bold in the following code example shows the additions and modification that I madeto the DataSource.groovy file for the online catalog application.import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration dataSource {configClass = GrailsAnnotationConfiguration.class pooled = false driverClassName = "com.mysql.jdbc.Driver" username = "root" password = "" dialect = "org.hibernate.dialect.MySQL5InnoDBDialect" } hibernate { cache.use_second_level_cache=true cache.use_query_cache=true cache.provider_class='com.opensymphony.oscache.hibernate.OSCacheProvider' } // environment specific settings environments {development {dataSource {dbCreate = "create-drop" // one of 'create', 'create-drop','update'url = "jdbc:mysql://localhost/petcatalog"}}test {dataSource {dbCreate = "update"url = "jdbc:mysql://localhost/petcatalog"}}production {dataSource {dbCreate = "update"url = "jdbc:mysql://localhost/petcatalog"}} } For Grails to recognize the JPA entities as domain classes, you need to addthe hibernate.cfg.xml file to the app_name\\grails-app\\conf\\hibernate directory.Here is the hibernate.cfg.xml file for the online catalog application. You can find it in thecatalog\\grails-app\\conf\\hibernate directory. <?xml version=""1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <mapping package="model" /> <mapping class="model.Item" /> <mapping class="model.Address" /> </session-factory> </hibernate-configuration> The ControllerNetBeans IDE 6.5 M1 enables you to create domain classes and controllers, but I haven't found the menu option to generatecontrollers, so for now, let's use the command line as follows to generate a controller:Open a command prompt and navigate to the project directory for your Grails application. If you've forgotten where thisis, you can find it in the project's Properties dialog.Generate a controller for a domain class by entering the following command: grails generate-controller domain-classwhere domain-class is the domain class name. For example, to generate a controller for the Itemdomain class in the online catalog application, I entered the following command: grails generate-controller model.ItemIn response, the command generates a file named domain-classController.groovy in thegrails-app/controllers directory. For the Item class, the generated controller is ingrails-app/controllers/ItemController.groovy.Figure 4 shows the controller, ItemController.groovy, in the NetBeans IDE 6.1 M1 Groovyeditor window.Figure 4. A Controller Listed in the Grails Directory Structure for the Online Catalog ApplicationControllers handle incoming HTTP requests, interact with the model to get data and process requests, invoke the correctview, and direct domain data to the view for display. In Grails, HTTP requests are handled by controller classes that containone or more action methods that are executed on request. The action methods either rendera Groovy Server Page(GSP) or redirect to another action. Grails routes requests to the controller action that corresponds to the URL mapping forthe request. In Grails, the default mapping from URL to action method follows the conventionhttp://host/app_name/controller/action/id where host is the host name,app_name is the name of the Grailsapplication, controller is the controller class, action is the action method, and idis the id of a passed parameter. For example, the URLhttp://host/catalog/item/list calls the list action method in the item controller class. Here is code snippet inItemController.groovy that shows the list method: import model.Item class ItemController { def index = { redirect(action:list,params:params) } // the delete, save and update actions only accept POST requests def allowedMethods = [delete:'POST', save:'POST', update:'POST'] def list = { if(!params.max) params.max = 10 [ itemList: Item.list( params ) ] }Grails scaffolding provides a series of standardized controlleraction methods for listing, showing, creating, updating, and deleting objects of a class. These standardized actions comewith both controller logic and default view Groovy Server Pages. The list action in ItemControllerrenders a view with a paginated list of item objects.If a URL has a controller but no action, as is the case for http://localhost:8080/catalog/item/, Grails defaults to theindex action. In the ItemController code, the index action method redirects to thelist action method. The list action method calls the Item.list() method, whichreturns an ArrayList of item objects retrieved from the item table in thedatabase. If there are more objects in the table than the number specified in params.max (in this case, 10),Grails automatically creates next and previous pagination links. The Grails framework automatically makes theitemList variable available to the view.After executing code, actions usually render a GSP in the views directory corresponding to the name of thecontroller and action. For example the list action renders the GSP, list.gsp, in thegrails-app\\views\\item directory.The ViewThe view layer uses data from domain objects provided by the controller to generate a web page. In Grails, the view isrendered using Groovy Server Pages. To generate the view, open a command prompt, navigate to the project directory foryour Grails application, and enter the following command: grails generate-views domain-classwhere domain-class is the domain class. For example, to generate a view for the Itemdomain class in the online catalog application, I entered the following command: grails generate-views model.ItemIn response, the command generates GSPs for the domain class. For example, it generates create.gsp,edit.gsp, list.gsp, The view uses instance variables set by the controller to access the data it needs to render the GSP. Groovy Server Pagesuse a GroovyTagLib that is similar to the JSP tag library. Notice the tags that start with <g:in the list.gsp code. These are GroovyTags. Here is a brief summary of the GroovyTags and some otherelements in the list.gsp code:<g:sortableColumn>Renders a sortable column to support sorting in tables.<g:each in="${itemList}" status="i" var="item">Loops through each object in the itemList variable, which is an ordered ArrayListof Item model objects, and assigns each Item model object to the item variable.<g:link action="show" id="${item.id}">${item.name?.encodeAsHTML()}</g:link>Creates an HTML anchor tag href based on the specified action, id, and controller parameters specified.In this example, it generates a link to the item/show/id action. This action will display thecorresponding item details. Here, the line generates the following HTML for the variable item: <a href="/catalog/item/show/2">Friendly Cat</a><img src="${createLinkTo(dir:'images',file:item.imagethumburl)}"/>Generates an HTML link for the item's

by Carol McDonald With the addition of support for scripting languages in the Java platform, there has been a lot of interestin combining into web applications scripting languages such as Groovy, Java...

performance

Using P6Spy and the GlassFish Connection Pool to Trace Database Operations

by Jagadish RamuDetecting performance bottlenecks is an important task in optimizing database operations in an application. One wayto do that is to trace the database operations of the application. This information can help you fine tune the databasecalls that the application makes and in this way improve the application's performance. This Tech Tip will demonstratehow to use a tool called P6Spy to trace the database requests issued by an application running with the GlassFish v2application server. Specifically, you'll learn how to trace SQL statements from an application that uses GlassFish'sJDBC Connection Pool.P6Spy is an open source Java tool that intercepts and logs alldatabase statements in an application that uses Java Database Connectivity (JDBC). The tool can be used with anycompliant JDBC driver. In fact, P6Spy itself is a JDBC-compliant driver that acts as wrapper for any JDBC-compliant driver.It can be used with a variety of application servers including GlassFish and with variousdatabases such as Oracle, DB2, SQL Server, MySQL, and Java DB. The tool can be seamlessly integrated withGlassFish, that is, you don't need to add or change any source code. Also, the tool is highly configurable and youcan switch it on only when you need to use it.Using P6Spy With GlassFishIn this tip, you'll use P6Spy to trace JDBC-based database calls made by an application running with GlassFish v2. Forthe application, let's use CustomerCMP, which is available as a sample project in theNetBeans IDE. The application usesa Java DB database. It also uses aJDBCconnection pool.Download and ConfigureIf you haven't already done so, download and install the following:GlassFish v2P6SpyNetBeans IDE 6.1Start GlassFish.Next, you need to configure things so that P6Spy can be used with GlassFish. To do that:Create a directory named p6spy below the GlassFish v2 installation directory. For example if youinstalled GlassFish v2 in C:\\Sun\\AppServer, create a directory C:\\Sun\\AppServer\\p6spy.Copy the spy.properties file from the P6Spy installation directory to the p6spy directorythat you just created. The spy.properties file is used to control various functions of the P6Spy driver.For example, the logfile property in the spy.properties file specifies the name of thefile in which P6Spy will log SQL statements. By default the file is specified as spy.log, but youcan change it to another file name.Comment out all realdriver property assignments in the spy.properties file.The realdriver property specifies the name of the database driver that P6Spy will work with.Do this because GlassFish uses datasource which are defined in realDataSource property of the P6Spyconnection pool.Add the location of the p6spy.jar file and the path to spy.properties to GlassFish'sclasspath --for example, in the <java-config classpath-prefix> element in the GlassFish domain.xml file.You can use the GlassFish Admin Console to do that, as follows:Login to the Admin Console.Select Admin Server in the left navigation bar. This will display the Application Server page.Select the JVM Settings tab then the Path Settings tab.Enter the location of the p6spy.jar file and the path to spy.properties in the ClasspathPrefix box.See for example, Figure 1.Figure 1. Adding the Location of the p6spy.jar File and the Path to spy.properties to GlassFish's ClasspathClick the Save button.Restart GlassFish.Create a JDBC Connection Pool and ResourceIn order to use P6Spy with GlassFish, you need to create a JDBC resource and P6Spy-based connection pool.GlassFish v2 simplifies this task by providing templates to create a connection pool and resource forvarious databases and JDBC drivers. You can find the templates in the lib/install/templates/resources/jdbcdirectory below the GlassFish v2 installation directory. For example, javadb_type4_datasource.xml isthe template for a Java DB Type 4 driver. All you need to do to use a template is specify appropriatevalues for properties such as user, password, databaseName, and serverName.To simplify things even further, you can download and use the p6spy_datasource.xml filethat accompanies this tip. The p6spy_datasource.xml file is based on the javadb_type4_datasource.xmltemplate and specifies a P6Spy connection pool and a Java DB (Derby) datasource.To create the connection pool and resource using the p6spy_datasource.xml file, enter the followingcommand on a command line:GF_INSTALL/bin/asadmin add-resources p6spy_datasource.xml_pathwhere GF_INSTALL is the directory where you installed GlassFish and p6spy_datasource.xml_path is thecomplete path to the p6spy_datasource.xml file.Alternately, you can use the Admin Console to create the JDBC resource and connection pool as follows:Select Resources in the left navigation bar. This displays the Resources page.Select JDBC, then JDBC Resources. This displays the JDBC Resources page.Click the New button on the JDBC Resources page. This displays the New JDBC Resource page.Enter the resource-name as jdbc/p6spy-resource in the JNDI name field.Select the pool-name p6spy_pool in the Pool Name drop-down list.Click the OK button.Now the p6spy-resource is ready to to intercept the database calls of resource jdbc/__default.Note that you can use other types of datasources. To do that, keep the p6spy-resource's type asjavax.sql.DataSource and the datasource-class as com.p6spy.engine.spy.P6DataSource.The realDataSourceName can be of type javax.sql.DataSource, javax.sql.ConnectionPoolDataSource,or Click the Next button.Specify a location for the project and click the Finish button.One other thing you need to do before you can use the application with the P6Spy-based resource is to point to theresource in the persistence.xml file. To do that, expand Configuration files below CustomerCMP-ejbin the NetBeans Projects list. You should see the persistence.xml file in the expanded listof Configuration files. Open persistence.xml and change the setting for <jta-data-source>to jdbc/p6spy-resource, as shown in Figure 3.Figure 3. Setting the jta-data-sourceLast, build the project by right-clicking on the CustomerCMP project in the project list and selecting Build.Then deploy the project by right-clicking the CustomerCMP project in the project list and selecting undeploy and deploy.Run the ApplicationTo run the CustomerCMP application, point your browser to http://localhost:8080/customer/. You should see a pagethat contains the contents shown in Figure 4.Figure 4. CustomerCMP PageClick the Create New Customer link and enter the data for a new customer, Jagadish Prasath, as shown inFigure 5. Then click the Submit buttonFigure 5. Creating a New CustomerThis request uses the P6Spy connection pool to persist the customer details in the Java DB database.P6Spy logs the SQL statements used for the database operations. You can find the spy log in thedomains\\domain1\\config directory below the GlassFish installation directory. If you examine thelog file, you'll see the following entry , which corresponds to the actions required to create the new userJagadish Prasath: 1215548015250|47|7|statement|INSERT INTO CUSTOMER (customerid, FIRSTNAME, LASTNAME) VALUES (?, ?, ?)| INSERT INTO CUSTOMER (customerid, FIRSTNAME, LASTNAME) VALUES ('1', 'Jagadish', 'Prasath') Let's look at some more P6Spy logging by creating another user and then searching for users. First createa new user in the same was as you did previously. Name the new user Arun Prasath. Then return to the initial pageof the customerCMP application and click the Search for Customer link. You should see the search page.Do a search on the last name Prasath as shown in Figure 6.Figure 6. Searching for CustomersYou should now see the following entries added to the spy log file: 1215549723390|15|11|statement|INSERT INTO CUSTOMER (customerid, FIRSTNAME, LASTNAME) VALUES (?, ?, ?)|INSERT INTO CUSTOMER (customerid, FIRSTNAME, LASTNAME) VALUES ('2', 'Arun', 'Prasath') 1215549975390|125|12|statement|SELECT customerid, FIRSTNAME, LASTNAME FROM CUSTOMER WHERE (LASTNAME = CAST (? AS VARCHAR(32672) ))|SELECT customerid, FIRSTNAME, LASTNAME FROM CUSTOMER WHERE (LASTNAME = CAST ('Prasath' AS VARCHAR(32672) )) 1215549975390|-1||resultset|SELECT customerid, FIRSTNAME, LASTNAME FROM CUSTOMER WHERE (LASTNAME = CAST ('Prasath' AS VARCHAR(32672) ))|CUSTOMERID = 1, FIRSTNAME = Jagadish, LASTNAME = Prasath 1215549975390|-1||resultset|SELECT customerid, FIRSTNAME, LASTNAME FROM CUSTOMER WHERE (LASTNAME = CAST ('Prasath' AS VARCHAR(32672) ))|CUSTOMERID = 2, FIRSTNAME = Arun, LASTNAME = Prasath Note that P6Spy gives you flexibility in what you trace. For example, you can trace a second datasource bycreating another p6spy-based resource and then referring to the second datasource that you want to trace.Also, you can customize which tables to trace by specifying appropriate values for the filter,include, and exclude properties in the spy.properties file.You can also request verbose logging through the excludecategories property in thespy.properties file.In addition, the P6Spy properties are dynamically reconfigurable. Simply set the reloadpropertiesproperty in the spy.properties file to true and the reloadpropertiesinterval propertyto the number of seconds you want as the time interval between property reloads.Further ReadingTemplatesto create JDBC Connection Pool & ResourceGlassFishProject - Connection PoolingAbout the AuthorJagadish Ramu is is an engineer in the GlassFish Application Server team. He works in the areas of JDBC,connection pooling, and connectors. He has been involved with the connectors team at Sun since mid-2005. Jagadishholds an M.Tech degree from BITS Pilani, India.

by Jagadish Ramu Detecting performance bottlenecks is an important task in optimizing database operations in an application. One wayto do that is to trace the database operations of the...

Java Persistence

Preventing Non-Repeatable Reads in JPA Using EclipseLink

by Rahul BiswasIn this tip, you'll learn how to prevent non-repeatable reads through theJava Persistence API (JPA)and JPA extensions provided by EclipseLink.Non-Repeatable ReadsA non-repeatable read is a concept pertinent to databasetransactions. In a non-repeatable read, multiple reads of a data itemfrom a datasource do not return the same value for the data item. In JPA terms, a non-repeatable readmeans that within a transaction, if an application reads the sameentity multiple times from a datasource, the application will find that the entitystate has changed between reads.Non-repeatable reads apply to the following scenario: A transaction, T1, reads a row in a database.Another transaction, T2, then modifies or deletes that row before T1 has committed. Both transactions eventuallycommit successfully.Generally one of the following approaches is used to prevent that scenario:Optimistic. This approach assumes that the same data is not being read and writtenconcurrently. The write transaction is allowed to commit. However, the read transactionis required to detect the changed value when it attempts to commit.Pessimistic. This approach assumes that the same data may be read and writtenconcurrently. The read transaction locks the row representing the data in the underlying datasource.The write transaction can commit only after the read commits. During theread transaction the value of the data being locked does not change.Consider, for example, the following simple table in a database:IdDescriptionPrice720Expensive Item582.99721Nice to have Item66.99Suppose an application, A, starts a transaction, T1, and queries thetable to retrieve the price for "Expensive Item". Suppose A then startsanother transaction, T2, to update the price for "Expensive Item".Figure 1 illustrates the optimistic approach. Transaction T1 assumes that datais not being concurrently modified, although, in fact, transaction T2 does concurrently modify thedata and proceeds with the commit. When T1 attempts to commit, it detects the change and notifies the application,which may rollback the T1 transaction.Figure 1. Preventing Non-Repeatable Reads Using an Optimistic ApproachFigure 2 illustrates the pessimistic approach.Here, the T2 update is blocked until the T1 transaction commits.Figure 2. Preventing Non-Repeatable Reads Using a Pessimistic ApproachPreventing Non-Repeatable Reads in JPAYou can use JPA to prevent non-repeatable reads on versioned entities.A versioned entity is marked with the @Version annotation, as illustratedin the following code snippet: @Entity public class StockQuote implements Serializable { @Version public Long getVersion() { return version; }and its corresponding database schema has a version column, such as that created by the following SQL statement: CREATE TABLE STOCKQUOTE (ID NUMBER NOT NULL, VERSION NUMBER, PRICE FLOAT, DESCRIPTION VARCHAR(255), PRIMARY KEY (ID));Versioning enables JPA to manage optimistic locking. Optimistic locking assumes that there will be infrequentconflicts between concurrent transactions. In optimistic locking, the objective is to give concurrent transactionsa lot of freedom to process simultaneously, but to detect and prevent collisions.The way you prevent non-repeatable reads in JPA on a versioned entity is through the lock() method ofthe EntityManager class. Here is the method signature: public void lock(Object entity, LockModeType lockMode);The first method parameter is the entity instance that needs to be locked in the transaction.The second method parameter is the lock mode, which can have one of the following values:READWRITEBoth lock modes prevent non-repeatable reads. However, the WRITE lock mode also forcesthe version column to be updated.As illustrated in Figure 1, transaction T1 acquires a read lock, buttransaction T2 is allowed to commit its changes. When transaction T1 tries to commit, the EclipseLink JPA implementationdetects that the data changed since the last read. It does this by checking the version column.It then throws an OptimisticLockException toapplication A. At this point, the application can retry the operation after refreshingthe value of the entity. Alternatively, the application can abort the operation and rollback the transaction.Taking Advantage of EclipseLink ExtensionsEclipseLinkis an open source project whose goal is to provide a comprehensive persistence frameworkthat will run in any Java environment and that will support the reading and writing of objects to and from virtuallyany type of data source. One of the project's deliverables is an advanced features extension to JPA.You can take advantage of this extension to ensure repeatable reads through pessimitic locking,something that is not currently supported in the JPA 1.0 specification.However, this solution is not portable because it uses EclipseLink-specific extensions.The way to ensure repeatable reads with EclipseLink is through its support for pessimistic locking onJPA Query Language (JPA QL) queries. Pessimistic locking assumes that there will be frequent conflictsbetween concurrent transactions. To prevent collisions during pessimistic locking, an entityis locked in the database for the entire time that it is in application memory.EclipseLink enables pessimistic locks on JPA QL queries through query hints, which are JPA extension points forvendor-specific query features.There are two ways to enable a pessimistic lock through a JPA QL query hint. One way is to usea @NamedQuery annotation, as in the followingexample: @NamedQuery( name="GetStock" query="select sq from StockQuote as sq where sq.id = :id" hints={@QueryHint(name=EclipseLinkQueryHints.PESSIMISTIC_LOCK, value=PessimisticLock.Lock)})The other way is to use the Query API, as in the followingexample: Query q = em.createNamedQuery("GetStock"); q.setHint(EclipseLinkQueryHints.PESSIMISTIC_LOCK, PessimisticLock.Lock); q.setParameter("id", 1);Acquiring a pessimistic lock through either of these techniques typically locks the pertinent row in theunderlying database. As illustrated in Figure 2, if transaction T1runs either of the two queries above, it locks the underlying datasource row and blocks T2 from committing its updates.After T1 commits, T2 can commit its changes.Sample ApplicationLet's look at a sample application that prevents non-repeatable reads through EclipseLink JPA extensions. In fact,the application also allows non-repeatable reads so that you can compare the results ofboth types of reads. You can find the application in the sample package thataccompanies this tip.The sample application is a simplified version of a stock market application that would typically handle a large numberof concurrent transactions, and in doing so, service simultaneous reads and writes to entities. In general, here's whatthe application does:Creates a table in a database. Here are the SQL statements that create the table (you can find this code infile createDDL.ddbc): CREATE TABLE STOCKQUOTE (ID NUMBER NOT NULL, VERSION INTEGER, PRICE FLOAT, DESCRIPTION VARCHAR(255), PRIMARY KEY (ID)) ; INSERT INTO STOCKQUOTE (ID, PRICE, VERSION, DESCRIPTION) VALUES(1, 23, 1, 'JAVA') ; CREATE TABLE SEQUENCE ( SEQ_NAME VARCHAR(50) NOT NULL, SEQ_COUNT INTEGER, PRIMARY KEY (SEQ_NAME)) ; INSERT INTO SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('SEQ_GEN', 1); Notice the VERSION column in the table.Establishes a persistence unit that specifies the metadata files, classes, and JAR files for the persistedentities. The persistence unit is always specified in the persistence.xml file in theMETA-INF directory of an application. Here is the content of the persistence.xml file for the sampleapplication: <?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="tech-tip-4-samplePU" transaction-type="RESOURCE_LOCAL"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <class>com.sun.techtip.sample.jpa.entity.StockQuote</class> <properties> <property name="eclipselink.jdbc.user" value="[your-db-userid]"/> <property name="eclipselink.jdbc.password" value="[your-db-password]"/> <property name="eclipselink.jdbc.url" value="jdbc:oracle:thin:@[your-host]:[your-port]:[your-db-sid]"/> <property name="eclipselink.jdbc.driver" value="oracle.jdbc.driver.OracleDriver"/> </properties> </persistence-unit> </persistence> Notice that the persistence unit specifies EclipseLink as the JPA persistence provider.Creates two worker threads, a ReaderThread and a WriterThread thread. The application can runin one of three modes, repeatable read with optimistic locking, repeatable read with pessimistic locking ornon-repeatable read. You indicate which mode by specifying rr and o, for repeatable read withoptimistic locking, rr and p, for repeatable read with pessimistic locking, or nrr,for non-repeatable read, when you start the application. The application uses theentries (or entry) as arguments when it startsthe ReaderThread. The code for this part of the application is in file Main.java. Here isa snippet of that code: public class Main { private static final String NRR = "nrr"; private static final String RR="rr"; private static final String P="p"; private static final String O="o"; public Main() { } public static void main(String[] args){ if(args==null || args.length < 1){ displayUsage(); System.exit(-1); } boolean bLock = RR.equals(args[0].trim()); if(args.length < 2 && bLock){ displayUsage(); System.exit(-1); } boolean isPessimistic = bLock? P.equals(args[1].trim()): false; System.out.println("Running sample for " + (bLock? "Repeatable read ":"Non-repeatable read ") + (bLock? (isPessimistic? "in pessimistic mode":"in optimisitic mode"): "")); //create two worker threads with lock options ReaderThread rt = new ReaderThread(bLock, isPessimistic); WriterThread wt = new WriterThread(); //start the run new Thread(rt).start(); new Thread(wt).start(); In repeatable read with optimistic locking mode, the ReaderThread begins a transactionon an entity. The WriterThread then updates the stock price during the ReaderThreadtransaction and successfully commits. The ReaderThread attempts to commit its transaction.However, the underlying JPA implementation detects that the corresponding database row has been updated byanother thread after it was last read, so it throws an OptimisticLockException. The applicationcatches this exception and flags the transaction as failed.In repeatable read with pessimistic locking mode, the ReaderThread begins a transactionon an entity. The WriterThread then attempts to update the stock price during theReaderThread transaction. However, the update attempt is blocked because the ReaderThreadhas a lock on both the entity object and the underlying database row representing the object.In non-repeatable read mode, the ReaderThread begins a transaction on an entity. Then theWriterThread updates the stock price on the same entity and commits its transaction before theReaderThread commits its transaction. The ReaderThread detects theconflict by detecting the difference in the price and prints out a warning message.Here is part of the code in the ReaderThread: public class ReaderThread implements Runnable{ private EntityManagerFactory emf; private boolean bLock; private boolean isPessimistic; public ReaderThread(boolean bLock, boolean isPessimistic) { this.bLock = bLock; this.isPessimistic=isPessimistic; } public void run() { emf = DataSourceManager.getInstance().getEMF(); read(); } private void read(){ EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); StockQuote sq; if(bLock){ if (isPessimistic) { Query q = em.createNamedQuery("GetStock"); q.setParameter("id", 1); q.setHint(EclipseLinkQueryHints.PESSIMISTIC_LOCK, PessimisticLock.Lock); sq = (StockQuote) q.getSingleResult(); }else{ sq = em.find(StockQuote.class, new Long(1)); em.lock(sq, LockModeType.READ); } }else{ sq = em.find(StockQuote.class, new Long(1)); } double price = sq.getPrice(); System.out.println("ReaderThread: original price - "+ price); //now wait for write thread to do it's update while(!WriterThread.readyToWrite.get()){ try{ System.out.println("ReaderThread: waiting for writer thread to" + " be ready..."); Thread.currentThread().sleep(100); }catch(InterruptedException iex){ iex.printStackTrace(); } } WriterThread.attemptWrite.set(true); System.out.println("ReaderThread: giving WriterThread OK to commit..."); //write thread has attempted it's write System.out.println("ReaderThread: hit enter to continue...."); try{ System.in.read(); }catch(Exception ex){ ex.printStackTrace(); } if(!bLock || (bLock && isPessimistic)){ em.refresh(sq); } double _price = sq.getPrice(); try{ em.getTransaction().commit(); System.out.println("ReaderThread: latest price - " + _price); if (_price != price && !bLock) { System.out.println("Price was modified by the writer thread, " + "repeatable read failed as expected."); } else if (!bLock) { System.out.println("Price did not change inspite of " + "concurrent update!"); } else if (_price == price && bLock) { System.out.println("Repeatable read succeeded!"); } else { System.out.println("The app failed in testing " + "repeatable reads, please check your DB supports " + "row locking."); } }catch(Exception ex){ System.out.println("ReaderThread: Transaction failed with following" + " message -- "+ex.getMessage()); } } } Notice that the ReaderThread enables repeatable reads through pessimistic locking in a JPA QL query hint: if(bLock){ if (isPessimistic) { Query q = em.createNamedQuery("GetStock"); q.setParameter("id", 1); q.setHint(EclipseLinkQueryHints.PESSIMISTIC_LOCK, PessimisticLock.Lock); sq = (StockQuote) q.getSingleResult(); }else{ sq = em.find(StockQuote.class, new Long(1)); em.lock(sq, LockModeType.READ); } }Running the Sample ApplicationA sample package accompanies this tip. To install and run the application in thesample package:Download the sample package and extract its contents. You should now see a newly extracted directory<sample_install_dir>/jpa-repeatable-read.tech-tip, where <sample_install_dir>is the directory where you installed the sample package. For example, if you extracted the contents to C:\\on a Windows machine, then your newly created directory should be at C:\\jpa-repeatable-read.tech-tip. Change to the jpa-repeatable-read.tech-tip directory and set the values for following properties in thebuild.xml file as appropriate for your operating environment: jdbc.url, db.userid,db.password, and javaee.home. The application uses these property settingsto update the persistence.xml file and in the initial setup on the database.Set up the database and establish the persistence unit by entering the following command in thejpa-repeatable-read.tech-tip directory: ant setupRun the application in repeatable read with optimistic lock mode. Ensure that the argumentsof the run target in the build.xml file have the values rr ando as follows: <target name="run" depends="clean, pusetup, compile"> <java classname="com.sun.techtip.sample.Main" fork="true"> <arg value="rr"/> <arg value="o"/>Then enter the following command in the jpa-repeatable-read.tech-tip directory: ant run allYou should see output similar to the following: Running sample for Repeatable read in optimisitic mode [EL Info]: 2008.07.01 12:46:16.500--ServerSession(17423963)--EclipseLink, version: Eclipse Persistence Services - 1.0 (Build SNAPSHOT - 20080604) [EL Info]: 2008.07.01 12:46:19.343--ServerSession(17423963)--file:/D:/work/articles/jpa-repeatable-read.tech-tip/build/classes/-tech-tip-4-samplePU login successful WriterThread: original price - 40.745903 WriterThread: ready, need OK from ReaderThread... ReaderThread: original price - 40.745903 ReaderThread: giving WriterThread OK to commit... ReaderThread: hit enter to continue.... WriterThread: starting to commit now... WriterThread: committed tx... WriterThread: updated price - 44.8204933 [EL Warning]: 2008.07.01 12:47:37.906--UnitOfWork(24118161)--Exception [EclipseLink-5006] (Eclipse Persistence Services - 1.0 (Build SNAPSHOT - 20080604)): org.eclipse.persistence.exceptions.OptimisticLockException Exception Description: The object [com.sun.techtip.sample.jpa.entity.StockQuote@878c4c] cannot be updated because it has changed or been deleted since it was last read. Class> com.sun.techtip.sample.jpa.entity.StockQuote Primary Key> [1] [EL Warning]: 2008.07.01 12:47:37.921--UnitOfWork(24118161)--javax.persistence.OptimisticLockException: Exception [EclipseLink-5006] (Eclipse Persistence Services - 1.0 (Build SNAPSHOT - 20080604)): org.eclipse.persistence.exceptions.OptimisticLockException Exception Description: The object [com.sun.techtip.sample.jpa.entity.StockQuote@878c4c] cannot be updated because it has changed or been deleted since it was last read. Class> com.sun.techtip.sample.jpa.entity.StockQuote Primary Key> [1] ReaderThread: Transaction failed with following message -- javax.persistence.OptimisticLockException: Exception [EclipseLink-5006] (Eclipse Persistence Services - 1.0 (Build SNAPSHOT - 20080604)): org.eclipse.persistence.exceptions.OptimisticLockException Exception Description: The object [com.sun.techtip.sample.jpa.entity.StockQuote@878c4c] cannot be updated because it has changed or been deleted since it was last read. Class> com.sun.techtip.sample.jpa.entity.StockQuote Primary Key> [1] Notice that the non-repeatable read was prevented. The underlying JPA implementation detects a change to the price by theWriterThread and throws an OptimisticLockException.Then the ReaderThread catches the exception and flags the transaction as failed.Run the application in repeatable read with pessimistic lock mode. Ensure that thearguments of the run target in the build.xml file have the values rr and pas follows: <target name="run" depends="clean, pusetup, compile"> <java classname="com.sun.techtip.sample.Main" fork="true"> <arg value="rr"/> <arg value="p"/>Then enter the following command in the jpa-repeatable-read.tech-tip directory: ant run allYou should see output similar to the following: Running sample for Repeatable read in pessimistic mode [EL Info]: 2008.07.01 12:53:50.078--ServerSession(17423963)--EclipseLink, version: Eclipse Persistence Services - 1.0 (Build SNAPSHOT - 20080604) [EL Info]: 2008.07.01 12:53:51.875--ServerSession(17423963)--file:/D:/work/articles/jpa-repeatable-read.tech-tip/build/classes/-tech-tip-4-samplePU login successful WriterThread: original price - 44.8204933 WriterThread: ready, need OK from ReaderThread... ReaderThread: original price - 44.8204933 ReaderThread: giving WriterThread OK to commit... ReaderThread: hit enter to continue.... WriterThread: starting to commit now... ReaderThread: latest price - 44.8204933 Repeatable read succeeded! WriterThread: committed tx... WriterThread: updated price - 49.302542630000005 Notice that the repeatable read succeeded. The WriterThread is blocked from committing the transaction untilthe ReaderThread transaction has committed.Run the application in non-repeatable read mode. Change the run target in the build.xml file to the valuenrr. Then enter the following command in the jpa-repeatable-read.tech-tip directory: ant run allYou should see output similar to the following: Running sample for Non-repeatable read [EL Info]: 2008.07.01 12:55:33.906--ServerSession(17423963)--EclipseLink, version: Eclipse Persistence Services - 1.0 (Build SNAPSHOT - 20080604) [EL Info]: 2008.07.01 12:55:35.734--ServerSession(17423963)--file:/D:/work/articles/jpa-repeatable-read.tech-tip/build/classes/-tech-tip-4-samplePU login successful ReaderThread: original price - 49.30254263 ReaderThread: waiting for writer thread to be ready... WriterThread: original price - 49.30254263 WriterThread: ready, need OK from ReaderThread... ReaderThread: giving WriterThread OK to commit... ReaderThread: hit enter to continue.... WriterThread: starting to commit now... WriterThread: committed tx... WriterThread: updated price - 54.232796893 ReaderThread: latest price - 54.232796893 Price was modified by the writer thread, repeatable read failed as expected. Notice that the repeatable read failed. The ReaderThread retrieves a value of 49.30 the first time it requeststhe price. The WriterThread is allowed to update the value to 54.23 concurrent with the ReaderThreadtransaction. The second ReaderThread read retrieves the updated price because it is made after theWriterThread commits its transaction.Note: Although the application should run with various types of databases, it has been tested only with anOracle database..Further ReadingJava Persistence APIEclipseLinkAbout the AuthorRahul Biswas is a member of the Java Performance Engineering group at Sun.

by Rahul Biswas In this tip, you'll learn how to prevent non-repeatable reads through theJava Persistence API (JPA) and JPA extensions provided by EclipseLink. Non-Repeatable Reads A non-repeatable read...

jMaki

Using jMaki With PHP on OpenSolaris

by Ludovic ChampenoisOpenSolaris is an operating system (OS), an open source project,and a community. The project's goals are innovation, collaboration, and the extension of OpenSolaris technologiessuch as Solaris OS, Sun's fully supported and tested enterprise operating system, as well as participation in thedevelopment of OpenSolaris releases and distributions. Recently, the OpenSolaris open source project released theOpenSolaris 2008.05 live CD operating system. TheCD includes a core operating system, kernel, system libraries, desktop environment, and a public repository-based packagemanagement system called Image Packaging System (IPS). Using IPS, you can extend the operating system with code packages suchas Web Stack packages that add the latest versions of the Apache Web Server, MySQL database, PHP engine, code samples,desktop tools, and user interface features.One of the code samples bundled in the "webstackui" Web Stack package isa simple web application that uses PHP, mySQL, and jMaki. This tip describes that application.The application highlights the fact that developing PHP applications is relatively easy using OpenSolaris technologies.Although the sample runs on the OpenSolaris OS, it also runs on the Linux, Mac OS, or Windows operating system with theApache, MySQL, PHP (AMP) stack of software.The tip assumes that you're familiar with the basics of PHP andmySQL. ThejMaki framework is a lightweight framework for creating Web 2.0applications using standards-based technologies such as CSS, HTML, and JavaScript. The framework can be used in serverenvironments such as a JavaServer Pages (JSP) environment, a JavaServer Faces (JSF) environment, jRuby, or PHP. For anintroduction to jMaki, see the January 27, 2007 Tech TipIntroduction to jMaki.The Sample ApplicationAmong its other features, the jMaki framework makes available widgets from popular JavaScript toolkits such as Dojo, Yahoo,script.aculo.us, and Google in a way that's familiar to Java technology, PHP, or Phobos developers. These widgetscommunicate within the jMaki framework through a mechanism called jMaki Glue which is built on top of a publish/subscribe eventmechanism. The April 15, 2008 Tech Tip Working with jMaki Events covered jMaki Glue and showed some examples of it in action. Let's take thisone step further by also showing how jMaki widgets can communicate with back-end logic. Specifically, let's create a simplePHP web application that does the following:Creates a MySQL database that contains one table -- a products table.Provides an HTML form in which users can enter the necessary values for a product.Uses a jMaki Yahoo table widget to display the list of products in the database.Uses a jMaki button widget which users can click to add a product. This action inserts a new entry in the MySQLproduct table as well as in the displayed Yahoo table to reflect the new content of the database.Figure 1 shows what the application displays to the user. Notice the table of products and theadd a product button.Figure 1. A Web Page That Displays a Product Table and an Add a Product ButtonFigure 2 shows what the application displays after the user enters information for a productand clicks the add a product button.Figure 2. Adding a Product to the Product Table Let's examine the major components of the application:MySQL Database ConfigurationSetup ScriptMain pageProduct List ScriptAdd Product ScriptjMaki Glue FileMySQL Database ConfigurationA script named dbname.php is used by all the PHP files in the application to access the MySQL database. Thescript specifies the database name and the credentials for access to the database and then connects to the database. It isassumed that the MySQL server has been started on the server.Here is the dbname.php script: <?php $username="root"; $password=""; $database="phpwebstacksample"; $dbhost="localhost"; $mysql_connection = mysql_connect($dbhost, $username, $password); if (!$mysql_connection) { die('Could not connect: ' . mysql_error()); }?>Notice that the database name is phpwebstacksample and the username is root. There is no password.The variable $mysql_connection refers to the correct database connection -- it is used in the other PHP files toconnect to the database.Setup ScriptA setup script, setup.php, is used when the application is run the first time and the database does not exist.The script creates a simple database and a table named products within the database. Notice that the scriptincludes the dbname.php script at the beginning to access the MySQL database.Here is the setup.php script (note that some of the code lines have been broken to fit the width constraintsof the page): include("dbname.php"); // Create database if (mysql_query("CREATE DATABASE phpwebstacksample",$mysql_connection)) { echo "Database created"; } else { echo "Error creating database: " . mysql_error(); } // Create table in my_db database mysql_select_db($database, $mysql_connection); $query="CREATE TABLE products ( id int(6) NOT NULL auto_increment, name varchar(15) NOT NULL, category varchar(20) NOT NULL, price varchar(20) NOT NULL, PRIMARY KEY (id), UNIQUE id (id), KEY id_2 (id))"; mysql_query($query,$mysql_connection); mysql_close($mysql_connection); echo "<br><br><br>Go back to the main index page to <a href=\\"index.php\\">run the application ...</a>"; ?>Main PageThe main page of the application, index.php, is responsible for connecting to the database,displaying an HTML form to display the contents of the database in an Ajax-enabled Yahoo table widget,and presenting a button to add a new product to the database. The button is an Ajax-enabled jMaki button. The applicationuses jMaki Glue to enable communication between the button and the display table. When a user clicks on theadd a product button, a call is made to a server-side PHP function that inserts the new entry intothe MySQL table. In addition, a jMaki event is published. The event is consumed by the jMaki Yahoo table widget,which then inserts a new row in the displayed table without doing a page reload of the entire page. Thisdemonstrates the power of Ajax to do asynchronous refreshes of parts of a page. It also demonstrates how thejMaki Glue mechanism allows different widgets on a page to communicate.Before you can use jMaki PHP widgets in a PHP script, you need to insert the following PHP statement at thebeginning of the page: <?php require_once 'Jmaki.php'; ?>Then you can add widgets by calling the addWidget(...) function. The index page has two widgets andso includes two calls to the addWidget(...) function.Here's the code in index.php (note that some of the code lines have been broken to fit the width constraintsof the page): <?php require_once "Jmaki.php"; ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>Web Stack Sample Application</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <link rel="stylesheet" href="style.css"> </head> <body> <?php require_once("dbname.php"); if ( !mysql_select_db($database, $mysql_connection) ) { echo "<br><br><br>The database for this sample does not exist. <a href=\\"setup.php\\"> Click on the initialization link...</a>; exit(); } ?> // Create the HTML Form with the 3 fields: name, category, and price of a Product Item: <br>Using the following form, you can add products that will be inserted in a MySql database, and displayed using jMaki Ajax framework in the table below.<br> <br><br> <form action="#" > Product Name : <input id="name" name="name" type="text"><br> Product Category :<input id="category" name="category" type="text"><br> Product Price : <input id="price" name="price" type="text"><br> </form> <?php addWidget( array("name" => "yahoo.button", "value" => "{ label : 'add a product' }" )); ?gt; <br> // Create the Ajax jMaki table that displays the content of the MySQL database table: // Notice the service parameter that calls a PHP script called ListProducts.php. // This service will emit the content of the MySQL table into a JSON format that can // be consumed with jMaki table: <?php echo "<b><center>List of Products:</center></b><br><br>"; addWidget( array( "name" => "yahoo.dataTable", "args"=> "{columns : [ { 'label' : 'name', 'id' : 'name'}, { 'label':'category', 'id' : 'category'}, { 'label': 'price ', 'id' : 'price'} ]}", "service"=>"listProducts.php" ) ); ?> </body> </html>To better understand how the button action works, see the jMaki Glue File section. The code snippetin the Glue file that pertains to the button click action is as follows: jmaki.subscribe("/yahoo/button/onClick", function(args) ...When a user clicks the jMaki button, a jMaki event named /yahoo/button/onClick is sent to the jMaki event handlingmechanism and a callback specified in the jMaki Glue file is then executed.Product List ScriptThe Product List script, lisProducts.php is responsible for retrieving the contents of the products table.The script returns the contents as a collection of row entries inJavaScript Object notation (JSON) format as follows: [ name: 'value1', category: 'value2', price: 'value3'}, name: 'value1', category: 'value2', price: 'value3'}, name: 'value1', category: 'value2', price: 'value3'}, name: 'value1', category: 'value2', price: 'value3'}, ... ]In essence, the listProduct.php is a service available on the Web that returns data in JSON format to thebrowser. Data returned in this format can then be rendered by the jMaki Yahoo table widget that was defined in theindex.php page.Here is the lisProducts.php script: <?php require_once("dbname.php"); if ( !mysql_select_db($database, $mysql_connection) ) { ?> <p>The database for this sample does not exist.</p> <p>Please, run the <a href="setup.php>setup page.</a></p> <?php exit(); } @mysql_select_db($database); $query="SELECT \* FROM products"; $result=mysql_query($query); $num=mysql_numrows($result); mysql_close(); ?> <?php $i=0; echo "{'rows' : ["; while ($i < $num) { $name=mysql_result($result,$i,"name"); $category=mysql_result($result,$i,"category"); $price=mysql_result($result,$i,"price"); echo "{ name: '".$name ."' , category :'".$category."', price :'".$price ."'}"; if ($i != $num -1) echo ","; ++$i; } echo "]}"; ?>Add Product ScriptThe script named add.php is called when the user clicks the add a product button on themain page. The script connects to the database and posts the new data to be added.The script is in the button callback function that is defined in the glue.js script file.Here is the add.php script: <?php include("dbname.php"); mysql_connect($dbhost,$username,$password); @mysql_select_db($database) or die( "Unable to select database"); $name=$_POST["name"]; $category=$_POST["category"]; $price=$_POST["price"]; $query = "INSERT INTO products VALUES ('','$name','$category','$price')"; mysql_query($query); mysql_close(); echo "value added"; ?>jMaki Glue FileFinally, let's examine the jMaki Glue file, glue.js, that "glues" the parts of the applicationtogether. The jMaki Glue file is the visible part of the jMaki publish/subscribe mechanism. You can learn moreabout the jMaki publish/subscribe mechanism in the April 15, 2008 Tech TipWorking with jMaki Eventsand in the document jMaki Glue.When a user clicks on the add a product button, the jMaki button widget publishes an eventto a topic named /yahoo/button/onClick. A listener in the glue.js file that is subscribedto the /yahoo/button/onClick topic calls the add.php server-side script to insert thenew data into the MySQL database. To do that, the listener calls the jmaki.doAjaxfunction, which is executed asynchronously. The function specifies the service URL (add.php)and the content to be added: name, category, and price (all are entry fields in the form on the main page).The jmaki.doAjax function also specifies a callback function. After the add.php scriptsuccessfully inserts the data into the database, it calls the callback function. The callback functionpublishes a new event to a topic named /yahoo/dataTable/addRow to add a new row in the jMaki Yahoo table.This action updates the table with the new data inserted into the database.Here is the glue.js file: // uncomment to turn on the logger jmaki.debug = false; // uncomment to show publish/subscribe messages jmaki.debugGlue = false; // map topic for the add Product button jmaki.subscribe("/yahoo/button/onClick", function(args) { // get the values of the 3 fields in the form: var name= document.getElementById("name").value; var category= document.getElementById("category").value; var price= document.getElementById("price").value; //do an ajax request to the add server side logic, with the correct params: jmaki.doAjax({ url : "add.php", // call the add.php URL method : "POST", content : { name : name, category : category, price : price }, callback: function(req) { //in this call back, we just add a new row to the local jMaki table if (jmaki.trim(req.responseText) == "value added") jmaki.publish ('/yahoo/dataTable/addRow', { value: { name : name, category : category, price : price } } ); else alert ("error adding a row: "+req.responseText); } }); });SummaryBy adding the jMaki Ajax framework to the fully integrated software stack provided byOpenSolaris 2008.05, which includes a PHP engine,an Apache Web Server, and a MySQL database, you can develop web applications that present modern Web 2.0 type behavior,combining the power of a scalable operating system and the rich capabilities of Ajax technologies. The jMaki frameworkhides the complexity of JavaScript and server-side PHP page rendering.Further ReadingOpenSolaris.orgProject jMakiNetBeans IDE Early Access for PHPGlassFish Plugins (for the Eclipse jMaki plugin)About the AuthorLudovic Champenois (ludo) is a principal engineer at Sun Microsystems. He is currently an architect for theJava EE GlassFish Application and the OpenSolaris WebStack (AMP), focused on developer experience and tools integration.

by Ludovic Champenois OpenSolaris is an operating system (OS), an open source project, and a community. The project's goals are innovation, collaboration, and the extension of OpenSolaris technologiessu...

Enterprise Java technology

Tech Tips Quiz

Over the years, the Enterprise Java Technologies Tech Tips have covered a wide variety of enterprise Java technology topics.Here's a short quiz that tests your knowledge of some topics covered in recent Tech Tips. You can find the answers at the endof the quiz.Which of the following WS-\* security specifications is supported by Metro?a. WS-Securityb. WS-SecurityPolicyc. WS-SecureConversationd. WS-Trustd. All of the above.e. None of the aboveWhat is jMaki Glue?a. A jMaki mechanism for binding data on a server to client objects.b. A feature that enables widget-to-widget communication in jMaki.c. A jMaki widget that implements page "stickiness".d. A jMaki wrapper for the Dojo Glue widget.The following annotation appears in a stateful session bean: @PersistenceContext(type=PersistenceContextType.EXTENDED)What does the annotation do?a. Injects a container-managed extended persistence scope into the bean.This establishes a persistence context whose lifetime begins when the statefulsession bean is created and ends only when the stateful session bean is removed from the container.b. Injects a transaction-scoped extended persistence scope into the bean.This establishes a persistence context that ends when an associated transaction commits or isrolled back through the Java Transaction API (JTA).c. Injects a bean-managed extended persistence scope into the bean.This establishes a persistence context in which the bean attaches and detaches entities.d. None of the above.True or false, SIP uses HTTP as its underlying protocol?a. Trueb. FalseYou have two web services, one named WeatherService and the other named DegreeConverter.The WeatherService web service is implemented as a servlet. It has a Java Naming and Directory Interface(JNDI) name of service/MyServletService and its associated WSDL file is at URLhttp://localhost:8080/weatherservice/GetWeather?wsdl.The DegreeConverter web service is implemented as a stateless session bean. It has a JNDI name ofservice/MyEjbService and its associated WSDL file is at URLhttp://localhost:8080/DegreeConverterService/DegreeConverter?wsdl.You want to be able to reference both web services from a single application client, so you add the following annotations toyour client: @WebServiceRefs({ @WebServiceRef(name="service/MyServletService", type=servlet_endpoint.WeatherServiceService.class, wsdlLocation="http://localhost:8080/weatherservice/GetWeather?wsdl"), @WebServiceRef(name="service/MyEjbService", type=ejb_endpoint.DegreeConverterService.class, wsdlLocation="http://localhost:8080/DegreeConverterService/DegreeConverter?wsdl") })Will your client be able to reference both web services?a. Yes.b. No.AnswersWhich of the following WS-\* security specifications is supported by Metro?a. WS-Securityb. WS-SecurityPolicyc. WS-SecureConversationd. WS-Trustd. All of the above.e. None of the aboved. All of the above. Metro is a high performance, extensible, easy to use web service stack. It combines the JAX-WS referenceimplementation with Project Tango. Project Tango, also called Web Services Interoperability Technology or WSIT,implements numerous WS-\* specifications, including the following WS-\* security specifications: WS-Security,WS-SecurityPolicy, WS-SecureConversation, and WS-Trust, as described in the March 31, 2007 Tech TipSecuring Web Services Using WSIT.Metro supports multiple token profiles for WS-Security including the Kerberos token profile. For more informationabout Metro's support for Kerberos, see the January 29, 2008 Tech Tip,Building Kerberos-BasedSecure Services Using Metro.What is jMaki Glue?a. A jMaki mechanism for binding data on a server to client objects.b. A feature that enables widget-to-widget communication in jMaki.c. A jMaki widget that implements page "stickiness".d. A jMaki wrapper for the Dojo Glue widget.b. A feature that enables widget-to-widget communication in jMaki. Glue representsa programmatic approach to handling events in jMaki based on a publish/subscribe mechanism. In jMaki there are producersof events (also called publishers) and consumers of events (also called subscribers). When an event occurs on a widgetthat is a producer, the widget publishes a notification of that event to a topic. Widgets that are consumersof that topic are notified when events are published to that topic. This approach allows the producer and consumers to communicatein an asynchronous and decoupled way. For more information about jMaki Glue, see the April 15, 2008 Tech TipWorking with jMaki Events.The following annotation appears in a stateful session bean: @PersistenceContext(type=PersistenceContextType.EXTENDED)What does the annotation do?a. Injects a container-managed extended persistence scope into the bean.This establishes a persistence context whose lifetime begins when the statefulsession bean is created and ends only when the stateful session bean is removed from the container.b. Injects a transaction-scoped extended persistence scope into the bean.This establishes a persistence context that ends when an associated transaction commits or isrolled back through the Java Transaction API (JTA).c. Injects a bean-managed extended persistence scope into the bean.This establishes a persistence context in which the bean attaches and detaches entities.d. None of the above.a. Injects a container-managed extended persistence scope into the bean.This establishes a persistence context whose lifetime begins when the statefulsession bean is created and ends only when the stateful session bean is removed from the container.A persistence context is a basic concept in the Java Persistence Architecture.Within a persistence context, entity instances and their lifecycle are managed by an entity manager.In the @PersistenceContext annotation, the type specification ofPersistenceContextType.EXTENDED establishes a container-managed extended persistence context.In a container-managed persistence context, the lifecycle of the persistence context is managed automaticallyby the container.A container-managed persistence context may be defined to have either a lifetime that is scoped toa single transaction or an extended lifetime that spans multiple transactions. One of the importantdistinctions between a transaction-scoped persistence context and an extended persistencecontext is the state of the entities after a transaction completes. In the case of a transaction-scoped persistencecontext, the entities become detached, that is, they are no longer managed. In the case of an extended persistencecontext, the entities remain managed. Learn more in the February 15, 2008 Tech TipExtended PersistenceContext in Stateful Session Beans.True or false, SIP uses HTTP as its underlying protocol?a. Trueb. Falseb. False. Session Initiation Protocol (SIP) is a signaling protocol that is used to set up, modify, and terminatea session between two endpoints. SIP can be used to set up a two-party call, a multi-party call, or even a multicastsession for Internet calls, multimedia calls, and multimedia distribution. The SIP protocol operates at the same layeras HTTP, that is, the application layer, and uses TCP, UDP, or SCTP as the underlying protocol. It does not use HTTPas an underlying protocol. However, SIP does have a lot of similarities with HTTP. For example, like HTTP, SIP is textbased and user readable. Also like HTTP, SIP uses a request-response mechanism with specific methods, response codes,and headers. A notable difference between HTTP and SIP is that the request-response mechanism is asynchronous in SIP --a request does not need to be followed by a corresponding response. To learn more about SIP as well as SIP servlets,see the February 29, 2008 Tech TipAdding Voice to Java EE With SIPServlets.You have two web services, one named WeatherService and the other named DegreeConverter.The WeatherService web service is implemented as a servlet. It has a Java Naming and Directory Interface(JNDI) name of service/MyServletService and its associated WSDL file is at URLhttp://localhost:8080/weatherservice/GetWeather?wsdl.The DegreeConverter web service is implemented as a stateless session bean. It has a JNDI name ofservice/MyEjbService and its associated WSDL file is at URLhttp://localhost:8080/DegreeConverterService/DegreeConverter?wsdl.You want to be able to reference both web services from a single application client, so you add the following annotationsto your client: @WebServiceRefs({ @WebServiceRef(name="service/MyServletService", type=servlet_endpoint.WeatherServiceService.class, wsdlLocation="http://localhost:8080/weatherservice/GetWeather?wsdl"), @WebServiceRef(name="service/MyEjbService", type=ejb_endpoint.DegreeConverterService.class, wsdlLocation="http://localhost:8080/DegreeConverterService/DegreeConverter?wsdl") })Will your client be able to reference both web services?a. Yes.b. No.a. Yes. The @WebServiceRefs annotation allows multiple web service references to be declared in a class.Each web service reference is specified in a @WebServiceRef annotation. Here the client references two web serviceendpoints, a servlet endpoint and an EJB endpoint. Notice that each @WebServiceRef annotationhas the following properties:name. The Java Naming and Directory Interface (JNDI) name of the resource.type: The Java type of the resource.wsdlLocation. A URL pointing to the WSDL document for the web service.After specifying the web service references, the client can lookup each web service and invoke its methods as needed.For more information about this technique, see the March 14, 2008 Tech TipReferencing MultipleWeb Services From An Application Client.Future TipsHere's your opportunityto tell us what topics you would like to see covered in future issues of the Tech Tips. Send your topic requests toEnterprise_TechTips@sun.com. Your input will help us make the Tech Tipsbetter serve your needs.

Over the years, the Enterprise Java Technologies Tech Tips have covered a wide variety of enterprise Java technology topics.Here's a short quiz that tests your knowledge of some topics covered in...

security

Adding Authentication Mechanisms to the GlassFish Servlet Container

by Ron MonzilloThis tip will show you how to implement and configure new authentication mechanisms in theGlassFish v2 servlet container. GlassFish v2 includes implementations of a number of HTTP layer authenticationmechanisms such as Basic, Form, and Digest authentication. You can use the techniques describedin this tip to add alternative implementations of the included mechanisms or to add implementations ofnew mechanisms such as HTTP Negotiate/SPNEGO, OpenID, or CAS.GlassFish v2 and JSR 196GlassFish v2 implements the Servlet Container Profileof JRS-196, Java Authentication Service Provider Interfacefor Containers. JSR 196 defines a standard service-provider interface (SPI) for integrating authentication mechanismimplementations in message processing runtimes. You can use the techniques covered in this tip to add authenticationmechanisms to GlassFish because GlassFish supports the JSR 196 standard. JSR 196 extends the concepts of theJava Authentication and Authorization Service (JAAS) to enable pluggability of message authentication modules in messageprocessing runtimes. The standard defines profiles that establish contracts for the use of the SPI in specific contexts.The Servlet Profile of JSR-196 defines the use of the SPI by a Servlet container such that (1) the resulting container canbe configured with new authentication mechanisms, and (2) the container employs the configured mechanisms in itsenforcement of the declarative servlet security model (declared in a web.xml file using security-constraintelements).The JSR 196 specification defines a simple message processing model composed of four interactionpoints, 2 on the client side, and 2 on the server side, as shown in Figure 1.Figure 1. Security Processing Injection PointsA message processing runtime uses the SPI at these interaction points to delegate the correspondingmessage security processing to authentication providers, also called authentication modules, integrated into theruntime by way of the SPI.A compatible server-side message processing runtime, such as the GlassFish servlet container, supports thevalidateRequest and secureResponse interaction points of the message processing model.The servlet container uses the SPI at these interaction points to delegate the corresponding message securityprocessing to a server authentication module (SAM), integrated by the SPI into the container.A key step in adding an authentication mechanism to a compatible server-side message processing runtime such as theGlassFish servlet container, is acquiring a SAM that implements the desired authentication mechanism. One way to dothat is to write the SAM yourself, so let's examine how to do that.Writing a SAMA SAM implements the javax.security.auth.message.module.ServerAuthModule interface as defined by JSR 196and is invoked (indirectly) by the message processing runtime at the validateRequest andsecureResponse interaction points. A SAM must implement the five methods of the ServerAuthModuleinterface, each of which is described briefly below. See section "3. Servlet Container Profile" in theJSR 196 specification for additional background and details.getSupportedMessageTypes()An array of Class objects where each element defines a message type supported by the SAM.For a SAM to be compatible with the Servlet Container profile, the returned array must include theHttpServletRequest.class and HttpServletResponse.class objects.initialize(MessagePolicy requestPolicy, MessagePolicy responsePolicy, CallbackHandler Map options)The container calls this method to provide the SAM with configuration values and with a CallbackHandler.The configuration values are returned in the policy arguments and in the options Map. The SAM usesCallbackHandler to access services, such as password validation, provided by the container.AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject)The container calls this method to process each received HttpServletRequest. The request andits associated HttpServletResponse are passed by the container to the SAM in the messageInfoargument. The SAM processes the request and may establish the response to be returned by thecontainer. The SAM uses the provided Subject arguments to convey its authentication results. TheSAM returns different status values to control the container's invocation processing. The status values and thecircumstances under which they are returned are as follows:AuthStatus.SUCCESS is returned when the application request message is successfully validated.The container responds to this status value by using the returned client Subject to invoke the target of therequest. When this value is returned, the SAM (provided a custom AuthConfigProvider is not beingused) must use its CallbackHandler to handle a CallerPrincipalCallback using theclientSubject as an argument to the callback.AuthStatus.SEND_CONTINUE indicates that message validation is incomplete and thatthe SAM has established a preliminary response as the response message in messageInfo. The containerresponds to this status value by sending the response to the client.AuthStatus.SEND_FAILURE indicates that message validation failed and that the SAM has establishedan appropriate failure response message in messageInfo. The container responds to this statusvalue by sending the response to the client.AuthStatus.SEND_SUCCESS is not typically returned. This status value indicates the end ofa multi-message security dialog originating after the service interaction and during the processing of the applicationresponse. The container responds to this status value by sending the response to the client.ValidateRequest may also throw an AuthException to indicate that the message processingby the SAM failed without establishing a failure response message in messageInfo.secureResponse(MessageInfo messageInfo, Subject serviceSubject)The container calls this method before sending a response, resulting from an applicationinvocation, to the client. The response is passed to the SAM in the messageInfo argument. Inmost cases, this method should just return the SEND_SUCCESS status.cleanSubject(MessageInfo messageInfo, Subject subject)This method removes the mechanism specific principals and/or credentials from the subject. Thismethod is not currently called by the container. A legitimate implementation could remove all theprincipals from the argument subject.Sample SAMThe class MySam.java is a sample SAM implementation. Notice that the sampleimplements the five methods of the ServerAuthModule interface. For example, here isthe implementation of the initialize() method: public void initialize(MessagePolicy reqPolicy, MessagePolicy resPolicy, CallbackHandler cBH, Map opts) throws AuthException { requestPolicy = reqPolicy; responsePolicy = resPolicy; handler = cBH; options = opts; }Also notice that the validateRequest method is stubbed. For authorization-protected resources,validateRequest returns a "FORBIDDEN" status code along with the message "authenticationrequired and not yet implemented." However, validateRequest allows access for unprotected resourcesby returning AuthStatus.SUCCESS. The SAM uses the return value of requestPolicy.isMandatory()to determine when the request is to an authorization-protected resource. The servlet container profile mandates thatthe message processing runtime establish the requestPolicy such it can be used by the SAM to determinewhen authentication is required. public AuthStatus validateRequest( MessageInfo msgInfo, Subject client, Subject server) throws AuthException { try { if (requestPolicy.isMandatory()) { HttpServletResponse response = (HttpServletResponse) msgInfo.getResponseMessage(); response.setStatus (HttpServletResponse.SC_FORBIDDEN); response.sendError( HttpServletResponse.SC_FORBIDDEN, "authentication required and not yet implemented"); return AuthStatus.SEND_FAILURE; } else { setAuthenticationResult(null, client, msgInfo); return AuthStatus.SUCCESS; } } catch (Exception e) { AuthException ae = new AuthException(); ae.initCause(e); throw ae; } }Before you can use the sample SAM, you need to compile, install, and configure it. Then you can bind it to an application.Compiling and Installing the SAMTo compile the SAM, you need to include the SPI in your classpath. When GlassFish is installed, the JAR file containing theSPI, jmac-api.jar, is installed in the lib subdirectory under the root of your GlassFish installationdirectory.After you compile the SAM, install it by copying a JAR file containing the compiled SAM to the libsubdirectory under the root of the GlassFish installation directory.Configuring the SAMYou can configure a SAM for GlassFish v2 using the GlassFish v2 Admin Console, officially known as theSun Java System Application Server Admin Console. Here are the steps:Make sure the GlassFish V2 Application Server is running. If it is not already running, you can start it using thefollowing command: <GF_HOME>bin/asadmin start-domain domain1where <GF_HOME> is the directory where you installed GlassFish v2.Open the GlassFish v2 Admin Console by pointing your browser to the URL: http://localhost:4848/.Login to the Admin Console by entering your ID and password.Expand the Configuration node at the bottom of the left-hand pane.Navigate to the Security node, expand it, and click MessageSecurity.Under Message Security Configurations, either open the HttpServlet layer if it already exists, or create itif it doesn't exist by clicking the New button. Clicking the button opens the New Message Security Configuration window.If you need to create the layer, you will need to configure the provider. To do that:Set the following in the New Message Security Configuration window as shown in Figure 2:Provider Type: serverProvider ID: MySamClass Name: SAM, that is, tip.sam.MySam.Do not check the Default Provider: Enabled check box.Figure 2. Configuring the Provider for the SAMClick the OK button. This saves the settings and opens the Message Security Configurations window.Click on HttpServlet in the Authentication Layer column.Select the Providers tab. This opens the Provider Configuration window.Select MySam in the Provider ID column. This opens the Edit Provider Configuration window.Click the Save button to complete the configuration of the provider.If the HttpServlet layer already exists, do the following:Open the HttpServlet layer by selecting it in the Message Security Configurations window.Select the Providers tab to open the Provider Configuration window.Click the New button to open the New Provider Configuration window. In the Provider Configuration area of the window, set the following:Provider Type: serverProvider ID: MySamClass Name: SAM, that is, tip.sam.MySam.Do not check the Default Provider: Enabled check box.Note that the provider configuration utility also provides a dialog box that you can use to configure additionalproperties. If you configure additional properties in this way, the properties are passedin the options parameter when the SAM’s initialize method is called. The sample SAM in this tipdoes not require any initialization properties. However, another SAM, for example, could support a property namingthe group principals to add as a side effect of a successful authentication.At this point the SAM is installed and available for use by GlassFish v2.Binding the SAM to Your ApplicationAfter you install and configure the SAM, you can bind it for use by the container on behalf of one or more ofyour applications. You have a few options in how you bind the SAM, depending on whether or not you arewilling to repackage and redeploy your application.Option1: If you are willing to repackage and redeploy, you can bind the SAM within the sun-web.xmlfile of your web application. You do this by configuring the httpservlet-security-provider attributeof the sun-web-app element to contain the provider id assigned when the SAM was installed, that is,MySam.If you use the NetBeans IDE, open the configuration file (in the non-XML view) and select theGeneral tab. Assign the provider id to the field titled Http Servlet Security Provider.You then need to rebuild and redeploy the application.Option 2: The first option leverages the native AuthConfigProvider implementation that shipswith GlassFish. Another approach would be to develop your own AuthConfigProvider andregister it with the Glassfish AuthConfigFactory for use on behalf of your applications. For example, a simple AuthConfigProvider might obtain, through its initialization properties, the classname of a SAM to configure on behalf of the applications for which the provider is registered. You can find a description of the functionality of an AuthConfigProvider and of the registration facilities provided by an AuthConfigFactory in the JRS-196 specification.After you have bound the SAM for use by the container on behalf of your application(s), the container will invokeMySam whenever a request is made to a resource within your application. Moreover, when a request is madeto a resource within your application that is protected by an auth-constraint, MySam will not dispatchthe request until it has determined that a successful authentication has occurred.Let's complete the implementation of validateRequest so that MySam will be able to performthe authentication.Revising the SAMYou've gone through the steps of installing, configuring, and binding a SAM. Now let's return tothe authentication mechanism implementation and make some changes to complete the implementation of thevalidateRequest method. To keep things simple, let's change the SAM to implement HTTP BasicAuthentication, or at least an approximation of it.Here is the modified SAM. The primary changes are as follows:New imports are added to account for the use of the Group and Password Validation callbacks,and the Base64 decoder. import javax.security.auth.message.callback.GroupPrincipalCallback; import javax.security.auth.message.callback.PasswordValidationCallback; import org.apache.catalina.util.Base64;New constants are added to represent the property names and the HTTP Basic headeridentifiers. private String realmName = null; private String defaultGroup[] = null; privte static final String REALM_PROPERTY_NAME = "realm.name"; private static final String GROUP_PROPERTY_NAME = "group.name"; private static final String BASIC = "Basic"; static final String AUTHORIZATION_HEADER = "authorization"; static final String AUTHENTICATION_HEADER = "WWW-Authenticate";The initialize method looks for the group.name and realm.name properties.The group.name property is used to configure the default group that will be assigned as a result of anysuccessful authentication. The realm.name property is used to define the realm value sent back to thebrowser in the www-authenticate challenge. public void initialize(MessagePolicy reqPolicy, MessagePolicy resPolicy, CallbackHandler cBH, Map opts) throws AuthException { requestPolicy = reqPolicy; responsePolicy = resPolicy; handler = cBH; options = opts; if (options != null) { realmName = (String) options.get(REALM_PROPERTY_NAME); if (options.containsKey(GROUP_PROPERTY_NAME)) { defaultGroup = new String[]{(String) options.get(GROUP_PROPERTY_NAME)}; } } }The implementation of the validateRequest method is revised to evaluate the www-authorize header andto issue the www-authenticate challenge. public AuthStatus validateRequest( MessageInfo msgInfo, Subject client, Subject server) throws AuthException { try { String username = processAuthorizationToken(msgInfo, client); if (username == null && requestPolicy.isMandatory()) { return sendAuthenticateChallenge(msgInfo); } setAuthenticationResult( username, client, msgInfo); return AuthStatus.SUCCESS; } catch (Exception e) { AuthException ae = new AuthException(); ae.initCause(e); throw ae; } }The setAuthenticationResult method is extended to add the defaultGroup if it is configured. // distinguish the caller principal // and assign default groups private void setAuthenticationResult(String name, Subject s, MessageInfo m) throws IOException, UnsupportedCallbackException { handler.handle(new Callback[]{ new CallerPrincipalCallback(s, name) }); if (name != null) { // add the default group if the property is set if (defaultGroup != null) { handler.handle(new Callback[]{ new GroupPrincipalCallback(s, defaultGroup) }); } m.getMap().put(AUTH_TYPE_INFO_KEY, ""MySAM"); } }Configuring the Revised SAMAfter you have built and installed the revised SAM in the GlassFish lib directory, from yourbrowser, use the GlassFish v2 Admin Console to reconfigure the SAM as follows:Expand the Configuration node at the bottom of the left-hand pane.Navigate to the Security node, expand it, and click Message Security.Under Message Security Configurations, select HttpServlet.Select the Providers tab.Click the entry for MySam to open the Edit Provider Configuration screen.Click the Add Property button in the Additional Properties frame and entergroup.name in the Name field and user in the Value field.Click the Add Property button again and enterrealm.name in the Name field and Sam in the Value field.Click the Save button.Alternatively, you could create a second provider with a different name and with thevalues for the defined properties. You could then switch the binding of your application to the newprovider and redeploy your application.As before, after the revised SAM is installed and bound to your application, it will be invoked by the containeron behalf of your application. When you attempt to access an auth-protected resource within your application,the revised SAM will prompt you for a username and password. The SAM will use the CallbackHandlerto ask the container to validate the supplied username and password using the realm configured for your application.For the validation to succeed, you will need to know the username and password of a user in the realm configuredfor your application.By default, GlassFish applications are configured to use the file realm. To add a user to the file realm, use theGlassFish v2 Admin Console as follows:Expand the Configuration node at the bottom of the left-hand pane.Navigate to the Security node, expand it, and click on Realms.Under Realms, open the file realm.Click the Manage Users button.Click on New.Fill in values for "User Id", "New Password", and "Confirm New Password".Click the OK button.Further ReadingYou can learn more about using JSR 196 in the following documents:JRS-196, Java Authentication Service Provider Interfacefor ContainersPluggableAuthentication in the Glassfish Web TierA SPNEGO and Kerberos plugin for GlassfishAbout the AuthorRon Monzillo is the specification lead for JSR 196 and JSR 115: Java AuthorizationContract for Containers. He defined the declarative security model for servlets and ledthe team that defined the EJB Secure Interoperability protocol, that is, CORBA/CSIv2. He alsomade contributions to the OASIS WS-Security standards and was the primary author of theWS-Security SAML token profile. Ron participates in most security activities relating toJava EE, servlets, and GlassFish.2008 JavaOne Conference: Last Chance for Discount RegistrationDon't miss this opportunity. Register by May 5, and save $100 for the JavaOne conference, May 6-9, 2008,in San Francisco. Experience 300+ sessions on Java technology, Rich Internet Applications, open source,compatibility and interoperability, next-generation scripting languages, Web 2.0, services integration,e-commerce collaboration, and more. Meet with 100+ companies leading Java technology innovations andexpanding into new technologies; and take advantage of opportunities to meet the experts in the SOA Village,Mobility and Device Village, and Startup Exhibitor Alley, all in the JavaOne Pavilion.Use priority code J8EM5IC, and register today at java.sun.com/javaone.

by Ron Monzillo This tip will show you how to implement and configure new authentication mechanisms in theGlassFish v2 servlet container. GlassFish v2 includes implementations of a number of HTTP layer...

jMaki

Working with jMaki Events

by Carla MottThe January 27, 2007 Tech Tip Introductionto jMaki introduced jMaki, a lightweight framework for creatingWeb 2.0 applications using standards-based technologies such as CSS, HTML, and JavaScript. Among its other features,the jMaki framework makes available widgets from popular JavaScript toolkits such as Dojo, Yahoo, Scriptaculous, and Googlein a way that's familiar to Java technology, PHP, or Phobos developers. The tip briefly discussed the components in jMaki andshowed some examples of using the framework to build Web 2.0 functionality into an application. It also briefly covered theframework's event mechanism and Glue, a key feature in the jMaki event mechanism.The following tip expands the discussion of the event mechanism in jMaki. You'll learn more about the concepts that underliethe jMaki event mechanism and how to take advantage of it to easily interact with widgets.For example, consider an application in which a user clicks on the date in a calendar widget, and that event causes anotherwidget such as a combobox to refresh or load different data. Or think of an application in which selecting a value ina combobox widget determines the values that are displayed in a table. Or perhaps an application where clicking on a widgetloads a service, such as a blog, into another widget such as a table widget. Using the jMaki event mechanism makes theseoperations easy and straightforward.Overview of jMaki EventsEvents in jMaki are handled by something called Glue. jMaki Glue is a powerful feature that enables JavaScript components to talk to each other.You can use Glue in your web application to implement widget-to-widget communication. However, any JavaScript componentcan utilize the power of jMaki Glue.Let's start with a simple example that uses Glue. Suppose you had an application that displays two buttons and two tables ona page as shown in Figure 1.Figure 1. A Web Page That Displays Two Buttons and Two TablesThe first button, labeled "select row 2", selects the second row of both tables, as shown inFigure 2, while the second button, labeled "yahoo table: select row 2",only selects the second row of the second table.Figure 2. What Happens When You Click the select Row 2 ButtonHere's the code that enables the interaction: <a:widget name="yahoo.button" value=" {label : 'select row 2', action : {topic : '/table/select', message: {targetId: 'bar'}}}"/> <a:widget name="yahoo.button" value=" {label : 'select row 2 in yahoo table', action : {topic : '/mytable/select', message: {targetId: 'bar'}}}"/> <a:widget name="dojo.table" value="{columns : [ { label : 'Title', id : 'title'}, { label :'Author', id : 'author'}, { label : 'ISBN', id : 'isbn'}, { label : 'Description', id : 'description'} ], rows : [ { title : 'Book Title 1', author : 'Author 1', isbn: '4412', description : 'A Some long description'}, { id : 'bar', title : 'Book Title 2', author : 'Author 2', isbn : '4412', description : 'A Some long description'} ] }" /><a:widget name="yahoo.dataTable" subscribe="['/table', '/mytable']" value="{columns : [ { label : 'Title', id : 'title'}, { label :'Author', id : 'author'}, { label : 'ISBN', id : 'isbn'}, { label : 'Description', id : 'description'} ], rows : [ { title : 'Book Title 1', author : 'Author 1', isbn: '4412', description : 'A Some long description'}, { id : 'bar', title : 'Book Title 2', author : 'Author 2', isbn : '4412', description : 'A Some long description'} ] }" />Notice that there are ajax custom tags that wrap four widgets in the code example, two for Yahoo button widgets, one fora Dojo table widget, and one for a Yahoo table widget. Notice too that the tags for both of the button widgetsinclude the action attribute: action : {topic : '/table/select' ...In jMaki, all table wrappers subscribe to the generic topic "/table" as well as to a topic that specifies thespecific table (for example, "dojo/table"). Notice that the tag for the Dojo table widget includes thesubscribe attribute: subscribe="['/table', '/mytable']" ...In both cases, the widgets subscribe to topics that are published by the button widgets.More specifically, one table widget subscribes to the generic topics ("/table" and"/dojo/table") and the other subscribes to a generic topic ("/table")and to a custom topic ("/mytopic") for that instance of the table.This is all you have to write for these widgets to communicate. jMaki Glue handles the widget-to-widget communicationwithout you having to write any additional JavaScript code.Publish/Subscribe MechanismSo what really is Glue? It's a programmatic approach to handling events in jMaki based ona publish/subscribe mechanism. Publish/subscribe mechanisms are used extensively in messaging systems.In jMaki there are producers of events (also called publishers)and consumers of events (also called subscribers). Widgets can be both producers and consumers. When an eventoccurs on a widget that is a producer, the widget publishes a notification of that event to a topic.A topic is a string or a name that associates the producer of an event to the consumers of that event andallows the producer and consumers to communicate in an asynchronous and decoupled way.Widgets that are interested in being notified of events published to that topic can registerto become consumers of that topic. To do that, they subscribe to that topic.Most widgets in jMakipublish events to topics based on some action. For example, a user selecting a row in a table, or clickingon a button, or expanding a tree node can result in the respective widget publishing a notification, that is,an event to a topic. Some widgets like the jMakidcontainer, areconsumers and expect to receive notification of events telling them to do something in response, such as loadcontent from another page, update the rows in a table, or add a node to a tree. The notification includes dataidentifying the producer widget and any data in the widget that is useful to the consumer. Each consumerreceives a notification of the event along with the published data. Using thismechanism, any producer widget can "talk" to any consumer widget (or set of consumer widgets) ina loosely coupled way.Using Publish/SubscribeThere are two ways to use the jMaki publish/subscribe mechanism: (1) through actions, which represent a declarativeapproach, or (2) through programmatic events. Both approaches use the same implementation and therefore behavethe same way.ActionsActions are a way of defining a producer of events in a declarative form. This approach is useful when the action is simpleor straightforward. Consider the previous example. Recall that you want to select the second row of both tables when a userclicks on the "select row 2" button.Here again is the tag for the button widget: <a:widget name="yahoo.button" value=" {label : 'select row 2', action : {topic : '/table/select', message: {targetId: 'bar'}}}"/>The button widget uses the action property to publish to the /table' topic the command/select' and the payload targetId: 'bar'.Before continuing with the discussion of the action approach, let's briefly examine topic names, commands, and payloads.Topic names. By default, topic names start with a slash followed by the name of the toolkit (such as jmaki,dojo, yahoo, and google), then a slash followed by the name of the widget (such as table, tree, or accordion).For example, the dojo table topic name defaults to "/dojo/table". See thejMaki widget documentation forthe name of the topic to which a widget will publish by default. You can, however, override the default topicname, and because a topic name is a string, you can set it to any string. For the Yahoo button widget, thetopic name is set to "table".Commands. Many widgets are consumers of events and so also have event handler code in them. The event handlersin the widget code perform common operations on the widget. The set of operations supported are specified in the jMakiData Event model pages.The jMaki documentation refers to the operations as commands. Commands are specific to the type of widget. The command nameis appended to the end of the topic name, and by convention, it is the string that follows the last slash in the topic name.For the Yahoo button widget, the published command is "select", and it follows the slash after thetopic name "table".Payloads. When a widget publish to a topic it specifies the topic name and a payload. The payload is the data thatthe widget publishes to the topic. The Yahoo button widget publishes the payload targetId: 'bar'.Here again is the tag for the Yahoo table widget: <a:widget name="yahoo.dataTable" subscribe="['/table', '/mytable']" value="{columns : [ { label : 'Title', id : 'title'}, { label :'Author', id : 'author'}, { label : 'ISBN', id : 'isbn'}, { label : 'Description', id : 'description'} ], rows : [ { title : 'Book Title 1', author : 'Author 1', isbn: '4412', description : 'A Some long description'}, { id : 'bar', title : 'Book Title 2', author : 'Author 2', isbn : '4412', description : 'A Some long description'} ] }" />Actions rely on code that already exists in each widget. The underlying code sets up event handlers that can be usedthrough the action property or directly. When a widget is initialized, the topic, such as /table/select,is associated by the underlying code with a function that is in the widget code.If you examine the jMaki data models, you'll notice a set of properties that are common across the models. One of thoseproperties is id. You use this property to identify an item such as a tab, table row, or tree node.Some of the other common properties are label, href, and action.Notice that the second row of the table has the id bar' (if no id property is present, jMaki generatesan id for you) and recall that the payload published by the Yahoo button widget fora select event is targetId: 'bar'. This targets the second row of the Yahoo table whenthe Yahoo button is selected.Programmatic EventsThere are times when the action you want performed in response to an event is not as straightforward as highlightinga row in a table. For example, you might want the response action to get data from a database and then use the data to updatea table. To do this you need to use the programmatic interface of Glue, which like the action approach,is based on the publish/subscribe mechanism. In fact, actions use Glue, but are transparent to you as an applicationdeveloper. To use the programmatic events approach, you typically add some code to a JavaScript file namedglue.js. The file is loaded by the jMaki framework by default. Placing the JavaScript code in theglue.js file makes it available to the entire application and promotes separation of JavaScript codefrom HTML, XML, and other markup in the application.Let's use the Programmatic Events approach to extend the previous example. Specifically, let's add a button to the pageand use the button to add a row to a table.Here's the code for the new button: <a:widget name="yahoo.button" value=" {label : 'add row', action : {topic : '/mytopic'}}"/>You also need to add a listener to the topic '/mytopic', which will add the row of data to the table. Add the listeneror handler to the glue.js file. The jMaki runtime will add this new handler to the internal hash map for topicswhen the page is loaded. jmaki.subscribe("/mytopic", function(args) { jmaki.log("in mytopic"); var row = { id : 'new', title : 'Book Title 3', author : 'Author 3', isbn : '4413', description : 'A Some long description'}; jmaki.publish("/table/addRow",{value: row}); });Here the row data is hard coded, but it can come from a database. The jmaki.publish API is used to send the datato the topic /table'. Both tables in this example subscribe to that topic so both will add a row when thebutton is clicked.Figure 3 shows what the page looks like after the new button, labeled "add row", is clicked.Figure 3. A Button that Adds a Row to a TableChaining EventsLet's look at one last example. Suppose you wanted the new button in the previous example to add a row to the tables and alsoselect the new row. To do that, you don't need to change the tags. Instead, you only need to update the handler inthe glue.js file. Here's what the updated handler code looks like: jmaki.subscribe("/mytopic", function(args) { jmaki.log("in mytopic"); var row = { id : 'new', title : 'Book Title 3', author : 'Author 3', isbn : '4413', description : 'A Some long description'}; jmaki.publish("/table/addRow",{value: row}); jmaki.publish("/table/select", {targetId: 'new'}); });This is an example of how to chain events in jMaki. You're chaining the publishing of two events: the event thatresults in a row being added to a table, and an event that selects the added row.Figure 4 shows what the page looks like after the add row button is clicked.Figure 4. A Button that Adds a Row to a Table and Selects the RowYou can download theapplication that displays the page shown in Figure 4 and try it out yourself.Further ReadingThe jMaki sample getwidgetdata is a more complete example of using Glue in jMaki. That example demonstrateshow to get data from the widget using a handler and how to pass the data to the server and on to another page in theapplication. The jMaki loadtable example shows how to use actions and Glue code to manipulate a table widget.Both examples are included in the standalone bundles, jmaki-java-1.1.zip and jmaki-php-1.1.zip,which you can download from the jMaki Downloads page.For more information about the Publish/Subscribe mechanism seeHandling jMaki Widget Events Using thePublish and Subscribe Mechanism.Also see the blog Fun withjMaki: Using the Yahoo Geocoder service with the Dojo Combobox, which shows some of the potential of jMaki Glue towork as a controller.About the AuthorCarla Mott is a contributor on Project jMaki. She is also a Java Enterprise Community leader on java.net anda committer on Dojo, an open-source JavaScript toolkit. Previously, she was a project owner for Project GlassFishwhere she helped to open source Sun's application server and to build the GlassFish community.

by Carla Mott The January 27, 2007 Tech Tip Introduction to jMaki introduced jMaki, a lightweight framework for creatingWeb 2.0 applications using standards-based technologies such as CSS, HTML, and...

web services

Secure Conversations for Web Services With Metro

by Jiandong GuoMetro is a high performance, extensible, easy-to-use web services stack.It combines the JAX-WS reference implementation with Project Tango. Project Tango, also called Web Services Interoperability Technologyor WSIT, implements numerous WS-\* standards to enable interoperability with other implementations and to provide Quality ofService (QOS) features such as security, reliability, and transaction support. Metro is bundled as part of the open source applicationserver called GlassFish v2 and thecommercial offering, Sun Java System Application Server 9.1.Metro also runs in other containers such as Tomcat.An earlier Tech Tip, SecuringWeb Services Using WSIT introduced Metro's support (through WSIT) for web services security. This support implements the followingweb services security specifications published by the Organization for the Advancement of Structured Information Standards (OASIS)consortium: WS-Security, WS-SecurityPolicy, WS-SecureConversation, and WS-Trust. The tip also showed examples of using the WS-Securitysupport in Metro. The following tip focuses on the support in Metro for WS-SecureConversation. You will learn the basics ofWS-SecureConversation and see examples of using the WS-SecureConversation support in Metro.A sample application package accompanies the tip. The sample applicationdemonstrates how to enable secure conversations in Metro for a web service. You can enable secure conversations for a web servicemanually by coding appropriate policy assertions in the Web Services Definition Language (WSDL) file for the service. However,the NetBeans IDE offers an easier, more automated way to enable secureconversations in Metro for a web service. Because of this, the sample in this tip uses NetBeans, specificallyNetBeans IDE 6.0.1. The sample also usesGlassFish v2 UR1.An Introduction to WS-SecureConversationWS-SecureConversation is a web services specification designed to enable secure communication between web services.The specification is built on top of two other web services specifications: WS-Security and WS-Trust. WS-Security provides the basicframework for message level security in web services and WS-Trust specifies a framework for brokered trust across different securitydomains. WS-Security and WS-Trust were covered in the tipSecuring Web Services Using WSIT.The objective of WS-SecureConversation is to enable secure messaging between a client and a web service, especially insituations where they exchange multiple messages. WS-Security is useful for securing simple one-way messages. However, to securelyexchange multiple messages, a client and a web service typically require a security context in which to exchange the messages.WS-SecureConversation provides just such a context. It adds a "handshake" process, shown in Figure 1,that allows a web service and its client to authenticate to each other and to establish a shared security context. The securitycontext is shared by the client and web service for the lifetime of a communication session. This context contains a shared secretkey that can be used to secure subsequent messages between the client and service, and can significantly improve performance by avoidingrepeated key exchanges in multi-message exchange scenarios.Figure 1. WS-SecureConversation Handshake ProcessIn WS-SecureConversation, a SecurityContextToken, typically obtained from a Security Token Service (STS), is used todescribe the security context. An STS, introduced in the WS-Trust specification, is trusted by both the client and the web service toprovide interoperable security tokens.Here is an example of a shared security token: <wsc:SecurityContextToken xmlns:wsu='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd' xmlns:wsc='http://schemas.xmlsoap.org/ws/2004/04/sc'> <wsu:Identifier>uuid:...</wsc:Identifier> <wsu:Created>2008-03-07T08:24:05</wsu:Created> <wsu:Expires>2008-03-08T09:24:06</wsu:Expires> <wsse:Keys> <xenc:EncryptedKeyId="...">...</EncryptedKeyId> <wsse:SecurityTokenReference>... </wsse:SecurityTokenReference> ... </wsse:Keys> </wsc:SecurityContextToken>The <SecurityContextToken> element describes the security context. The <Identifier> elementidentifies the security context using an absolute Uniform Resource Identifier (URI). Notice too that the creation and expiration dateof the shared security token are also specified. The <Keys> element specifies the shared secret key of the securitycontext.WS-SecureConversation also introduces key derivation mechanisms that enhance overall security. These mechanisms can use differentalgorithms for deriving keys. Although a shared secret can be used to sign or encrypt messages, the WS-SecureConversation specificationrecommends that messages be signed or encrypted using derived keys. Using a common secret, a client and a web service can definedifferent key derivations to use. It's possible, for example, to derive four keys so that a client and a web service can sign andencrypt using separate keys. The key derivation mechanisms are not only used within the shared security context, that is, with aSecurityContextToken, but can also be used with other security tokens such as those used in WS-Security.WS-SecureConversation in MetroMetro supports WS-SecureConversation within the general framework of WS-Security, WS-SecurityPolicy, and WS-Trust. Each web serviceenabled for WS-SecureConversation has an associated STS that is used to issue and manage security contexts. Managing a security contextmight include tasks such as renewing or canceling the security context. An extensible SessionManager on the server canbe used to persist the security contexts so that the contexts can be used in a "web farm" (a site thatuses multiple servers to deliver its content) in support of failover and high availability. By default,the SessionManager stores the security contexts in memory, but you can extend the SessionManager to storethe session in a database.Metro specifies a WS-SecureConversation through a <sp:SecureConversationToken> policy assertion.Security requirements for the WS-SecureConversation messages are specified by the <sp:BootstrapPolicy> elementinside the <sp:SecureConversationToken> policy assertion. No run-time API is required.Security contexts and derived keys are represented in Metro by their corresponding tokens, <SecurityContextToken>and <DerivedKeyToken>, which are used in securing application messages within the general mechanisms introduced in WS-Security.Here is part of a policy assertion in Metro that includes a WS-SecureConversation specification: <ns3:SecureConversationToken ns3:IncludeToken=" http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"> <wsp:Policy> <wsp:ExactlyOne> <wsp:All <ns3:BootstrapPolicy> <wsp:Policy> <wsp:ExactlyOne> ... <ns3:AlgorithmSuite> <wsp:Policy> <wsp:ExactlyOne> ... </wsp:ExactlyOne> </wsp:Policy> </ns3:AlgorithmSuite <ns3:IncludeTimestamp/> ... <ns3:X509Token ns3:IncludeToken= "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"> ... <ns3:WssX509V3Token10/> ... <ns3:OnlySignEntireHeadersAndBody/> ... <ns3:WssX509V3Token10/ ... </ns3:BootstrapPolicy> ... </wsp:Policy> </ns3:SecureConversationToken>Here is an example of a SecurityContextToken and DerivedKeyToken: <wsc:SecurityContextToken> <wsc:Identifier>urn:uuid:4d651587-8443-4874-8e01-308a8b2fb8f8</wsc:Identifier> </wsc:SecurityContextToken> <wsc:DerivedKeyToken <wsse:SecurityTokenReference> <wsse:Reference ValueType="http://schemas.xmlsoap.org/ws/2005/02/sc/sct" URI="urn:uuid:4d651587-8443-4874-8e01-308a8b2fb8f8" /> </wsse:SecurityTokenReference> <wsc:Offset>0</wsc:Offset> <wsc:Length>24</wsc:Length> <wsc:Nonce>uE/cm2f0wuq5C7e2sJTvY704</wsc:Nonce> </wsc:DerivedKeyToken>Security ProfilesAs mentioned earlier, the NetBeans IDE offers an easier, more automated way to enable secure conversations in Metro for a webservice. One of the ways it does this is by providing a set of security profiles that specify the mechanism to be used in securingconversations. The profiles are:Username Authentication with Symmetric KeysMutual Certificates SecurityTransport Security (SSL)Message Authentication over SSLSAML Authorization over SSLEndorsing CertificateSAML Sender Vouches with CertificatesSAML Holder of KeySTS Issued TokenSTS Issued Token with Service CertificateSTS Issued Endorsing TokenYou specify one of these mechanisms when youconfigure security for a web serviceusing the NetBeans IDE as shown in Figure 2.Figure 2. Specifying a Security Profile for a Web ServiceYou can enable a secure conversation with any of the security mechanisms simply by clicking the Configure button next to the securitymechanism selection. This opens a secondary window for that security mechanism. Then select the "Establish Secure Session (SecureConversation)" checkbox in the secondary window as shown in Figure 3.Figure 3. Establishing a Secure Conversation for an Web ServiceWhen you build and run the web service, the handshake process will be used to establish a secure session between the web service andits client. In general, if you want to secure a web service for more than one message in a transaction, you should enable a secureconversation.Running the Sample CodeA sample application package accompanies the tip. To install and run the sample do the following:If you haven't already done so, download NetBeansIDE 6.0.1 and GlassFish v2 UR1.Start the NetBeans IDE.If GlassFish v2 is not one of the NetBeans application servers, add it as follows:Right-click the Servers node inthe Services window.Select Add Server.Select GlassFish v2.Click the Next button.Click the Browse button and browse to the location that you installed GlassFish v2.Click the Choose button.Click the Next button.Set the Admin Password to the default, adminadmin, unless you chose a different password for GlassFish.Click the Finish button.Add testing certificates to GlassFish as follows:Download the copyv3.zip file from thexwss : Document & files page and unzip the file. You should see a newly extracted directorycopyv3.Change to the copyv3 directory.Open the build.xml file and set the AS_HOME variable to the location where you installed GlassFish v2.Run the ant command. This copies the sample certificates to the GlassFish v2 application serverkeystores for use with the sample. You can find ant in the <GF_install_dir>\\lib\\ant\\bin directory,where <GF_install_dir> is the directory where you installed GlassFish v2.Download the sample package and extract its contents. You should now see a newly extracted directory sc_samples.Change to the sc_samples\\lib directory. Copy the hook.jar file to theGF_install_dir\\lib directory.Open the CalculatorServiceSC project in theNetBeans IDE as follows:Select Open Project from the File menu.Browse to the sc_samples directory from the sample application download.Select CalculatorServiceSC in the Open Project window.Click the Open Project Folder button.CalculatorServiceSC is a simple calculator service that was created using the NetBeans IDE. It uses the MutualCertificates Security profile and is enabled for secureconversation. You can see the security configuration forCalculatorServiceSC by expanding its Web Services node in the Projects window. Then right-click on CalculatorSC in the WebServices node and select Edit Web Services Attributes as shown in Figure 4.Figure 4. Viewing Web Service AttributesRunthe CalculatorServiceSC project as follows:Right-click the CalculatorServiceSC node in the Projects window.Select Run.In response, the CalculatorServiceSC service is deployed to the GlassFish v2 application server andthe WSDL file for the web service is published to http://localhost:8080/CaculatorServiceSC/CaculatorSCService?wsdl.If you examine the WSDL file, you'll notice that it includes a <sp:SecureConversationToken> policy assertion anda <sp:BootstrapPolicy> element inside the policyassertion. <ns3:SecureConversationToken ns3:IncludeToken= "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"> <wsp:Policy> <wsp:ExactlyOne> <wsp:All> <ns3:BootstrapPolicy> <wsp:Policy> <wsp:ExactlyOne> <wsp:All> ...In other words, the NetBeans IDE generates the appropriate WSDLspecifications for a secure conversation based on the securityprofile and secure conversation selection that were made when the web service was created. You do not have to specify theWSSecureConversation-related specifications in the WSDL file manually.Open the CalculatorClientSC project with the NetBeans IDE as follows:Select Open Project from the File menu.Browse to the sc_samples directory from the sample application download.Select CalculatorClientSC in the Open Project window.Click the Open Project Folder button.CalculatorClientSC is the client for the CalculatorServiceSC service.Run the CalculatorClientSC project as follows:Right-click the CalculatorClientSC node in the Projects window.Select Run.You should see the results similar to those shown in Figure 5.Figure 5. CalculatorClientSC ResultOpen the CalculatorService project with the NetBeans IDE as follows:Select Open Project from the File menu.Browse to the sc_samples directory from the sample application download.Select CalculatorService in the Open Project window.Click the Open Project Folder button.CalculatorService is a simple calculator service that was created using the NetBeans IDE. It uses the MutualCertificates Security profile, but is not enabled for secure conversation. You can see the security configuration forCalculatorService in the same way as you did for CalculatorServiceSC.Run the CalculatorService project as follows:Right-click the CalculatorService node in the Projects window.Select Run.In response, the CalculatorService service is deployed to the GlassFish v2 application server and the WSDL filefor the web service is published to http://localhost:8080/CaculatorService/CaculatorService?wsdl.If you examine the WSDL file, you'll notice that it does not include any WSSecureConversation-related specifications. Inparticular, there is no <sp:SecureConversationToken>policy assertion or<sp:BootstrapPolicy> elementin the WSDL file.Open the CalculatorClient project with the NetBeans IDE as follows:Select Open Project from the File menu.Browse to the sc_samples directory from the sample application download.Select CalculatorClient in the Open Project window.Click the Open Project Folder button.CalculatorClient is the client for the CalculatorService service.Run the CalculatorClient project as follows:Right-click the CalculatorClient node in the Projects window.Select Run.You should see the results similar to those shown in Figure 6.Figure 6. CalculatorClient ResultCompare the running times for each project in the displayed Time value. Notice that it takes much less time to runthe calculator service with secure conversation enabled.Currently the client accesses the calculator service five times. You can adjust the number of times that theclient calls the calculator service and see how it impacts the running times for each project.About the AuthorJiandong Guo is a staff engineer and a senior member of the Application Server Web Services Security Group.He has lead the development of implementations and solutions based on WS-SecureConversation and WS-Trust in theTango project.-----------------------------------------------------------------------------------------------------------------------------Java EE SDKs RefreshedUpdate 4 versions of the Java EE 5 SDKs and Java Application Platform SDKs now offer multilingual support.The "+ JDK" bundles also include the latest Java SE 6 (JDK) Update 5. Download the SDKs now.--------------------------------------------------------------------------------------GlassFish With MySQL Cobundle ReleasedSun Java System Application Server 9.1 Update 1 (GlassFish v2 UR1) is now available bundled with theMySQL Community Server open-source database.Read the Release Notes and thisblog for details.Download it now.

by Jiandong Guo Metro is a high performance, extensible, easy-to-use web services stack.It combines the JAX-WS reference implementation with Project Tango. Project Tango, also called Web Services...

Enterprise JavaBeans Technology

Referencing Multiple Web Services From An Application Client

by Bhakti MehtaJSR 109: Implementing Enterprise Web Servicesdefines the programming model and runtime architecture for implementing web services in Java.The architecture builds on the Java EE component architecture to provide a client and serverprogramming model that is portable and interoperable across application servers.JSR 109 defines two ways of implementing a web service. One way is based on the Java classprogramming model -- the web service is implemented by a Java class that runs in a web container.The other way is based on the Enterprise JavaBeans (EJB) programming model -- the web service isimplemented as a stateless session bean that runs in an EJB container. Two previous Tech Tipscovered the two techniques. The tipDeveloping Web ServicesUsing JAX-WS, described how to develop a web service using the Java class programming modeland Java API for XML Web Services (JAX-WS) 2.0. The tipDeveloping Web ServicesUsing EJB 3.0 described how to develop a web service using the EJB programming model and JAX-WS 2.0.The following tip is a successor to those previous tips. It describes how to develop an applicationclient that references multiple web services that implement any combination of the two webservices programming models.A sample package accompanies this tip. It demonstrates a standalone Java client that accessestwo web services, one implemented as a servlet and the other implemented an a stateless session bean.The example uses an open source application server called GlassFish v2, specifically GlassFish V2 UR1.You can download GlassFish v2 from theGlassFishCommunity Downloads page. You can find instructions on how to install and configure GlassFishhere.Also see the GlassFish QuickStart Guide for the basic steps to start the server and deploy an application.Let's start by creating the two web services.The Servlet-Based Web ServiceHere is the source code for WeatherService, a servlet-based web service that displays the currenttemperature for a given zip code. You can find the source code for Weather Service in theservlet_endpoint directory of the sample package. @WebService public class WeatherService { public float echoTemperature(String zipcode) { System.out.println("Processing the temperature for " + zipcode); //Its Beverly Hills let it be nice and sunny !! return 80; } }As you can see, JAX-WS 2.0 relies heavily on the use of annotations as specified inJSR 175: A Metadata Facility for the JavaProgramming Language andJSR 181: Web Services Metadata for the JavaPlatform, as well as additional annotations defined by the JAX-WS 2.0 specification.Notice the @WebService annotation in the WeatherService class. This is an annotationtype defined in the javax.jws.WebService package and marks the class as a web service.A web service requires an endpoint implementation class, a service endpoint interface, and portable artifactsfor execution. However, as specified by JSR 109, you only need to providea javax.jws.WebService-annotated service class, as is the case here.Creating the EJB-Based Web ServiceHere is the code for DegreeConverter, a web service that is implemented as a stateless session bean.This web service converts a temperature value from the Fahrenheit scale to the Celsius scale. You can find the sourcecode for DegreeConverter in the ejb_endpoint directory of the sample package. @WebService @Stateless public class DegreeConverter { public float fahrenheitToCelsius(float far){ float degCelcius; degCelcius = (far - 32) \* 9/12; return degCelcius; } }One of the significant improvements in the Java EE 5 platform is a much simpler EJB programming model as defined in theEJB 3.0 specification.You can declare aclass a session bean or entity bean simply by annotating it. For example, you can declare a class a stateless session beanby annotating it with the @Stateless annotation, as is the case for this web service .Again, all you need to provide is the javax.jws.WebService-annotated service class.Compiling and Deploying the Web ServicesAfter you create each web service, you need to compile it, generate portable artifacts for its execution,and deploy it. An ant task is provided in the sample package to perform these steps. See the sectionRunning the Sample Code for details.Creating the ClientAfter you deploy the web services, you can access them from a client program. The client uses@WebServiceRef annotations to declare references to a web service. The @WebServiceRefannotation is in the javax.xml.ws package, and is specified in JSR 181. If you examine the source codefor Client, the client program used in this tip (you can find the source code for Clientin the client directory of the installed sample package), you'll notice the following: @WebServiceRefs({ @WebServiceRef(name="service/MyServletService", type=servlet_endpoint.WeatherServiceService.class, wsdlLocation="http://localhost:8080/weatherservice/GetWeather?wsdl"), @WebServiceRef(name="service/MyEjbService", type=ejb_endpoint.DegreeConverterService.class, wsdlLocation="http://localhost:8080/DegreeConverterService/DegreeConverter?wsdl") }) public class Client { ...The @WebServiceRefs annotation allows multiple web service references to be declared in the class.Here the class references two web service endpoints, a servlet endpoint and an EJB endpoint. Notice that each@WebServiceRef annotation has the following properties:name. The Java Naming and Directory Interface (JNDI) name of the resource.type: The Java type of the resource.wsdlLocation. A URL pointing to the WSDL document for the web service.Here is the code in Client that looks up the servlet-based weather service, gets its port,and invokes its echoTemperature method: javax.naming.InitialContext ic = new javax.naming.InitialContext(); WeatherServiceService svc = (WeatherServiceService)ic.lookup( "java:comp/env/service/MyServletService"); float temp = svc.getWeatherServicePort().echoTemperature("90210");Here is the code in Client that looks up the EJB-based service, gets its port, and invokes itsfahrenheitToCelsius method: DegreeConverterService degConverter = (DegreeConverterService)ic.lookup( "java:comp/env/service/MyEjbService"); System.out.println("Invoking the degree converter service for zip 90210.. " ); float degree = degConverter.getDegreeConverterPort().fahrenheitToCelsius(temp); System.out.println("Temperature in degrees is " + degree);Compiling and Running the ClientAfter you create the client, you need to generate portable artifacts required to compile the client and thencompile the client. You can then run the client. An ant task is provided in the sample package to perform these steps.See the section Running the Sample Code for details.Running the Sample CodeA sample package accompanies this tip. To install and run the sample:Download the sample package and extract its contents. You should now see a newly extracted directory<sample_install_dir>/webservicesrefs-techtip, where <sample_install_dir>is the directory where you installed the sample package. For example, if you extracted the contents to C:\\on a Windows machine, then your newly created directory should be at C:\\webservicesrefs-techtip.If you haven't already done so, downloadGlassFish v2UR1.Change to the webservicesrefs-techtip directory and set AS_HOME inthe build.xml file to point to the location where you installedGlassFish. For example, if GlassFish is installed in a directory name mydir/glassfish, setAS_HOME as follows: <property name="AS_HOME" value="/mydir/glassfish"/>Start GlassFish by entering the following command: <GF_install_dir>/bin/asadmin start-domain domain1where <GF_install_dir> is the directory in which you installed GlassFish.Execute the following command: ant serverThis ant task target builds the server-side classes for the web services, that is, it compiles the classes,generates the portable artifacts, and packages the war and EJB jar files. It then deploys the web servicesto GlassFish. The WSDL files for the web services are published to:http://localhost:8080/weatherservice/GetWeather?wsdlhttp://localhost:8080/DegreeConverterService/DegreeConverter?wsdlExecute the following command: ant clientThis ant task target runs the wsimport utility to generate the client-side artifacts and then compilesand runs the client. You should see the following in the response: runclient: runclient-windows: runclient-non-windows: [exec] Invoking the weather service for zip 90210.. [exec] Temperature for zip 90210 is 80.0 [exec] Invoking the degree converter service for zip 90210.. [exec] Temperature in degrees is 36.0 BUILD SUCCESSFULNote: To run the sample with JDK 6 prior to the JDK 6 Update 4 release, you need use the endorsed override mechanismby copying the webservices-api.jar file from <GF_install_dir>/lib/endorsed, where<GF_install_dir> is the directory where you installed GlassFish, to<jdk_install_dir>/jre/lib/endorsed, where<jdk_install_dir> is the directory in which the runtime software is installed. If you run the samplewith JDK 6 Update 4 or later, you do not need to use the override mechanism.About the AuthorBhakti Mehta is a Member of Technical Staff at Sun Microsystems. She is currently working on the implementation ofJSR 109, the Web Services for Java EE specification. Previously she has worked on WS-Reliable Messaging to interoperate withthe Microsoft Windows Communication Foundation, as well as the JAXB and JAXP Reference Implementations. She has a MastersDegree in Computer Science from the State University of New York at Binghamton and a Bachelors Degree in Computer Engineeringfrom Mumbai University.----------------------------------------------------------------------------------------------------------------------------------------------------------------------------Connect and Participate With GlassFishTry GlassFish for a chance to win an iPhone. This sweepstakes ends on March 23, 2008. Submit your entry today.

by Bhakti Mehta JSR 109: Implementing Enterprise Web Services defines the programming model and runtime architecture for implementing web services in Java.The architecture builds on the Java EE...

Enterprise JavaBeans Technology

Adding Voice to Java EE With SIP Servlets

by Prasad SubramanianSession Initiation Protocol (SIP)is a signaling protocol that is used to set up, modify, and terminate asession between two endpoints. SIP can be used toset up a two-party call, a multi-party call, or even a multicastsession for Internet calls, multimedia calls, and multimediadistribution. JSR 116: SIP Servlet APIis a server-side interface describing a container of SIP components orservices. SIP servlets, servlets that runin a SIP container, are similar to HTTP Servlets, but also support theSIP protocol. Together, SIP and SIP servlets,are behind many popular telecommunications-based applications thatprovide services such as Voice-over-IP (VoIP), instantmessaging, presence and buddy list management, as well as webconferencing.SIP and SIP servlets are also important in the enterprise. Combinedwith Java EE technology, SIP servlets can be used toadd rich media interactions to enterprise applications.JSR 289:SIP Servlet v1.1 updates the SIP Servlet APIand defines a standard application programming model to mix SIPservlets and Java EE components. SIP servlets are going toplay an even bigger part in building the next generation oftelecommunications services.This Tech Tip covers some of the basic concepts underlying SIP and SIPservlets. It also presents a sampleapplication that uses SIP servlets and HTTP servlets to provide VoIPphone service.What is SIP?An easy way to describe SIP is to examine a usage scenario.Let's say a user identified as A wants to set up a call with a useridentified as B. In a telecommunicationssetting, user A and B would communicate through what are called useragents. One example of a user agent isa soft phone -- a software program for making telephone calls over theInternet. Another example isa VoIP Phone -- a phone that uses VoIP. Here are the steps that need tohappen to set up the call:A invites B to start a conversation. As part of the invitation, Aindicates what media it is capable of supporting.B receives the invitation, sends an immediate response to A, andthen evaluates the invitation.When B is ready to accept the invitation, it sends anacknowledgment to A. As part of the acknowledgement, B indicateswhat media it supports.A examines the acknowledgment it receives from B and determinesif the media supported by B and A are the same.If A and B support the same media, a call is set up between A and B.The media specified in the invitation facilitatesthe call.Figure 1 illustrates the steps in setting up a call.Figure 1. Steps in Setting Up a Call SIP provides a standardized way of carrying out these steps. It doesthis by defining specific request methods,responses, response codes, and headers for signaling and call control.The protocol has been standardized bythe Internet Engineering Task Force (IETF) under RFC3261and is now accepted as the standard signaling protocol for the3rd GenerationPartnership Project (3GPP) and as a permanent elementin the IP Multimedia Subsystem (IMS)architecture.How is SIP related to HTTP?People often ask if SIP uses HTTP as the underlying protocol. Theanswer is no.SIP is a protocol that operates at the same layer as HTTP, that is, theapplication layer, and uses TCP, UDP, or SCTPas the underlying protocol. However, SIP does have a lot ofsimilarities with HTTP. For example, like HTTP, SIP is text basedand user readable. Also like HTTP, SIP uses a request-responsemechanism with specific methods, response codes, and headers.A notable difference between HTTP and SIP is that the request-responsemechanism is asynchronous in SIP -- a request does notneed to be followed by a corresponding response. In fact, a SIP requestcould result in one or more requests being generated.SIP is a peer-to-peer protocol. This means that a user agent can act asa server as well as a client. This is anotherdifference between SIP and HTTP. In HTTP, a client is always a clientand a server is always a server.SIP supports the following request methods and response codes:Request methods:REGISTER. Used by a client to register an addresswith a SIP server. .INVITE. Indicates that the user or service is beinginvited to participate in a session.The body of this message includes a description of the session to whichthe user or service is being invited.ACK. Confirms that the client has received a finalresponse to an INVITE request.This method is only used with INVITE requests.CANCEL. Used to cancel a pending request.BYE. Sent by a user agent client to indicate to theserver that it wishes to terminate the call.OPTIONS. Used to query a server about itscapabilities.Response codes:1xx: Provisional. An ACK thatindicates the action was successfully received, understood, andaccepted.3xx: Redirection. Further action is required toprocess this request.4xx: Client Error. The request contains incorrectsyntax and cannot be fulfilled at this server.5xx: Server Error. The server failed to fulfill anapparently valid request.6xx: Global Failure. The request cannot be fulfilledat any server.Session Description ProtocolSession Description Protocol (SDP) is a format for describing the mediaformat and type to be used in a multimedia session.SIP uses SDP as a payload in its messages to facilitate the exchange ofcapabilities between various user agents. For example,the content of an SDP might specify the codecs supported by the useragent and the protocol to be used such asReal-time Transport Protocol (RTP).SIP MessageFigure 2 shows the composition of a SIP message .There are three major parts:Request Line. Specifies the request method, address, and SIPversion.Headers. Specify data about the session or call to be set up orterminated.Message Body. Provides the payload, that is the SDP, describingthe media for the session.Figure 2. Composition of a SIP Message The SIP Servlet ModelThe SIP servlet programming model is based on the servlet programmingmodel. It brings programming in SIP closerto Java EE. Servlets are server-side objects that process incomingrequests and send an appropriate response to the client.They are typically deployed in a servlet container and have awell-defined life cycle. The servlet container isresponsible for managing the life cycle of the servlets within thecontainer and managing resources relatedto technologies such as JNDI and JDBC that the servlet uses. Theservlet container also manages network connections forservlets.As mentioned earlier, SIP servlets are similar to HTTP Servlets, exceptthat they process SIP requests.They do this by defining specific methods to process each of the SIPrequest methods.For example, HTTP servlets define the doPost() method,which overrides the service() method,to handle POST requests. By comparison, SIP servletsdefine a doInvite() method, which alsooverrides the service() method, to handle INVITErequests.JSR116defined SIP Servlet API 1.0. It specified:An API for the SIP servlet programming model.The responsibilities of the SIP servlet container.How SIP servlets interface with HTTP servlets and Java EEcomponents.The initial SIP Servlet API specification is being revised byJSR 289:SIP Servlet v1.1.SIP Servlet API -- Key ConceptsThe key concepts that underlie SIP servlets are similar to those thatunderlie HTTP servlets. The followingsections briefly describe some of those concepts.SipServletRequest and SipServletResponseThe request-response methodology in SIP is similar to that for HTTPservlets. A request is defined in aSipServletRequest object and a response in a SipServletResponseobject.However, only one ServletRequest or ServletResponseobject is non-null. That's becausea SIP request does not result in a symmetric response. There is also acommon super interface, calledSipServletMessage, for both SipServletRequestand SipServletResponse objects.The SipServletMessage interface defines the methods thatare common to SipServletRequestand SipServletResponse objects.Figure 3 illustrates the hierarchy of the SipServletRequestandSipServletResponse objects.Figure 3. Hierarchy of SipServletRequestand SipServletResponse Objects Servlet ContextThe servlet context as defined in the servlet specification alsoapplies to SIP servlets. The servlet specification definesspecific context attributes that are used to store and retrieveinformation specific to SIP servlets and interfaces from thecontext. The servlet context can be shared with HTTP servlets withinthe same application. This is explained in thesection Converged Applications.Deployment DescriptorAn XML-based deployment descriptor is used to describe the SIPservlets, the rules for invoking them, as well asthe resources and environment property used in the application. Thisdescriptor is in a sip.xml file andis similar to the file used in HTTP servlets. The sip.xmlfile is defined by an XMLschema.SIP Application PackagingSIP applications have the same packaging structure as web applications.They are packaged in the JAR format with a fileextension of .sar (Sip archive) or .war (web archive).Converged Context and Converged ApplicationAn application may use both SIP and HTTP servlets to create a service.To allow for HTTP and SIP servlets being in the same applicationpackage, the SIP servlet specificationdefines a ConvergedContext object. This object holds theservlet context sharedby both HTTP and SIP servlets and provides the same view of theapplication to SIP and HTTP servlets in terms ofservlet context attributes, resources, and JNDI namespaces.When an application includes both SIP and HTTP servlets it is known asa converged application. This is in contrastto a SIP-only application, which is called a SIP application. Aconverged application is similar in structure toa SIP application except that it has a web.xml file as adeployment descriptor in addition toa sip.xml file. In SIP Servlet API 1.1 (JSR289), theconcept of converged applications has been extendedto also cover enterprise applications. Enterprise applications can nowinclude a SIP application or a converged applicationas a module. This type of enterprise application is called a convergedenterprise application.SIP SessionsThe SIP servlet specification defines SipSession objectsto represent a session over SIP in the same way asHttpSession objects represent sessions over HTTP. Becausea single application such as a convergedapplication may have sessions over HTTP and SIP, the specification alsodefines SipApplicationSession, whichis a session object at the application level. The SipApplicationSessionobject acts as a parent to HTTP andSIP sessions (that is, protocol sessions) in an application.AnnotationsRecall that the SIP Servlet API 1.1 aims to align SIP servlets withJava EE 5. As a result, the specificationintroduces the use of annotations defined by Java EE 5 within SIPservlets and listeners. It also defines customannotations to represent interfaces defined by the SIP servletspecification. The specification introduces the followingannotations:@SipServlet. Used to indicate that a particular class isa SipServlet@SipApplication. Used to define a SIP application. Thisannotation has a set of attributes, one of them being the "name" attribute,which is used to define the name of the application. TheSipApplication annotation can be used to create a logical collection ofservlets which form an application, without the use of deployment descriptor.@SipListener. Allows a particular class to beregistered as a SipListener for a particular SIP application. The nameof the SIP application is defined as an attribute to this annotation.@SipApplicationKey. A method level that helps define aSipApplicationKey for a SIP application. The SipApplicationKeyis used to associate request with existing SipApplicationSessions.Project Sailfin - an Open Source SIP Application ServerA SIP servlet container can be standalone, that is, supporting only SIPservlets, or it can be a converged containersupporting both HTTP and SIP servlets. However, for most enterpriseuses, a SIP servlet container needs to bea converged container within an application server.Project Sailfinis an effort toproduce an open source implementation of a SIP servlet container usingtheGlassFishapplication server. The project is beingdeveloped under java.net, with Sun and Ericsson as the majorcontributors. Sailfin, the SIP servlet containerimplementation in GlassFish being developed in the SailFin project,supports SIP Servlet API 1.0 and aims to supportSIP Servlet API 1.1 when the specification is finalized.The CallSetup Sample ApplicationThe sample application for this tip, named CallSetup, is available aspart of the SailFin download. You can downloadSailFin from theDownload SailFin Builds page.Follow theSailFin Project - Instructionsto install and configure SailFin. The code for the CallSetupapplication is in the<sailfin-install-home>/samples/sipservlet/CallSetupdirectory, where<sailfin-install-home> is the directory where youinstalled SailFin.The CallSetup application uses SIP servlets and HTTP servlets toprovide VoIP phone service. The applicationplaces VoIP calls with the help of a Back-to-Back User Agent (B2BUA)SIP servlet. A B2BUA sets up a call betweentwo user agents by calling each user agent individually and thenconnecting the two of them.CallSetup ComponentsCallSetup includes the following components:Registration.java. A plain old Java object (POJO)that represents the registered user.RegistrarServlet. A SIP servlet that allows users toregister. The servlet is also used to persistthe user data in the the Java DB database bundled with SailFin.RegistrationBrowserServlet.java. An HTTP Servletthat provides an interface to select the registeredusers for the call.SipCallSetupServlet.java. An HTTP Servlet that sendsan INVITE message to the first user (UserB).B2BCallServlet.java. A SIP Servlet that handles the response fromthe first user and sets up the callwith the second user (User A)web.xml. Deployment descriptor for the HTTP servlets.sip.xml. Deployment descriptor for the SIP servlets.sun-web.xml. A product-specific deploymentdescriptor.persistence.xml. Defines the persistence unit.Figure 4 shows the sequence of execution of theapplication.Figure 4. CallSetup Sequence of Execution Let's look at some of the code in the components that compriseCallSetup. Not all of the components for the applicationare shown here and not necessarily all the code in each component.You're encouraged to explore the entire code for theapplication in the SailFin download.RegistrarServlet.javaWhen a user agent sends a REGISTER request, the doRegister()method is invoked and theregistration data is stored. A response with a status code is then sentto the user agent.importcom.ericsson.sip.Registration;@PersistenceContext(name = "persistence/LogicalName", unitName ="EricssonSipPU")public class RegistrarServletextends SipServlet{    The PersistenceUnit annotation is usedto annotate the EntityManagerFactory with the name of the PU to be used.    @PersistenceUnit(unitName= "EricssonSipPU")    privateEntityManagerFactory emf;   The Resource annotation is used to inject the UserTransaction     @Resource    privateUserTransaction utx;    protectedvoid doRegister(SipServletRequest request) throws ServletException,IOException {        SipServletResponse response= request.createResponse(200);        try {                        TheSipServletRequest object is parsed to get to address and requestheaders. The Contact header is obtained and stored in the database            SipURI to = cleanURI((SipURI)request.getTo().getURI());           ListIterator<Address> li = request.getAddressHeaders("Contact");           while (li.hasNext()){               Address na = li.next();               SipURI contact = (SipURI)na.getURI();               logger.log(Level.FINE, "Contact = " + contact);                                 An EntityManagerobject is created for storing the user data.               EntityManager em =emf.createEntityManager();               try {                       utx.begin();                       Registration registration = new Registration();                       registration.setId(to.toString());                       registration = em.merge(registration);                       em.remove(registration);                       utx.commit();                       logger.log(Level.FINE, "Registration was successfully created.");                } catch (Exception ex) {                       try {                           utx.rollback();                       } catch (Exception e) {                       }               }               em.close();               If the registration is successful , a response code of 200 OK is sent               response.send();        } catch(Exception e) {           If theregistration is not successful , a response code of 500 is sent            response.setStatus(500);            response.send();        }    }RegistrationBrowserServlet.javaThis is an HTTP Servlet that provides an interface to list registeredusers and to set up calls between the two of them.@PersistenceContext(name= "persistence/LogicalName", unitName ="EricssonSipPU")public classRegistrationBrowserServlet extends HttpServlet {@PersistenceUnit(unitName ="EricssonSipPU") private EntityManagerFactory emf;   public CollectiongetRegistrations() {       EntityManager em =emf.createEntityManager();       Query q = em.createQuery("selectobject(o) from Registration as o");       return q.getResultList();   }   protected void processRequest(HttpServletRequest request,HttpServletResponse response)   throws ServletException, IOException {      response.setContentType("text/html;charset=UTF-8");       PrintWriter out =response.getWriter();              This gets the list ofregistrations      Collection registrations = getRegistrations();       Iterator iter =registrations.iterator();      out.println("<html><body>");      Call to the HTTP servlet SipCallSetupServlet      out.println("<FORM ACTION = \\"/CallSetup/SipCallsetupServlet\\"METHOD = POST>");       out.println("<INPUT TYPE=SUBMITNAME=Submit VALUE=\\"Submit\\">");       out.println("</FORM>");       out.println("SipFactoryInstance ="+sf.toString());      out.println("</body></html>");       out.close();   }SipCallSetupServlet.javaThis HTTP Servlet is called from the RegistrationBrowserServletandacts like a B2BUA by setting up a call between the two users.publicclass SipCallSetupServlet extends HttpServlet {        SipFactory sf = null;        TimerService ts = null;        ServletContext ctx = null;    public void init(ServletConfig config) throwsServletException {       ctx = config.getServletContext();       Getting the SIpFactory object from the ServletContext      sf = (SipFactory) ctx.getAttribute(SipServlet.SIP_FACTORY);    }    protected void processRequest(HttpServletRequestrequest, HttpServletResponse response)    throws ServletException, IOException {        String callA = null;        String callB = null;        Getting the contacts from request parameters        String[] contacts =request.getParameterValues("CONTACT");        if ( contacts.length < 2)  {           return;        }        callA = contacts[0];        callB = contacts[1];       Using the SipFactory object to create a SipApplicationSession        SipApplicationSession as =sf.createApplicationSession();        Using theSipFactory object to create a "To" and "From" Address objects        Address to = sf.createAddress(callB);       Address from = sf.createAddress(callA);                Creating a SipServletRequest using the SipFactory  and theSipApplicationSessionObjects created. Note that         INVITE is being sentas  if UserA is inviting UserB.        SipServletRequest sipReq =sf.createRequest(as, "INVITE", from, to);         logger.log(Level.FINE, "SipCallSetupServlet sipRequest = " +sipReq.toString());                 Set an attributein SipServletRequest to indicate that this is an initial INVITE        sipReq.setAttribute("CALL","INITIAL");         // set servlet toinvoke by response        Getting a SipSession from the Request created         SipSession s = sipReq.getSession();         This is the key part. We set name of the servlet that would handler theresponse for the           Request being sent. Here b2b is the name of the SIP Servlet that wouldhandle the response            to thisrequest.        s.setHandler("b2b");         // lets send invite toB ...          Sending the request         sipReq.send();    }B2BCallServlet.javaThis SIP Servlet receives and handles the response to the INVITErequest sent by SipCallSetupServlet.The servlet processes the response headers and body, gets the SDP, andsends another INVITE request to theother user agent, along with the SDP metadata. After it receives theresponse from other user with a success responsecode, the servlet sets up the call between the two users.publicclass B2BCallServlet extends SipServlet {   SipFactory                             sf              = null;   ServletContext                         ctx             = null;   publicvoid init(ServletConfig config) throws ServletException {        super.init(config);        ctx =config.getServletContext();           Get the SipFactory from the ServletContext            sf = (SipFactory)ctx.getAttribute(SipServlet.SIP_FACTORY);            ts =(TimerService) ctx.getAttribute(SipServlet.TIMER_SERVICE);    }    protectedvoiddoResponse(SipServletResponse resp) throws ServletException,IOException {       get the  SipApplicationSession and SipServletRequest from theresponse       SipApplicationSessionsas = resp.getApplicationSession(true);        SipServletRequest origReq =resp.getRequest();        String alreadySent =(String) origReq.getAttribute("SENT_INVITE");               if( alreadySent == null && resp.getContentLength() > 0&& resp.getContentType().equalsIgnoreCase("application/sdp")) {           String responseFrom = (String) origReq.getAttribute("CALL");            Checkif this an response to INITIAL INVITE sent from the HTTP Servlet, andif there is             anSDP sent in the response, create an INVITE to the other user            if("INITIAL".equals(responseFrom)) {               //Take the SDP and send to A              Note that To address in the orginal request is the From address hereand vice versa. This is what makes this servlet act like               a B2BUA.               SipServletRequest newReq =sf.createRequest(sas,"INVITE",origReq.getTo(),origReq.getFrom());               newReq.setContent(resp.getContent(),resp.getContentType());               SipSession ssA = newReq.getSession(true);               SipSession ssB = resp.getSession(true);               Set the SipSession object as a session attribute to each call leg               ssA.setAttribute("OTHER_SESSION",ssB);               ssB.setAttribute("OTHER_SESSION",ssA);               //Test               Set the b2b servletas the handler for the response for the new request being sent.               ssA.setHandler("b2b");               ssB.setHandler("b2b");               origReq.setAttribute("SENT_INVITE","SENT_INVITE");               send the request to the other user               newReq.send(); //Send to A            }else {                If this is aresponse from User A then get the SDP from User A and set it i               SipSession ssB = (SipSession)resp.getSession().getAttribute("OTHER_SESSION");               ssB.setAttribute("SDP",resp.getContent());            }        } else {           return;        }        // Count so that both sidessent 200.        Ifresponse has a 200OK as the status code       if( resp.getStatus() == 200 ) {            Check if this is a response from theUserB ( first user)           SipServletResponse first = (SipServletResponse)sas.getAttribute("GOT_FIRST_200");            if(first == null ) { // This is the first 200               sas.setAttribute("GOT_FIRST_200",resp);            }            else{ //This is the second 200 sen both ACK               Thisis a second response and now we send an ACK to both                 User A and UserB. This exchanges the SDP and sets up the call.               sendAck(resp);               sendAck(first);            }        }    }          Thismethod sends the ACK with the SDP.   private void sendAck( SipServletResponse resp ) throws IOException{        SipServletRequest ack =resp.createAck();        //Check if pending SDP toinclude in ACK        Object content =resp.getSession().getAttribute("SDP");        if( content != null ) {           ack.setContent(content,"application/sdp");        }        ack.send();    }}sip.xmlThe sip.xml file defines the SIP servlets and specifiestheir mapping. The mapping for a SIP servletuses the equal, and, or, and notoperators to define a conditionin which the servlet is invoked. In this case, the match is on therequest method being either REGISTER,INVITE, OPTIONS, or MESSAGE.<sip-app>    <display-name>SIPRegistrar</display-name>    <description>SIP Registrarapplication</description>    <servlet>        <servlet-name>registrar</servlet-name>        <description>RegistrarSIP servlet</description>       <servlet-class>com.ericsson.sip.RegistrarServlet</servlet-class>        <init-param>           <param-name>Registrar_Domain</param-name>           <param-value>ericsson.com</param-value>        </init-param>       <load-on-startup>1</load-on-startup>    </servlet>    <servlet>        <servlet-name>b2b</servlet-name>       <servlet-class>com.ericsson.sip.B2BCallServlet</servlet-class>       <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>        <servlet-name>registrar</servlet-name>        <pattern>           <and>               <equal>                   <var ignore-case="false">request.uri.host</var>                   <value>test.com</value>               </equal>               <or>                   <equal>                       <var ignore-case="false">request.method</var>                       <value>REGISTER</value>                   </equal>                   <equal>                       <var ignore-case="false">request.method</var>                       <value>INVITE</value>                   </equal>                   <equal>                       <var ignore-case="false">request.method</var>                       <value>OPTIONS</value>                   </equal>                   <equal>                       <var ignore-case="false">request.method</var>                       <value>MESSAGE</value>                   </equal>               </or>           </and>        </pattern>    </servlet-mapping></sip-app>persistence.xmlThe persistence.xml file defines the persistence unit, EricssonSipPU,which is used to persistthe registration data in the database. The application uses the defaultJDBC resource available with Sailfin,jdbc/__default.<?xmlversion="1.0" encoding="UTF-8"?><persistence version="1.0"xmlns="http://java.sun.com/xml/ns/persistence"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/persistencehttp://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">  <persistence-unitname="EricssonSipPU"transaction-type="JTA">   <provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>   <jta-data-source>jdbc/__default</jta-data-source>    <properties>      <propertyname="toplink.ddl-generation" value="drop-and-create-tables"/>    </properties>  </persistence-unit></persistence>Running the Sample ApplicationTo run the CallSetup application, follow the instructions on theSailFin Project - Instructionspage. If you follow the instructions successfully, you should be ableto set up a call between two softphone clients.The phone should ring sequentially at two selected end points.SummaryThis tip covered some of the basic concepts underlying SIP and SIPservlets. It also presented a sampleapplication that uses SIP servlets and HTTP servlets to provide VoIPphone service. And it introduced the SailFinproject, which is building an open source implementation of a SIPservlet container using the GlassFish application server.To learn more about SIP, SIP servlets, and the SailFin project, consultthe following resources:Session Initiation Protocol (sip)ProjectSailFinSailFin WikiNote that there is a NetBeans plugin available for SIP servlets, whichallows you to create a SIP application usingthe NetBeans IDE. The plugin is available as a part of SailFin. You canlearn more about the NetBeans pluginin the blog entryNetBeans 6.1 and Project Sailfin.About the AuthorPrasad Subramanian is a staff engineer at Sun Microsystems and is theengineering lead for Project Sailfin.----------------------------------------------------------------------------------------------------------------------------------------------------------------------------Connectand Participate With GlassFishTry GlassFish for a chance to win an iPhone. This sweepstakes ends onMarch 23, 2008. Submit your entry today.

by Prasad Subramanian target="_blank">Session Initiation Protocol (SIP) is a signaling protocol that is used to set up, modify, and terminate a session between two endpoints. SIP can be used toset up...

Enterprise JavaBeans Technology

Extended Persistence Context in Stateful Session Beans

by Mahesh KannanThe Java Persistence Architecture, a part of theEnterprise JavaBeans 3.0 (EJB 3.0) specification,simplified the development of EJB applications using data persistence. A major simplification was theintroduction of the EntityManager interface for accessing a database and creating, removing, or updatingentities within a transaction. Entities are objects that represent data in a database. They are persistentin the sense that they exist even after the application that created them ends. To foster entity persistence anentity manager interacts with the persistence context, which the Java Persistence Architecture defines as:A set of managed entity instances in which for any persistent entity identity there is a unique entity instance.Within the persistence context, the entity instances and their lifecycle are managed by the entity manager.The Java Persistence Architecture also states that a container-managed persistence context, that is, a persistence contextwhose life cycle is managed automatically by the container, may be defined to have either a lifetime that is scopedto a single transaction or an extended lifetime that spans multiple transactions. The lifetime scope depends on thetype specified in the PersistenceContextType class when an entity manager is created.In the case of a container-managed persistence context that is scoped to a single transaction, the persistence contextends when an associated transaction commits or is rolled back through the Java Transaction API (JTA).By comparison, a container-managed persistence context that has an extended lifetime begins when a stateful sessionbean is created and ends only when the stateful session bean is removed from the container. The extended persistencecontext is said to be bound to the stateful session bean. Note that only stateful session beans can have a container-managed,extended entity manager.One of the important distinctions between a transaction-scoped persistence context and that of an extended persistencecontext is the state of the entities after a transaction completes. In the case of a transaction-scoped persistencecontext, the entities become detached, that is, they are no longer managed. In the case of an extended persistencecontext, the entities remain managed. In other words, all operations, such as persist, that are done outside ofa transaction are queued and committed when the persistence context is attached to a transaction (and when it commits).This makes an extended persistence context ideal for modeling a conversation with a user that spans many interactions.You can accomplish the same thing with a bean-managed transaction that spans the entire user conversation. You startthis transaction with the UserTransaction.begin() method. However, this alternate approach is morecomplicated than taking advantage of an extended persistence context.This Tech Tip illustrates an application that uses a stateful session bean and an entity manager with anextended persistence context. The application handles travel reservations -- it allows a user to book airplaneflight and rental car reservations for a trip.A sample package accompanies the tip.The code examples in the tip are taken from the source code of the sample (which is included in thepackage).A Trip Reservation ApplicationThe application for this tip presents a simple web page that allows a user to make trip reservations. A trip reservation involves booking airline or car reservations for the trip. A user makes a trip reservation byspecifying a departure and destination location, selecting the dates for the trip, and then choosing an airlineor a car. The user then selects the Book It button to confirm the booking of a rental car or airplaneflight, respectively. The user can make multiple bookings for the trip. The user then confirms his or herselections by clicking the Confirm button.If you examine the source code for the application, you'll notice that a servlet, ControllerServlet,presents the reservation web page. The servlet uses a stateful session bean,BookingControllerLocalBean, to maintain the conversational state of theapplication. The stateful session bean uses a container-managed extended persistence context to manage the entities.Note that the default transaction attribute for all methods other than confirmBooking()in the application is NOT_SUPPORTED.The following code in BookingControllerLocalBean injects a container-managed extended persistencescope: @PersistenceContext(type=PersistenceContextType.EXTENDED) private EntityManager em;Beginning a Trip ReservationThe servlet begins the trip reservation process by calling the startBooking() method inBookingControllerLocalBean. Here's the call in the servlet to the method: bookingController = (BookingControllerLocal) (new InitialContext()).lookup("java:comp/env/ejb/BookingController"); session.setAttribute("bc", bookingController); tripId = bookingController.startBooking();And here is the startBooking() method in BookingControllerLocalBean: public Trip startBooking() { this.trip = new Trip(); // Create a new Trip em.persist(trip); return trip(); //Return the Trip which is an Entity }Again note that because this application uses an extended persistence context, the entity Tripremains managed even though the methods are called without a transaction.Handling Flight and Car ReservationsWhen the user requests a flight or a car reservation, the servlet calls the doBooking(Booking b)method in BookingControllerLocalBean. This method calls the em.persist method tomake the entity persistent. The method then adds the Booking entity to the Trip entity as follows: trip.getBookings().add(b); b.setTrip(trip);Note that the doBooking() method is not called within a transaction. Because of that, the entitiesare not flushed to the database, but rather remain managed by the entity manager. This makes it possible to modifythe Booking object even after the doBooking() method is called. By comparison,if this application used a transaction-scoped entity manager , it would have to call em.merge() at thebeginning of the next transaction to again have the entity manager manage the entity. However, because the applicationuses an entity manager with extended persistence scope the entities remain managed even after a transaction commits.Here is the complete code for the doCarBooking() method: public void doBooking(Booking b) { em.persist(b); trip.getBookings().add(b); b.setTrip(trip); }Displaying the State of a Trip ReservationThe servlet displays all the Booking entities in a trip by calling the bean'sgetAllBooking() method in BookingControllerLocalBean. This method does not fetch data fromthe database. Instead it fetches the collection of Booking entities within the Tripentity.Here is the code for the getAllBooking() method. . public List<Booking>getAllBookings() { return trip.getBookings(); }Completing the Trip ReservationWhen the user clicks the Confirm button, the servlet calls the confirmTrip() method inBookingControllerLocalBean. This method doesn't do anything: @TransactionAttribute(TransactionAttributeType.REQUIRED) public void confirmTrip() { em.flush(); }However, because the method executes within a transaction, the container automatically associates the extendedpersistence manager with the transaction. When the method completes, the container commits the transaction and theentity manager flushes the entity's state to the database.Running the Sample CodeA sample package accompanies this tip.To install and run the sample:Download the sample package and extract its contents. You should see an enterprise archive namedtechtip3.ear.If you haven't already done so, download and installGlassFish v2.Start GlassFish v2 by entering the following command on a command line: <glassfish_install_dir>/bin/asadmin start-domainWhere <glassfish_install_dir> is the directory in which you installed GlassFish v2.Start the Java DB database server that is packaged with GlassFish v2 by entering the following command on a command line: <glassfish_install_dir>/bin/asadmin start-databaseWhere <glassfish_install_dir> is the directory in which you installed GlassFish v2.Deploy techtip3.ear in GlassFish v2. You can do this various ways. One way is toenter the following command on a command line: <glassfish_install_dir>/bin/asadmin deploy techtip3.earOpen your browser to the following URL: http://localhost:8080/techtip3-war/TripController.You should see the trip reservation web page.SummaryThis tip showed an example that uses a container-managed entity manager with an extended persistence contextto a handle a long conversation that spans multiple interactions with a user. The example also showed thatintermediate user interactions do not have to be handled within a transaction, and how this type of entity manageris flushed when the transaction completes.About the AuthorMahesh Kannan is member of the EJB container team. He has been involved with Java EE development for the last 7 years.----------------------------------------------------------------------------------------------------------------------------------------------------------------------------Connect and Participate With GlassFishTry GlassFish for a chance to win an iPhone. This sweepstakes ends on March 23, 2008. Submit your entry today.

by Mahesh Kannan The Java Persistence Architecture, a part of theEnterprise JavaBeans 3.0 (EJB 3.0) specification,simplified the development of EJB applications using data persistence. A major...

web services

Building Kerberos-Based Secure Services Using Metro

by Ashutosh ShahiMetro is a high performance,extensible, easy to use web service stack. It combines theJAX-WS reference implementationwith Project Tango. Project Tango,also called Web Services Interoperability Technology or WSIT, implements numerousWS-\* standards to enable interoperability with other implementations and to provideQuality of Service (QOS) features such as security, reliability, and transactionsupport. Metro is bundled as part ofSun Java System ApplicationServer 9.1. Metro also runs in other containers such as Tomcat.The March 2007 Tech Tip, Securing Web Services Using WSIT, focused on WSIT's support for web services security and showedhow to secure a web service using WSIT's features. It was followed by the October 2007 Tech Tip,TestingInteroperability Between Metro and .NET, which showed a sample that demonstrates interoperabilitybetween Metro and .NET. This Tech Tip builds on the March 2007 tip. It shows how to build secure webservices and clients using the Kerberos support in Metro. Kerberos support has been added tothe security support provided by WSIT for Metro 1.1. Future releases of Metro will continue toinclude this added support. The support for Kerberos security in WSIT is based on theWSS:KerberosToken Profile 1.1 implementation. You request Kerberos security in Metro usingWS-SecurityPolicy assertions -- these assertions are covered in the "Securing Web ServicesUsing WSIT" tip.A sampleapplication package accompanies this tip. The code examples in the tip are takenfrom the source code of the sample (which is included in the package). The sample application issimilar to the one used in the "Securing Web Services Using WSIT" tip. The major differenceis that the WS-SecurityPolicy assertions in the sample application for this tip specify Kerberos tokensand consequently the messages are secured using the Kerberos V5 protocol.Introduction to KerberosKerberos is a network authentication servicedeveloped as part of Project Athena at the Massachusetts Institute of Technology. The protocol is namedafter Cerberus, known in Greek mythology as the three-headed monstrous dog who guards Hades.Kerberos assumes that network connections, rather than servers, are the weak links in network security,and so interactions between hosts and clients should be encrypted. Kerberos uses a trusted third party,termed a Key Distribution Center (KDC), which consists of two separate logical parts: an AuthenticationServer (AS), and a Ticket Granting Server (TGS). The KDC maintains a database of secret keys. Each entityin the network, whether it's a client or a server, shares a secret key known only to itself and to the KDC.Knowledge of this key serves to prove an entity's identity.For communication between two entities such as a client and a service, the KDC generates a session keywhich the entities can use to secure their interactions. Figure 1 shows the steps takento secure a client's access to a service:Figure 1. Securing Client Access to a Service Using Kerberos A user enters a user name and password on the client. The client executes a one-way hash function onthe password to generate a secret key for the user. The client sends a cleartext request to the AS torequest a Ticket Granting Ticket (TGT). This TGT is later used by the client to request tickets for anyspecific service.The AS checks to see if the client is in its database. If the client is in the database, the ASgenerates a reply containing the following:A session key encrypted with the secret key of the user. The encrypted session key is kept in secretbetween the client and the TGS.A TGT encrypted using the secret key of the TGS.The client obtains the encrypted session key from the above message and decrypts it. This session keyis used for further communication with the TGS. Note that the client cannot decrypt the TGT because the TGTis encrypted using the TGS's secret key. When the client requests access to services, it sends a message tothe TGS composed of the following:The TGT obtained in Step 2 and the ID of the requested service.An authenticator that includes a client ID and timestamp.The authenticator is encrypted using the client/TGS session key.When it receives the message from the client, the TGS decrypts the TGT using its secret key. This givesthe TGS the client/TGS secret key. The TGS verifies the authenticator using this secret key. If the verificationis successful, the TGS sends the following to the client:A client-to-server ticket that includes the client ID, validity period, client/server session key, as wellas other information. The client-to-server ticket is encrypted using the service's secret key.The client/server session key encrypted with the client/TGS session key.The client decrypts the client/server session key, and now has enough information to authenticate itself tothe service. The client sends the following to the service for authentication:The encrypted client-to-server ticket.A new authenticator that includes the client ID and timestamp. The new authenticator is encrypted using theclient/server session key.The service decrypts the ticket using its own secret key and verifies the authenticator. If mutualauthentication is not enabled (this is discussed later in this tip), the server is now ready to provide therequested services to the client. Also, communication between the client and the service can be secured usingthis client-to-server secret key.Setting up KerberosThis tip assumes that you have Kerberos set up in a UNIX environment. If you need information on how to set upKerberos in the Solaris or Ubuntu Linux environments, see the following documents:Solaris 10: Installinga Kerberos KDCUbuntu Linux: Kerberos OnUbuntuNote that in a Windows environment you can set up a Kerberos KDC only on Window Server editions 2000 and 2003.The KDC is bundled in these editions with its own Kerberos implementation called Active Directory. You cannotinstall the MIT Kerberos KDC on Windows. A Windows XP system can act as a client of the Windows Server 2003 KDC.Alternatively, you can install a client module of MIT Kerberos for Windows -- seeKerberos for Windows Release 3.2.2.You can then use the client module to authenticate against a KDC that was set up on a UNIX system.After you set up Kerberos, make sure that the following DNS lookups to the KDC are working correctly. # nslookup [kdc_hostname] # nslookup [kdc_ip]For example, you might enter the following command: nslookup ashu07.india.sun.localIn response, you should see the IP address of your system, such as 129.158.229.84. Similarly, if youenter the following command: nslookup 129.158.229.84You should see the hostname of your KDC such as ashu07.india.sun.local. The idea here is that theDNS server is able to resolve the hostname of your KDC correctly.Next, add user accounts for the client and service that will be used in this tip, as follows:Create a user principal for your Kerberos account by entering the following command: # kadmin.local -q "addprinc admin/admin" [type password]The user principal is used to administer the Kerberos account.Add user accounts for the Kerberos client and service by entering the following commands: #kadmin.local -p admin/admin kadmin.local: addprinc -randkey -e "es128-cts-hmac-sha1-96:normal" [service_principal] (Ex of service_principal: websvc/service) kadmin.local: addprinc -e "aes128-cts-hmac-sha1-96:normal" [client_principal] [type password] (Ex of client_principal: testClient) kadmin.local: ktadd -e "aes128-cts-hmac-sha1-96:normal " [service_principal] kadmin.local: quitLogin to the Kerberos account that you created by entering the following command: #kinit [client_principal] [type password]Kerberos Security With Metro and GlassFishMetro 1.1 (and future releases) enables secure communication of SOAP messages between a clientand a service using Kerberos V5 protocol. The Introduction to Kerberos sectionpresented the steps in securing communication between a client and a service using Kerberos. Let'sexamine how those steps are performed using the Kerberos support in Metro.Step 1 and 2: A user (that is, the client) logs into the pertinent account, for example using thekinit command, or the client obtains a new TGT.Step 3: Before accessing a service, the client accesses the name of the service principal from a configurationfile named wsit-client.xml used in Metro (the wsit-client.xml file is discussedlater in the tip) and requests a ticket for the service principal from the KDC. Step 4: If the client has valid credentials, the KDC grants the client a ticket for the service and a secretkey to be used with the service.Step 5: All the communication in the previous steps takes place outside of SOAP messages. However at this pointcommunication is performed using SOAP messages. After the client has the ticket for the service and secret key,it sends the ticket and authenticator to the service enclosed in a BinarySecurityToken elementin the SOAP Security header. The client also secures any protected information in the SOAP message using thesecret key for this session.Step 6: The service decrypts the ticket to obtain the session key and verifies the authenticator. If theauthentication is successful, the service uses the secret key to verify the integrity or confidentiality ofthe protected parts of the message.Creating a Kerberos Token-Based SecurityPolicy for the ServiceTo enable security for a web service with WSIT, you need to create and attach a security policy to the Web ServicesDefinition Language (WSDL) file for the service. In general, there are two types of security policies you need tocreate for the web service: binding level policy and operational level policy. See theSecuring Web Services UsingWSIT tip for an explanation of these policies. The binding level policy shown in that tip needs to be changedto specify the use of Kerberos tokens. A Kerberos token here is the ticket and authenticator enclosed in theBinarySecurityToken element in the SOAP Security header as described in Step 5 above. <wsp:Policy wsu:Id="IFinancialService_policy"> <wsp:ExactlyOne> <wsp:All> <wsaws:Us"http://www.w3.org/2006/05/addressing/wsdl"/> <sp:SymmetricBinding> <wsp:Policy> <sp:ProtectionToken> <wsp:Policy> <sp:KerberosToken sp:IncludeToken= "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Once"> <wsp:Policy> <!--<sp:RequireDerivedKeys />--> <sp:WssGssKerberosV5ApReqToken11/> </wsp:Policy> </sp:KerberosToken> </wsp:Policy> </sp:ProtectionToken> ... <sp:AlgorithmSuite> <wsp:Policy> <sp:Basic128/> </wsp:Policy> </sp:AlgorithmSuite> </wsp:Policy> </sp:SymmetricBinding> ... <sc:KerberosConfig xmlns:sc= "http://schemas.sun.com/2006/03/wss/server" loginModule="KerberosServer"/> </wsp:All> </wsp:ExactlyOne> </wsp:Policy>Notice the <sp:KerberosToken> element. This is the Kerberos token assertion. It assertsthat the Kerberos token from the client is required to authenticate the client to the service and to protectthe message. The WssGssKerberosV5ApReqToken11 element specifies that GSS-wrapped Kerberos v5tokens will be used in the messages, as specified in theThe Kerberos Version 5 Generic Security ServiceApplication Program Interface (GSS-API) Mechanism: Version 2, RFC4121.Also notice the <sc:KerberosConfig> element. It specifies the name of theJava Authenticationand Authorization Service (JAAS) login module to use with Kerberos. This JAAS login module, which isKerberosServer in the example, is specified in the<AS_HOME>/domains/domain1/config/login.conf file as shown in theRunning the Sample Code section of the tip.The operation level policy used in the sample is same as in the "Securing Web Services Using WSIT" tip.It specifies that the body and addressing headers should be signed and the body should be encrypted.Deploying the Web ServiceYou can build and deploy a WSIT security-enabled web service in the same way as a regular JAX-WS based web service.For information on how to build a JAX-WS based web service, see the tipDeveloping Web Services Using JAX-WS.Creating the ClientAfter you deploy the web service, you can access it from a client program. The steps for building a client thataccesses a JAX-WS based web service are described in the tip Developing Web Services Using JAX-WS.However, to build a client that accesses a secured web service through WSIT, you need to configure security forthe client.Configuring Security Information For the ClientTo configure security for a client you specify security-related information in a file named wsit-client.xml.This file, which contains a WSDL document, specifies the local security policies to be used by the client and thepolicies obtained from the service WSDL.A standalone client, FinancialServiceClient.java, is provided in the sample application package thataccompanies this tip. Here is the security configuration for the client in the wsit-client.xml file: <wsp:Policy wsu:Id="ClientKerberosPolicy" xmlns:sc="http://schemas.sun.com/2006/03/wss/client" xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy" xmlns:scc="http://schemas.sun.com/ws/2006/05/sc/client"> <wsp:ExactlyOne> <wsp:All> <sc:KerberosConfig wspp:visibility="private" loginModule="KerberosClient" servicePrincipal="websvc/service@INDIA.SUN.COM" credentialDelegation="true" /> </wsp:All> </wsp:ExactlyOne> </wsp:Policy>This sample local policy has an element which specifies the name of the JAAS login moduleto be used with Kerberos on the client. The name is specified in the loginModule attribute. ThisJAAS login module, KerberosClient in the example, is specified in the<AS_HOME>/domains/domain1/config/login.conf file as shown in theRunning the Sample Code section of this tip. The servicePrincipal attributespecifies the name of the service principal for which the client should request a ticket from theKDC. The credentialDelegation element indicates whether the client credentials should be delegatedto the service -- in this example, it should. Credential delegation is useful if the server wants to initiateother security contexts on behalf of the client, something that's important for single sign-on ina multi-tier environment.Running the Sample CodeA sample packageaccompanies this tip. To install and run the sample:If you haven't already done so, download JDK 6 from theJava SE Downloads page and install it. The Kerberossupport in Metro works only with JDK 6 and later releases.If you haven't already done so, download the Java EE 5 SDK Update 4 from theJava EE Downloads page and install it.Download Metro 1.1 from the Metro Project site and follow the installationinstructions on theWSIT Documentation page.Set the WSIT_HOME system property as follows:Open the file <AS_HOME>/domains/domain1/config/domain.xml in a text editor,where <AS_HOME> is the installation directory in which you installed Java EE 5 SDK Update 4.Add the following JVM options to the file: <jvm-options>-DWSIT_HOME=${com.sun.aas.installRoot} </jvm-options> <jvm-options> -Dcom.sun.xml.ws.transport.http.HttpAdapter.dump=true </jvm-options> <jvm-options> -Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true </jvm-options>Specify the JAAS login modules to be used for Kerberos in the<AS_HOME>/domains/domain1/config/login.conf file, as follows: KerberosClient { com.sun.security.auth.module.Krb5LoginModule required useTicketCache=true; }; KerberosServer { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true keyTab="/etc/krb5.keytab" doNotPrompt=true storeKey=true principal="websvc/service@INDIA.SUN.LOCAL"; };You can give any names to the login modules, that is, instead of KerberosClient andKerberosServer. You need to refer to these names in the <sc:KerberosConfig>assertion in the WSDL file and in the wsit-client.xml file. Also edit the principal in KerberosServer to the service_principal that you created.Download the sample package for the tip and extract its contents. You should now see the newly extracteddirectory as <sample_install_dir>/wssec-kerb, where <sample_install_dir>is the directory in where you installed the sample package.Change to the wssec-kerb/src/fs directory. In the build.properties file setjava.home. to the location of the JDK on your system. Set glassfish.home to the installationdirectory of Java EE 5 SDK Update 4.Run the sample by entering the following command: ant run-sampleYou should see the following response: balance=1,000,000 Acknowledgement : successfully deposited.You can view the message flows by examining the log file for the application server in the<AS_HOME>/domains/domain1/logs directory.About the AuthorAshutosh Shahi is a member of the Web Services Security group at Sun Microsystems. He currently works onimplementation of WS-\* technologies related to security in the Metro web services stack from Sun. Beforejoining Sun, Ashutosh worked on the development of Apache Axis, an open source SOAP engine from Apache.----------------------------------------------------------------------------------------------------------------------------------------------------------------------------Connect and Participate With GlassFishTry GlassFish for a chance to win an iPhone. This sweepstakes ends on March 23, 2008. Submit your entry today.

by Ashutosh Shahi Metro is a high performance, extensible, easy to use web service stack. It combines theJAX-WS reference implementation with Project Tango. Project Tango,also called Web Services...

web services

Using JAX-WS with Maven

By Rama PulavarthiJava API for XML-Based Web Services, JAX-WS, is a fundamental technology for developing SOAP-based and RESTful Java Web services, and is a key part of project Metro, the web services technology stack in GlassFish. In addition to providing a high performance runtime, JAX-WS offers the wsimport and wsgen tools for creating web services and web service clients. The wsimport tool takes as input a Web Services Definition Language (WSDL) file and generates JAX-WS portable artifacts such as a service endpoint interface (SEI). The wsgen tool reads a web service endpoint class and generates all the required artifacts for web service deployment and invocation.You can access wsimport and wsgen through the GlassFish command line interface (CLI). You can also access the tools through Ant tasks or through a Maven plugin. In this tip, you'll learn how to use the JAX-WS Maven plugin to develop web services.MavenMaven is a highly configurable framework that you can use to manage various aspects of a project's life cycle, from building and deploying an application to document generation and project management. Maven, like Ant, is a very popular development tool due to its standardized project layout and dependency management mechanism. By following standard conventions for project layout and usingcommon defaults for building lifecycle phases such as compilation and packaging, you can create projects that are easy to understand and manage. Maven uses Project Object Model (POM) to describe project-related information. Unlike Ant, in which you need to define how projects are built and deployed, all Maven projects implicitly share a set of plugins for doing well-defined tasks such as building and packaging. These plugins can also be configured to change default behavior and change build order as needed.For more information about Maven, see Welcome to Maven and Building Web Applications with Maven 2.JAX-WS Maven PluginAs mentioned previously, JAX-WS provides two tools for web services development: wsimport and wsgen. The JAX-WS Maven plugin provides Maven adapters for these tools. The plugin offers the tools' functionality as two goals jaxws:wsimport and jaxws:wsgen. A goal is roughly the Maven equivalent of an Ant task. For each of the two goals, the plugin accepts all the configuration options that can be passed to corresponding CLI or Ant tasks. For the jaxws:wsimport goal, the plugin reads a WSDL file and generates Java classes required for web service creation, deployment, and invocation. The jaxws:wsimport goal is automatically executed within the life cycle phase generate-sources. By default, the plugin looks for WSDL files in the ${basedir}/src/wsdl directory. You can optionally specify the location of the WSDL files by configuring the wsdlLocation parameter. You can see descriptions of all the jaxws:wsimport configuration parameters on the JAX-WS commons page for jaxws:wsimport.For the jaxws:wsgen goal, the plugin reads an SEI class and generates all of the portable artifacts for the JAX-WS web service. The jaxws:wsgen goal is automatically executed within the life cycle phase process-classes. The plugin requires that you set the sei parameter for the jaxws:wsgen goal, which specifies the service endpoint implementation class name. The plugin can optionally generate a service description, that is a WSDL file, from the service endpoint implementation class if you specify the genWsdl parameter. However, the genWsdl parameter is optional -- the JAX-WS runtime can dynamically generate the WSDL after deployment. You can see descriptions of all the jaxws:wsgen parameters on the JAX-WS commons page for jaxws:wsgen.The jaxws:wsimport and jaxws:gen goals are executed implicitly when the corresponding life cycle phase is run. Optionally, the plugin can be explicitly run by specifying a goal such as jaxws-maven-plugin:wsimport. You can get more information about the Maven build life cycle phases and execution in Introduction to the Build Lifecycle. Why Use the JAX-WS Maven Plugin Instead of Ant?The advantage of using the JAX-WS Maven plugin instead of Ant tasks is that you don't have to get the JAX-WS dependencies, set up the classpath, and configure and invoke the tool tasks for compilation and packaging -- steps required by the Ant tasks. Maven automatically downloads all dependencies, makes them available to your application, and plugs them into the build life cycle phase. You might however need to do some tweaking of the configuration to make the plugins behave in a preferred way. For more information about the JAX-WS Maven plugin as well as other JAX-WS tools, see the Metro Tools page. JAX-WS Maven SampleNow that you've learned some of the basics of the JAX-WS Maven plugin, let's look at a sample application that uses the plugin to create a web service and web service client. The NetBeans IDE supports Maven 2 project management (Maven 2 is the current version of Maven) through a plugin. You can use the plugin within the IDE to create Maven-based projects, execute Maven commands by associating IDE actions to Maven goals, browse a repository, add dependencies, and do hot deployment of web applications with a few mouse clicks. You can also perform some of these tasks manually by running Maven and editing the configuration in the POM file. However, the NetBeans IDE offers an easier, more automated way to generate and configure POMs. Because of this the sample in this tip uses NetBeans IDE 6.0.A package that contains the code for the sample application accompanies the tip. As you build the sample application using the instructions below, you can compare the files that you create to those in the package.Initial SetupBefore you install and run the sample, you need to do some initial setup as follows:If you haven't already done so, download and install the following: NetBeans IDE 6.0GlassFish V2.GlassFish v2 is also available as part of the NetBeans IDE 6.0 Web and Java EE bundle.Also, to run the sample with JDK 6 prior to the JDK 6 Update 4 release, you need use the endorsed override mechanism by copying the jaxb-api.jar andjaxws-api.jar files to <java-home>/lib/endorsed, where <java-home> refers to the directory in which the runtime software is installed -- this is the top-level directory of the Java SE Runtime Environment or the jre directory in the JDK. If you run the sample with JDK 6 Update 4 or later, you do not need to use the override mechanism.  If you downloaded GlassFish v2 separately, register it in NetBeans as follows: Right-click on the Servers node in the Services window. Select Add Server. Leave the Server as Sun Java System Application Server. Click the Next button. Click the Browse button and browse to the location that you installed GlassFish V2. Click the Choose button. Click the Next button. Set the Admin Password to the default, adminadmin, unlessyou chose a different password for GlassFish v2. Click the Finish button. Install the Mevenide2-Netbeans plugin, which provides support in NetBeans for Maven 2 projects, as follows: Select Plugins from the Tools menu.Select the Available plugins tab in the Plugins window.Select the Maven plugin.Click the Install button.Creating the Project and SubprojectsIn this sample, you create a main project, that is, a parent project, named jaxws-maven-sample. The parent project has two subprojects: HelloService, for the web service, and HelloClient,for the web service client. Here is what the project structure looks like:   jaxws-maven-sample (POM Project)     helloservice (WAR project)     helloclient (JAR Project)To reduce redundancy, the parent project POM holds configuration parameters that are in common between HelloService and HelloClient. To create the project and subprojects, do thefollowing:Create the parent (POM project), jaxws-maven-sample. Select New Project from the File menu.Choose the Maven category then the Maven project.Click the Next button.Select the Maven Quickstart Project archetype (the default).On the next screen specify the following project settings, also known as Maven project coordinates:     - ProjectName: jaxws-maven-sample    - ProjectLocation: Specify a directory to contain the project, for example, Users/ramapulavarthi.    - Version: 1.0-SNAPSHOT    - GroupId: com.example.maven.jaxws    - Package: com.example.maven.jaxws  Click the Finish button to create the project.You should now see the project in NetBeans Projects window.   Change the project properties from jar to pom. Right-click the jaxws-maven-sample in the Projects window. Select the Properties option from the menu. In the General category, change the Packaging value from jar to pom.Click the OK button. Notice that the entry in the Projects window now shows jaxws-maven-sample (pom).Remove unwanted dependencies and files created by default.Because this is a POM project, it will have submodules instead of sources/tests. So you need to remove sourcesfrom the project. Also, there are no unit tests in this project so you need to remove any JUnit dependencies.  Click the Files tab (next to Projects tab).In the Files window, right-click the src directory below jaxws-maven-sample and choose Delete.In the Projects window, expand the TestLibraries node of jaxws-maven-sample, right-click on the junit-3.8.1.jar, and select Remove Dependency. Change the source to Java 5. You need Java 5 to create web services. However, the default is Java 1.4.  Right-click the jaxws-maven-sample in the Projects window. Select the Properties option from the menu. In the Sources category, change the Source/Binary Formatvalue from 1.4 to 1.5.Click the OK button.  If you examine the pom.xml file in the Project Files belowjaxws-maven-sample, you'll notice the configuration sourceand target values are changed to 1.5.  Create the subproject (WAR project), helloservice. Repeat the steps in step 1, "Create the parent (POM project),jaxws-maven-sample" except instead of selecting the Maven Quickstart Project archetype, select Maven WebApp archetype.Also specify the settings as follows:        - ProjectName: helloservice       - ProjectLocation: Specify the directory that contains the jaxws-maven-sample project, for example, /Users/ramapulavarthi/jaxws-maven-sample.       - Version: 1.0-SNAPSHOT       - GroupId: com.example.maven.jaxws       - Package: com.example.maven.jaxws.helloservice Click the Finish button to create the project. You should now see helloservice Maven Webapp (war) in the NetBeans Projects window. Notice that the pom.xml file for helloservice has a reference to the parent project, jaxws-maven-sample, and the pom.xml file for jaxws-maven-sample now specifies a module for helloservice.Remove unwanted dependencies and files for helloservice.  Click the Files tab (next to Projects tab).In the Files window, expand the src directory below helloservice Maven webapp, right-click the test directory and choose Delete.In the Projects window, expand the TestLibraries node of helloservice Maven webapp, right-click on junit-3.8.1.jar, and select Remove Dependency. Create the subproject (JAR project), helloclient. Repeat the steps in step 1, "Create the parent (POM project),jaxws-maven-sample" except specify the settings as follows:        - ProjectName: helloclient       - ProjectLocation: Specify the directory that contains the jaxws-maven-sample project, for example, /Users/ramapulavarthi/jaxws-maven-sample.       - Version: 1.0-SNAPSHOT       - GroupId: com.example.maven.jaxws       - Package: com.example.maven.jaxws.helloclient  Click the Finish button to create the project.You should now see helloclient (jar) in the NetBeans Projects window. Notice that the pom.xml file for helloclient has a reference to the parent project, jaxws-maven-sample, and the pom.xml file for jaxws-maven-sample now specifies a module for helloclient. Remove unwanted dependencies and files for helloclient. Click the Files tab (next to Projects tab).In the Files window, expand the src directory below helloclient, right-click the test directory and choose Delete.In the Projects window, expand the TestLibraries node of helloclient, right-click on junit-3.8.1.jar, and select Remove Dependency.Remove com.example.maven.jaxws.App.java from the SourcePackages directoryAdd JAX-WS JARs and RepositoriesNow that you've created the project and its subprojects, you need to couple them with needed JAX-WS jar files and repositories.Add a dependency on jaxws-rt.jar. Expand jaxws-maven-sample in the Projects window and right-click on Libraries.Select "Add Library..." and then enter the following information in the Add Library popup window: - GroupId: com.sun.xml.ws- ArtifactId: jaxws-rt- Version: 2.1.3- Scope: compile (The scope determines if the artifact is required for compile time or runtime).Click the OK button.Notice that the pom.xml file for jaxws-maven-sample now has a compile-time dependency on jaxws-rt.jar and specifies a scope of compile -- the jaxws-rt.jar file is required to be available for the service and client at runtime.GlassFish includes JAX-WS, so if you use GlassFish as the deployment container, you can set the Scope value to "provided". In this case, Maven creates a "skinny" WAR file, that is, it doesn't bundle the jax-ws jar files into the WAR.Add repository for the jax-ws jars. Maven uses this information to get the jaxws-maven-plugin and its dependent artifacts. Expand the Project Files node for jaxws-maven-sample and open the pom.xml file.Add the following repository information for downloading JAX-WS JARs:    <repositories>     <repository>       <id>maven-repository.dev.java.net</id>       <name>Java.net Repository for Maven 1</name>       <url>http://download.java.net/maven/1/</url>       <layout>legacy</layout>     </repository>     <repository>       <id>maven2-repository.dev.java.net</id>       <name>Java.net Repository for Maven 2</name>       <url>http://download.java.net/maven/2/</url>     </repository>   </repositories> This adds information for both the Maven 1 and Maven 2 repositories. (Some of the JAX-WS dependencies exist in both repositories.)  Add plugin repository information for the jaxws-maven-plugin to the pom.xml file, as follows:     <pluginRepositories>     <pluginRepository>       <id>maven2-repository.dev.java.net</id>       <url>http://download.java.net/maven/2/</url>     </pluginRepository>   </pluginRepositories> Because all the configuration specifications are in the pom.xml file of the parent project, the configuration is shared by the subprojects helloservice and helloclient.Build the Web ServiceAdd logic to helloservice. Right-click the SourcePackages node in the helloservice project. Select New, then Java Class.In the New Java Class window, specify:     - Class Name: Hello     - Package: com.example.maven.jaxws.helloservice Click the Finish button.Update the source code for the Hello class to annotate it as a WebService and include a method sayHello. The updatedsource code should look as follows:    package com.example.maven.jaxws.helloservice;   import javax.jws.WebService;   @WebService   public class Hello {     public String sayHello(String param) {     ;  return "Hello " + param;     }   } Run the jaxws-maven-plugin:wsgen on the SEI class. Open the pom.xml file of helloservice.Add the following code under the build section in the pom.xml file:         <plugins>              <plugin>        <groupId>org.codehaus.mojo≶/groupId>        <artifactId>jaxws-maven-plugin≶/artifactId>          <executions>            <execution>              <goals>                <goal>wsgen</goal>              </goals>              <configuration>              <sei>com.example.maven.jaxws.helloservice.Hello              </sei>              <!--for demo purpose only, the webapp does not-->              <!--need the generated wsdl files-->              <genWsdl>true</genWsdl>                         <keep>true≶/keep>              </configuration>            </execution>          </executions>        </plugin>      </plugins>  As mentioned earlier, the jaxws-maven-plugin:wsgen goal is automatically invoked during the process-classes life cycle phase. The <sei> element value com.example.maven.jaxws.helloservice.Hello will be passed to the goal as a parameter. Deploy the Web ServiceSpecify deployment information.  If you use GlassFish or any other Java EE 5 container to deploy the web service, change the default web.xml file to use version "2.5". To do that:     - Expand the Web Pages node in the helloservice project.    - Expand the WEB-INF node and select the web.xml file.    - Click the XML view button above the source editor windowto view the XML contents of the file.    - Replace the contents of the web.xml file with the following:    <web–app version="2.5"       xmlns="http://java.sun.com/xml/ns/javaee"       xmlns:xsi="http://www.w3.org/2001/XMLSchema–instance"       xsi:schemaLocation=       "http://java.sun.com/xml/ns/javaee       http://java.sun.com/xml/ns/javaee/web–app_2_5.xsd">     <welcome–file–list>     <welcome–file>index.jsp</welcome–file>     </welcome–file–list>   </web–app> Make sure to remove the <!DOCTYPE> element at the beginning of the file.     - Save the file.  Deploy the artifacts to GlassFish. Right-click the helloservice project and select Properties.In the Run category, specify the following:     - Server: GlassFish v2    - Context Path: /helloservice    - Click the OK button. You can also optionally check the Display Browser on Run checkbox and enter HelloService?wsdl in the Relative URL field. If you make these optional specifications, NetBeans will open a browser showing the helloservice WSDL after thehelloservice service is deployed.In response, the pom.xml file for helloservice is updated todeploy the artifacts to GlassFish.Run the ServiceRight-Click on helloservice and select Run. NetBeans runs Maven to build the web application and automatically deploys the WAR file to GlassFish. You can see the process in the NetBeans Output window. You can access the WSDL for the service to check if the service is successfully deployed. If you checked the Display Browser on Run checkbox as described in previous step, NetBeans opens a browser showing the WSDL of the deployed web service. If you did notcheck the Display Browser on Run checkbox, you can display theWSDL for the web service by opening http://localhost:8080/helloservice/HelloService?wsdl in your browser.Create a Client to Invoke the Web ServiceRun jaxws-maven-plugin:wsimport on the helloservice WSDL: Open the pom.xml file of helloclient.Add the following code to the pom.xml file:     <build>     <plugins>       <plugin>         <groupId>org.codehaus.mojo</groupId>           <artifactId>jaxws-maven-plugin</artifactId>           <executions>             <execution>               <goals>                 <goal>wsimport</goal>               </goals>               <configuration>                 <wsdlUrls>                   <wsdlUrl>         http://localhost:8080/helloservice/HelloService?wsdl                   </wsdlUrl>                 </wsdlUrls>             <packageName>com.example.maven.jaxws.helloclient             </packageName>               </configuration>             </execution>           </executions>       </plugin>     </plugins>   <bulid> The jaxws-maven-plugin:wsimport goal is run during the life cycle phase generate-sources. As you can see in the above configuration, wsimport is run on the WSDL located at http://localhost:8080/helloservice/HelloService?wsdl to generate Java classes in the com.example.maven.jaxws.helloclient package. Build the client. Right-click on the helloclient project and select build. Maven builds the project, runs wsimport, and generates all the Web Service artifacts that you see in the target folder. (To see the generated files, open then Files window and expand helloclient/target).Expand the Source packages node in the helloclient projectand right-click on com.example.maven.jaxws.helloclientSelect New, then Java class.Specify the class name as HelloClient.Click the Finish button.Update the HelloClient class with the following source code:    package com.example.maven.jaxws.helloclient;   public class HelloClient {     public static void main(String[] args) {     HelloService service = new HelloService();     Hello port= service.getHelloPort();     System.out.println(port.sayHello("Duke"));     }   } Associate the NetBeans IDE action "Run" to build the jar and run HelloClient. Right-click on helloclient and select Properties.Under Run category, enter com.example.maven.jaxws.helloclient.HelloClient as theMain class.Click the OK button.Run the ClientRight click on helloclient and choose Run. Maven runs wsimport on the WSDL file, creates Java classes, compiles HelloClient, and runs it. In the NetBeans Output window you should see the following result of the web service invocation:     Hello Duke SummaryUsing Maven you can easily create JAX-WS-based web services. Although this tip showed you how to do that using NetBeans, you can also can create JAX-WS-based web services using Maven manually, that is, without using NetBeans. To do so, use the mvn CLI and edit the pom files as needed. However, NetBeans makes it easier to use Maven for your projects and saves you from having to worry about configuration syntax.For more information about using Maven to create JAX-WS-based web services, see the Metro User's Guide.About the AuthorRama Pulavarthi is a Member of Technical Staff in the Java Web Services group at Sun Microsystems. He currently works on the development of the JAX-WS Reference Implementation. He previously lead the Software Quality Engineering effort for JAX-RPC.

By Rama Pulavarthi Java API for XML-Based Web Services, JAX-WS, is a fundamental technology for developing SOAP-based and RESTful Java Web services, and isa key part of project Metro, the web services...

Sun

Tech Tips Quiz

Over the years, the Enterprise Java Technologies Tech Tips have covered a wide variety of enterprise Java technology topics. Here's a short quiz that tests your knowledge of some topics covered in recent Tech Tips. You can find the answers at the end of the quiz.What is @UriTemplate?   The location of a template used for constructing a URI.A JAX-RS annotation that identifies the URI path for a RESTful web service resource.A JAXB annotation that serializes a RESTful web service URI parameter.None of the above. What type of security store is used for a GlassFish v2 application server whose domain is configured with the enterprise profile?   JKS NSSSLS The following tag appears in a JSP page for an application:    <jsfExt:scripts/>   What does the tag do? Includes the jsfExt script into the application. Includes the JavaServer Faces tag library into the application.Includes the script.aculo.us JavaScript library into the application.Includes the Dynamic Faces JavaScript library into the application. True or false, when a Java Persistence implementation runs in J2SE mode, an application is responsible for creating it's own entity managers? TrueFalse You want to create a simple web service to manage inventory. You create a class that can be used to model any inventoryobject that you want to expose through your web service, asfollows:     public abstract class Item implements Serializable {       private long id;       private String brand;       private String name;       private double price;        ...             }  Then you define classes for specific inventory objects suchas the following:     public class Glove extends Item {        private String size;       }   You then define the web service interface:         @WebService()         public class Inventory {             ...             public List<Item> getItems() {...}                     public boolean addItem(Item item) {...}             ...         }If you deploy the web service and then look at the generated WSDL and schema, would you see a definition for specific inventory items such as Glove? YesNoAnswers What is @UriTemplate? A JAX-RS annotation that identifies the URI path for a RESTful web service resource. The annotation identifies the URI path for which a resource class or class method associated with a RESTful web service will serve requests. For more information about RESTful web services and JAX-RS, see the November 16, 2007 Tech Tip Implementing RESTful Web Services in Java.What type of security store is used for a GlassFish v2 application server whose domain is configured with the enterprise profile? NSS. A GlassFish v2 profile presets configuration parameters for a particular type of use. The three profiles are developer, cluster, and enterprise. One of the configuration parameters is Security Store, which identifies how security and trust-related artifacts such as certificates and keys are stored. For the enterprise profile, the Security Store value is set to NSS, which stands for Network Security Services. For more information about security-related settings in GlassFish v2 profiles, see the November 30, 2007 Tech Tip Enabling the GlassFish v2 Application Server as an SSL Server. The following tag appears in a JSP page for an application:     <jsfExt:scripts/> What does the tag do?  Includes the Dynamic Faces JavaScript library into the application. <jsfExt:scripts/> is the standard tag to include for Dynamic Faces applications. You can see an example of a Dynamic Faces application in the October, 2007 Tech Tip Client-Side Polling With Dynamic Faces.True or false, when a Java Persistence implementation runs in J2SE mode, an application is responsible for creating it's own entity managers? True. You can use Java Persistence implementations that are compliant with the EJB 3.0 specification (JSR-220) in either of two modes: Java EE (formerly called "in-container")and J2SE (formerly called "out-of-container"). In Java EE mode, an EntityManager instance can be obtained through injection or through JNDI lookup. The lifecycle of an entity manager instance obtained in this way is managed by the container. In J2SE mode, the application is responsible for managing the lifecycle of its entity managers. An EntityManagerFactory can be used to create the entity manager. For more information about the two modes of running a Java Persistence implementation, as well as insights into optimizing the performance of a Java Persistence implementation, see the May 26, 2007 Tech Tip How to Get the Best Performance Out of a Java Persistence Implementation.You want to create a simple web service to manage inventory. You create a class that can be used to model any inventoryobject that you want to expose through your web service, asfollows:       public abstract class Item implements Serializable {          private long id;          private String brand;          private String name;          private double price;           ...            }   Then you define classes for specific inventory objects such as the following:       public class Glove extends Item {        private String size;        } You then define the web service interface:      @WebService()        public class Inventory {            ...            public List<Item> getItems() {...}                       public boolean addItem(Item item) {...}                ...        }  If you deploy the web service and then look at the generated WSDL and schema, would you see a definition for specific inventory items such as Glove? No. If you deployed this web service and then looked at the generated WSDL and schema, you would notice that only the Item type is defined -- there would be no mention of Glove or any other specific item that extends the abstract Item class. This is because when JAX-WS introspects the Inventory class there is no mention of classes for the specific items. To remedy that you can use the @XmlSeeAlso annotation and list the other classes that you want to expose through the Inventory web service. For more information about the @XmlSeeAlso annotation and how it can be used to enable support for type substitution, see the September 2007 Tech Tip Using Type Substitution With Web Services.

Over the years, the Enterprise Java Technologies Tech Tips have covered a wide variety of enterprise Java technology topics. Here's a short quiz that tests your knowledge of some topicscovered in...

security

Using SSL with GlassFish v2

By Kumar JayantiMost enterprise applications need to run in a secure environment. Transport Layer Security (TLS)/Secure Sockets Layer (SSL) is a point-to-point secure transport mechanism that can be used for authenticating messages exchanged between a clientand a server, and for ensuring message integrity and confidentiality. TLS/SSL (or in this tip, simply "SSL") meets the security requirements of most enterprise application environments, and is widely adopted.However to participate in SSL-secured message exchanges, the server needs to be enabled as an SSL server. This tip will show you how to enable the GlassFish v2 application server as an SSL server.In order to follow the steps, you need to understand some basic concepts in SSL such as keys and certificates and understand a concept in GlassFish v2 called profiles. Keys and CertificatesTwo important concepts in SSL are keys and certificates. Keysare used to establish trust and privacy in transactions betweenthe client and the server. SSL uses public key cryptography, which is based on key pairs. Key pairs contain one public keyand one private key. If data is encrypted with one key, it can be decrypted only with the other key of the pair.Certificates are used for authentication. To use SSL, the server must have an associated certificate for each client IP address with which it can connect. The certificate identifies the owner of the server site and provides related information. The certificate is digitally and cryptographically signed by its owner. For sites in which authentication is important, a certificate can be purchased from a well-known trusted certificate authority (CA). However, if authentication is not really a concern, a site can use a self-signed certificate. GlassFish v2 ProfilesGlassFish v2 supports various usage profiles. Each profile presets configuration parameters for the application server to optimize it for a particular type of use. The three profiles are developer, cluster, and enterprise. The developer profile optimizes GlassFish v2 for use in a development environment. This means that the configuration parameters support objectives such as fast startup, but don't support things like logging or session replication. The cluster profile sets configuration parameters that enable cluster creation and session replication. A cluster is a group of GlassFish v2 instances that can be managed and monitored as a single logical entity. The enterprise profile optimizes GlassFish v2 for a production environment. It supports things like logging and other security-related features.Enabling the GlassFish v2 Application Server as an SSL Server The steps to enable the GlassFish v2 as an SSL server depend on the profile used for the application server. Let's first examine the process if the developer profile is used. Then let's examine the process when the enterprise profile is used. When the Developer Profile is UsedRecall that a GlassFish v2 profile presets configuration parameters for a particular type of use. One of those parameters is Security Store, which identifies how security andtrust-related artifacts such as certificates and keys are stored. For the developer profile, the Security Store value isset to JKS. In this case, certificates and keys for the server are stored in a Java keystore file (keystore.jks) and certificates issued by trusted CAs are stored in a certificatesfile (cacerts.jks). When you install GlassFish v2, it creates a default self-signed certificate as the server certificate. However, if authentication is important in your site, you need to replace the self-signed certificate with a digitally-signed certificate from a CA. This section describes how to replace the self-signedcertificate, how to obtain a server certificate from a CA, and how to import the server certificate into the keystore. The steps described below use keytool, a key and certificate management tool. Keytool is available in various versions of the Java Platform, Standard Edition (Java SE) Development Kit (jdk). However Java SE 6 added some required functions to keytool. The instructions below are based on the jdk 6 version of keytool. For detailed information about keytool, see JDK Tools and Utilities.Here are the instructions for enabling GlassFish v2 as an SSL server when the application server is configured with the developer profile. Delete the default self-signed certificate by issuing thefollowing command (note that the commands in this and subsequent steps are shown on multiple lines for formatting purposes):       keytool -delete -alias s1as -keystore keystore.jks        -storepass <store_passwd>where <store_passwd> is the password for the keystore, for example, "mypass". Note that s1as is the default alias of the GlassFish v2 keystore. Generate a new key pair for the application server by issuing the following command:      keytool -genkeypair -keyalg <key_alg>       -keystore keystore.jks -validity <val_days> -alias s1as where <key_alg> is the algorithm to be used for generating the key pair, for example RSA, and <val_days> is the number of days that the certificate should be considered valid, for example, 365.Note that in addition to generating a key pair, the command wraps the public key into a self-signed certificate and stores the certificate and the private key in a new keystore entry identified by the alias. It's important to ensure that the name of the certificate matches the fully-qualified hostname of your site. If thenames don't match, clients connecting to the server will see a security alert stating that the name of the certificate does not match the name of the site. You should notice that the name of the default self-signed certificate matches the fully-qualified hostname. Generate a Certificate Signing Request (CSR) by issuing the following command:      keytool -certreq -alias s1as -file <certreq_file>       -keystore keystore.jks -storepass <store_passwd>where <certreq_file> is the file in which the CSR is stored,for example, s1as.csr, and <store_passwd> is the password for the keystore, for example, changeit. Submit the CSR to a CA such as VeriSign.In response, you should receive a signed server certificate. Make sure to import into your browser the CA certificate of the CA and any intermediate certificates indicated by the CA in the reply. Store the signed server certificate from the CA including the markers -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- into a file such as s1as.cert. Download the CA certificate and any intermediate CA certificates and store them in local files. Refer to your browser documentation on how to import the CA and intermediate CA certificates into the browser. The CA may provide information on how to import the CA certificates into various browsers such as Mozilla and Internet Explorer. Replace the original self-signed certificate with the certificate you obtained from the CA (stored in a file such as s1as.cert). You can use keytool to do this, as follows: keytool -import -v -alias s1as -file s1as.cert -keystore keystore.jks -storepass <store_passwd>When you import the certificate using the same original alias "s1as", keytool treats it as a command to replace the original certificate with the certificate obtained as reply to a CSR.After running the program, you should see that the certificate s1as in the GlassFish keystore is no longer the original self-signed certificate, but is now the response certificate from the CA. Here is an example that compares an original s1as certificate with a new s1as certificate obtained from VeriSign:Original s1as (self-signed):Owner: CN=KUMAR, OU=Sun Java System Application Server, O=SunMicrosystems, L=Santa Clara, ST=California, C=USIssuer: CN=KUMAR, OU=Sun Java System Application Server, O=Sun Microsystems, L=Santa Clara, ST=California, C=USSerial number: 472acd34Valid from: Fri Nov 02 12:39:40 GMT+05:30 2007 until: Mon Oct 30 12:39:40 GMT+05:30 2017New s1as (contains signed cert from CA):Owner: CN=KUMAR, OU=Terms of use at www.verisign.com/cps/testca (c)05, OU=Sun Java System Application Server, O=Sun Microsystems, L=Santa Clara, ST=California, C=USIssuer: CN=VeriSign Trial Secure Server Test CA, OU=Terms of use at https://www.verisign.com/cps/testca (c)05, OU="For TestPurposes Only. No assurances.", O="VeriSign, Inc.", C=USSerial number: 1375de18b223508c2cb0123059d5c440Valid from: Sun Nov 11 05:30:00 GMT+05:30 2007 until: Mon Nov 26 05:29:59 GMT+05:30 2007 After performing these steps, you can restart GlassFish v2 and use the signed server certificate issued by the CA. When the Cluster Profile is UsedYou perform the same steps to enable GlassFish v2 as an SSL server when the application server is configured with the cluster profile as you do for a developer profile. However, in this case you need to ensure that the same server key in replicated in all the application server instances in the cluster.When the Enterprise Profile is UsedThe Security Store parameter value for the enterprise profile isNSS, which stands for Network Security Services. In an NSS security infrastructure there is no JKS keystore and so there is no default GlassFish keystore. For the most part, the steps to enable the GlassFish v2 application server as an SSL server are the same when the enterprise profile is used as when the developer profile is used.However there are two differences. The first difference pertainsto the first step of the process. Because there is no JKS keystore, you start the process with an empty keystore (keystore.jks). The second difference pertains to the last stepof the process. Instead of importing the resulting signed certificate into the JKS keystore, you import it into the NSS store. In other words, to enable the GlassFish v2 applicationserver as an SSL server, you perform the same steps as in the When the Developer Profile is Used section, but you start with an empty keystore, and you replace step 6 in that section with the following steps:Export the private key for the server certificate from the keystore in Privacy Enhanced Mail (PEM) format by issuing the following command:       keyexport.bat -keyfile serverkey.pem       -keystore keystore.jks -storepass changeit -alias s1as The command invokes the keyexport utility. You can find thekeyexport in the keyexport package, which you can download from the XWSS downloads page in Project Metro In response you will be prompted for the keystore password. The keystore password is the same as the key password, so you can reply by simply pressing the return key.This creates a serverkey.pem file which contains the server private key under the markers -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY-----.Append the signed certificate reply from the CA, including the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- markers, to the servercert.pem file. Append the reply just below the END PRIVATE KEY marker. Convert the serverkey.pem file into a PKCS#12 file (a file with a .pfx extension). "PKCS" refers to a group of public key cryptography standards devised and published by RSA Security. PKCS#12 defines a file format commonly used to store private keys with accompanying public key certificates, protected with a password-based symmetric key.There are various tools you can use to convert the serverkey.pem file into a PKCS#12 file. One of them is the openssl tool. Here is the command to convert the file using openss1:      openssl pkcs12  -export  -in serverkey.pem -out s1as.pfxIn response, you will be prompted for the export password. Enter a password such as "changeit" or the GlassFish master password. The s1as.pfx file will now contain the required signed server certificate and the private key.Delete the original s1as self-signed entry, if it exists, by issuing the following command:       certutil -D -n s1as -d $AS_NSS_DBUse the pk12util utility to import the new s1as.pfx file into the NSS store by issuing the following command:      pk12util -i s1as.pfx -d $AS_NSS_DB pk12util is an NSS utility available inside the GlassFish installation template directory for the Enterprise Profile. The utility is used to import or export a PCKS#12 file to and from an NSS store.In response to the command, you will be prompted for the passwords for the NSS soft token and PKCS#12 file. Supply the appropriate passwords. You should then see the following message indicating that the import was successful:      pk12util: PKCS12 IMPORT SUCCESSFUL   There are two other cases to consider:The application server profile is the enterprise profile andthe server key pair is already in a PKCS#12 file. If there is already an entry in the store with alias s1as, all you have to do is perform step 4 as described in "When the Enterprise Profile is Used" to delete the original entry:     certutil -D -n s1as -d $AS_NSS_DB Then perform step 5 to import the new s1as.pfx file into the NSS store:      pk12util -i s1as.pfx -d $AS_NSS_DB If there is no entry in the store with alias s1as, simply perform step 5. The application server profile is the developer profile andthe server key pair is already in a PKCS#12 file. In this case, all you need to do is perform step 5 as described inWhen the Enterprise Profile is Used to delete the original s1as entry. Then use the pkcs12import utility to import the PCKS#12 file into the GlassFish keystore:     pkcs12import.sh -file s1as.pfx -alias s1as      -keystore keystore.jks -storepass changeit      -pass <exp_password>where <exp_password> is the password that was used when the PKCS#12 file was exported, for example, changeit.You can find the pkcs12import utility in the pkcs12import package, which you can download from the XWSS downloads page in Project MetroFor More InformationTo learn more about SSL with GlassFish see SSL and CRL Checking with GlassFish v2.Also see the following resources:Using JAX-WS-Based Web Services with SSLGlassfish with ECCSecuring Web Applications in Java EE 5Configuring Security in GlassFishInstalling and Configuring SSL Support in the Sun Java System Application Server Authentication (Java EE Blueprints) Enterprise Java Bean over SSLKey Management and PKCS#11 Tokens in Sun Java System Application Server 8.1No more 'unable to find valid certification path to requestedtarget'About the Author Kumar Jayanti is a staff engineer at Sun Microsystems and works in the Web Technologies and Standards team. In his current role, Kumar is the lead for the XML and Web Services Security implementation and has also recently taken over responsibilityfor the GlassFish security module. He has been involved with theweb services security effort at Sun since early 2004. Kumar holds an M.Tech degree in Computer Science from IIT Mumbai, India. His areas of interest include distributed computing, CORBA, XML, web services, and security.

By Kumar Jayanti Most enterprise applications need to run in a secure environment. Transport Layer Security (TLS)/Secure Sockets Layer (SSL) is a point-to-point secure transport mechanism that canbe...

web services

Implementing RESTful Web Services in Java

By Jakub Podlesak and Paul SandozThis Tech Tip will show you how to write RESTful web services in Java that conform to the JAX-RS: Java API for RESTful Web Services (JSR-311) specification and its reference implementation - Jersey. You'll learn some of the principles of Representational State Transfer (REST) and get introduced to JAX-RS and Jersey. The tip uses a sample application to demonstrate some of the JAX-RS concepts and techniques. You can obtain the sample by downloading the latest Jersey snapshot from the Jersey downloads page.The code examples in the tip are taken from the source code of the sample application (which is included in the download package).An Introduction to RESTful Web ServicesRepresentational State Transfer (REST) is a style of software architecture for distributed systems such as the World Wide Web. The term was introduced in the doctoral dissertation of Roy Fielding in 2000, and has since come into widespread use in the networking community. An important concept in REST is the existence of resources, each of which can be referred to using a global identifier, that is, a URI. In order to manipulate these resources, components of the network, clients and servers, communicate using a standardized interface such as HTTP and exchange representations of these resources.RESTful web services are services built using the RESTful architectural style. Building web services using the RESTful approach is emerging as a popular alternative to using SOAP-based technologies for deploying services on the Internet, due to its lightweight nature and the ability to transmit data directly over HTTP.RESTful Web Service PrinciplesA RESTful web service is based on the following principles:Resources and representations. Instead of providing just one endpoint for a particular web service and having that endpoint perform various operations, you provide access to resources. A resource is a single piece of your web application that you make accessible to clients. Because the resources you have are not transportable over the network, "providing them" means providing representations of their state. Addressability and connectedness. Resources have their representations, but providing representations of resources would be useless if you could not address them. In REST, every resource must have at least one address, that is, one URI. To address the resource, you simply specify the URI. This concept is called "addressability". By publishing your web application, you introduce many different URIs that areconnected to each other. Because of that connectedness, the only URI you need to give to your clients is one URI called the "bootstrap URI".Uniform interface. Even if you make resources available through URIs and representations to exchange between the client and server, it still does not allow you to establish communication. You need a communication protocol/interface to use. In a REST architecture, such an interface must be uniform. It means that whatever URI you access, the interface should be the same. For instance, on the World Wide Web no matter what URI (resource address) you enter, your web browser simply uses an HTTP GET method to retrieve a corresponding web page (resource representation) and displays it. Statelessness. Statelessness means that a web application is not responsible for keeping any information about the state of its clients. REST does not encompass the concept of HTTP sessions. The client is responsible for tracking its own actions (if it needs to). The service maintains its resources and provides a uniform interface to the clients. JAX-RS and JerseyJAX-RS provides a standardized API for building RESTful web services in Java. The API basically provides a set of annotations and associated classes and interfaces. Applying the annotations to Plain Old Java Objects (POJOs) enables you to expose web resources. The API is not yet complete. The final version should become part of Java EE 6. You can find more information about JAX-RS in the jsr311 project.Jersey is a reference implementation of JAX-RS. You can find downloadable distributions of Jersey on the Jersey project downloads page.If you select the latest Jersey snapshot and unzip it, you will see that the Jersey implementation is bundled with several examples demonstrating its use. Let's examine one of those examples.An Example of JAX-RS in Use: The Bookmark ApplicationOne of the examples distributed with Jersey is a bookmark application. You'll find it in the examples/Bookmark subdirectory. The application uses the JAX-RS API to maintain information about bookmarks saved by users. If you run the application and specify a specific user, the application returns data similar to the following:   {sdesc":"test desc","userid":"testuserid","uri":   "http://java.sun.com","ldesc":"long test description"}Notice that the application returns the data in JavaScript Object Notation (JSON) format.If you navigate below the examples/Bookmark subdirectory to the resources subdirectory, you'll find the following resourcesfor the application:UsersResource: Represents a list of users UserResource: Represents a specific user BookmarksResource: Represents a list of bookmarks for a specific user BookmarkResource: Represents a specific bookmark Recall that to address a resource in REST you specify its URI. However, to communicate with a resource, you also need to specify a communication protocol such as HTTP. Here are the URIs and HTTP methods that correspond to the resources in the Bookmark application:  ResourceURI PathHTTP Methods UsersResource/usersGET UserResource/users/{userid}GET, PUT, DELETE BookmarksResource/users/{userid}/bookmarksGET, POST BookmarkResource/users/{userid}/bookmarks/{bmid}GET, PUT, DELETE  To understand some of the basics of the JAX-RS, let's look at two of these resources: UsersResource and UserResource.UsersResourceHere is a snippet of source code from the UsersResource class:   @UriTemplate("/users/")   public class UsersResource {            @HttpContext UriInfo uriInfo;           @PersistenceUnit(unitName = "BookmarkPU")       EntityManagerFactory emf;       /\*\* Creates a new instance of Users \*/       public UsersResource() {       }           public List<UserEntity> getUsers() {           return emf.createEntityManager().createQuery(                  "SELECT u from UserEntity u").getResultList();       }           @UriTemplate("{userid}/")       public UserResource getUser(@UriParam("userid")               String userid) {           return new UserResource(                  uriInfo, emf.createEntityManager(), userid);       }       @HttpMethod("GET")       @ProduceMime("application/json")       public JSONArray getUsersAsJsonArray() {           JSONArray uriArray = new JSONArray();           UriBuilder ub = null;           for (UserEntity userEntity : getUsers()) {               ub = (ub == null) ?                       uriInfo.getBuilder() : ub.clone();               URI userUri = ub.                       path(userEntity.getUserid()).                       build();               uriArray.put(userUri.toString());           }           return uriArray;       }   }Notice that the UsersResource class is annotated by the@UriTemplate("/users/") annotation. @UriTemplate is a JAX-RS annotation that identifies the URI path for the resource. Herethe annotation identifies the URI path as /users/:   @UriTemplate("/users/")Annotating the class with a @UriTemplate annotation makes the class a "Root resource class." It also means that for client requests that access the /users/ URI path, this resource is responsible for providing appropriate responses. Note too that the /users/ URI path is the bootstrap URI path for the entireBookmark web application.Another JSR-311 annotation in the UsersResource class is @HttpContext.    @HttpContext UriInfo uriInfo;This annotation injects information into a class field or method parameter. In the UsersResource class, @HttpContext injects information about the URI into the uriInfo variable, which is then available to provide pertinent information about the URI. UsersResource MethodsThe UsersResource class has two methods, getUser and getUsersAsJsonArray. For the moment, let's skip getUser and focus on getUsersAsJsonArray. The getUsersAsJsonArray method returns the URIs for all user resources. Notice that themethod is annotated with two JSR 311 annotations: @HttpMethod and @ProduceMime. The @HttpMethod annotation indicates that the annotated method should be used to handle HTTP requests. The annotation also specifies the type of HTTP request to which the method will respond. In this example, the annotation specifies that the getUsersAsJsonArray method serves HTTP GET requests.    @HttpMethod("GET")Methods like this that serve REST requests are called "Resource methods". The @ProduceMime annotation specifies the MIME types that a method can produce. Here, the annotation specifies that the getUsersAsJsonArray method returns a JSONArray object containing an array of URIs for all existing user resources.   @ProduceMime("application/json")Get Users Resources The JSON array object that the method returns to a client might look like this:   ["http://localhost:8080/Bookmark/resources/users/joe",    "http://localhost:8080/Bookmark/resources/users/mary"]This JSON array contains URIs, that is, links, to two user resources, joe and mary. The getUser method gets information about a specific user. Forexample, if a client wants to get information about user joe, the client accesses the resource at its URI -- in this case, http://localhost:8080/Bookmark/resources/users/joe. Recall thatthe UsersResource class serves all requests for paths beginning with /users/, including the URI path for joe, that is, /users/joe. Here it's important that the getUser method is annotated with @UriTemplate("{userid}/"). This makes the method a "Sub-resource locator". Also the getUser method is annotated with @UriParam. As a result, when the getUser method is invoked, a userid from the current request URI path is injected into the userid parameter. Notice that there is no @HttpMethod annotation associated with the getUser method. Because of that, the output of the method is considered a Resource class object. This means that request processing will be delegated to the Resource class and appropriate @HttpMethod-annotated methods will be looked up there. Because the getUser method returns a UserResource object:   public UserResource getUser(@UriParam("userid")                  String userid) {           return new UserResource(...)an appropriate method in the UserResource class is invoked.Get User Resources UserResourceAs just mentioned, request processing for the getUser method in the UsersResource class is delegated to an appropriate method in a newly instantiated UserResource object. Here is a snippet of code from the UserResource class showing one of its methods, getUser.   @HttpMethod("GET")   @ProduceMime("application/json")   public JSONObject getUser() throws JSONException {       if (null == userEntity) {           throw new NotFoundException(                  "userid " + userid + "does not exist!");       }       return new JSONObject()           .put("userid", userEntity.getUserid())           .put("username", userEntity.getUsername())           .put("email", userEntity.getEmail())           .put("password", userEntity.getPassword())           .put("bookmarks",                 uriInfo.getBuilder().path("bookmarks").build());    } Notice that this method also is annotated by @HttpMethod("GET")and @ProduceMime("application/json"). Here the getUsers method serves HTTP GET requests and returns a JSONObject object. The JSONObject object contains a representation of a particular user, for instance, the representation of the user whose userid is joe.You're encouraged to examine the rest of the source code in UserResource. You'll notice additional JSR 311 annotations, suchas @ConsumeMime, which identifies the MIME types that a method can accept.Building and Deploying the Sample CodeThe sample code for the tip is available as a NetBeans project.You can build an deploy the sample from the NetBeans IDE or from the command line. In either case: If you haven't already done so, download and install GlassFish V2. Download the latest Jersey snapshot from the Jersey downloads page and extract its contents. You should now see the newly extracted directory as <sample_install_dir>/jersey, where <sample_install_dir> is the directory where you installed the sample application. For example, if you extracted the contents to C:\\ on a Windows machine, then your newly created directory should be at C:\\jersey. Building and Deploying the Sample Code in NetBeansIf you haven't already done so, download and install the NetBeans 5.5.1 IDE.Start the NetBeans IDE. If you haven't already done so, register GlassFish V2 in NetBeans as follows: Right click on Servers node in the Runtime window.Select Add Server.Leave the Server as Sun Java System Application Server.Click the Next button.Click the Browse button and browse to the location that you installed GlassFish V2.Click the Choose button.Click the Next button.Set the Admin Password to the default, adminadmin, unless you chose a different password for GlassFish.Click the Finish button. Open the Bookmark project as follows:Select Open Project from the File menu.Browse to the Bookmark subdirectory.Click the Open Project Folder button. Build and deploy the Bookmark project as follows:Right click the Bookmark project node in the Projects window.Select Deploy Project or press F6 (Run Main Project).Building and Deploying the Sample Code From the Command LineSet the AS_HOME environment variable to the GlassFish v2 installation directory, for example, (here shown in bash syntax):      export AS_HOME= <GF_install_dir>where <GF_install_dir> is the directory where you installed GlassFish v2.Navigate below the <sample_install_dir>/jersey directory to the /examples/Bookmark directory. Build the Bookmark application by entering the following command on the command line (here shown in bash syntax):      AS_HOME/lib/ant/bin/ant run-on-glassfishRunning the Sample CodeYou can run the deployed Bookmark application as follows using Curl, a command line HTTP tool.If you haven't already done so, download Curl.Add a new user by entering the following command on the command line (note that the commands in this and subsequentsteps are shown on multiple lines for formatting purposes):      curl -i --data "{\\"userid\\":\\"techtip\\",\\"username\\":      \\"TechTip User\\",\\"email\\":\\"techtip@example.com\\",      \\"password\\":\\"TEST\\"}" -H Content-type:application/json       -X PUT       http://localhost:8080/Bookmark/resources/users/techtip/In response, an HTTP GET request is dispatched to the getUser method in the UsersResource class, which instantiates a new UserResource object. The request is further dispatched to theputUser method.You should see output similar to the following:      HTTP/1.1 204 No Content      X-Powered-By: Servlet/2.5      Server: Sun Java System Application Server 9.1_01      Date: Thu, 01 Nov 2007 14:31:53 GMTGet a list of users by entering the following command on the command line:      curl -i -X GET       http://localhost:8080/Bookmark/resources/users/ This invokes the getUsersListAsJson method of the UsersResource class.You should see output similar to the following:      HTTP/1.1 200 OK      X-Powered-By: Servlet/2.5      Server: Sun Java System Application Server 9.1_01      Content-Type: application/json      Transfer-Encoding: chunked      Date: Thu, 01 Nov 2007 14:34:07 GMT      ["http:\\/\\/localhost:8080\\/Bookmark\\/resources\\/users\\      /techtip"]Get the representation of a user by entering the following command on the command line :      curl -i -X GET       http://localhost:8080/Bookmark/resources/users/techtip/ The resulting actions here are similar to those for step 2.You should see output similar to the following:      HTTP/1.1 200 OK      X-Powered-By: Servlet/2.5      Server: Sun Java System Application Server 9.1_01      Content-Type: application/json      Transfer-Encoding: chunked      Date: Thu, 01 Nov 2007 14:35:38 GMT      {"userid":"techtip","username":"TechTip User",      "email":"techtip@example.com","password":"TEST",      "bookmarks":"http:\\/\\/localhost:8080\\/Bookmark\\/resources      \\/users\\/techtip\\/bookmarks"}SummaryThis tip demonstrated how you can write RESTful web services in Java that conform to the JAX-RS: Java API for RESTful Web Services (JSR-311) specification. You can learn more about JAX-RS in the jsr311 project. Youcan learn more about Jersey, the reference implementation of JAX-RS, in the Jersey project.About the AuthorsJakub Podlesak is a member of the Jersey project team. Previously, he participated in the development of Metro, the GlassFish v2 web services stack, as a member of the WS-Policy team.Paul Sandoz is the co-spec lead and implementation lead for JSR 311: Java API for RESTful Web Services. He has participated in the W3C, ISO, and ITU-T standards organizations and contributed various performance-related technologies and improvements to the GlassFish web services stack, particularly in standardization, implementation, integration, and interoperability of Fast Infoset.

By Jakub Podlesak and Paul Sandoz This Tech Tip will show you how to write RESTful web services in Java that conform to the JAX-RS: Java API for RESTful Web Services (JSR-311) specificationand its...

Sun

Testing Interoperability Between Metro and .NET

By Harold CarrThe March 2007 Tech Tip, Securing Web Services Using WSIT introduced Web Services Interoperability Technology (WSIT), an implementation of open web services technologies that enables interoperability between Java EE and .NET. WSIT along with Java API for XML-Based Services (JAX-WS) comprise the stack of web services technologies in GlassFish v2. The web services stack in GlassFish v2 is called Project Metro or Metro for short. Metro is built into Sun Java System Application Server 9.1. Metro also runs in other containers such as Tomcat.WSIT, also called Project Tango, includes features that enable advanced web service interoperability with the .NET Windows Communication Foundation (WCF), a set of technologies for building and running connected systems. WSIT also addresses key aspects of web services interoperability such as reliable messaging, transaction handling, and security. What this means is that any combination of Metro-based and WCF-based clients and services can interoperate with support for reliable messaging, transaction handling, and security.To ensure that the stack of WCF and Metro technologies interoperate properly and provide the proper support, Microsoft and Sun engineers run comprehensive interoperability tests called "plug-fests". You can find out more about the plug-fests,including the scenarios that are tested, by viewing the Web Services Interoperability Plug-Fest Home Page. All tests pass in the current levels of .NET and Metro: .NET 3.0 and Metro 1.0. In this tip, you'll build and run an interoperability test in which a Metro-based client communicates with a WCF-based service. A package that contains the code for the interoperability testaccompanies the tip. The code examples in the tip are taken from the source code of the sample (which is included in the package). A Reliable One-Way Interoperability TestThe interoperability test you'll build and run in this tip is a "reliable one-way test." This type of test is described in "Scenario #1.1. One-Way Anonymous Client" in the document WCF(Indigo) Introperability Lab: Reliable Messaging. This is a typical enterprise use case where a client sends data to a service for processing but does not wait for a response -- that's why it's called "One-Way". However, the client wants assurances that the messages are received by the service. The message flow in this test is as follows:Reliable Messaging Operation The client initiates the establishment of a reliable communication channel by sending a CreateSequence protocol message. The service creates a sequence identifier to uniquely identify the reliable channel. The service returns this identifier in a CreateSequenceResponse protocol message.The client sends three application messages. Each of these messages is accompanied with header information containing the sequence identifier for the channel and a message number identifying the message. For each application message received, the service responds with a SequenceAcknowledgement identifying what messages have been received. The service does this without having to wait for the business logic to complete processing.If the client sees that some of the messages it sent have not been received, it retransmits those messages. (This situationis not tested in this tip.)The client closes the channel when the channel is no longer needed. This causes a LastMessage protocol messages to be sent. The service responds with a SequenceAcknowledgement protocol message indicating which messages have been received. Again, if the client sees that some of the messages it sent have not been received, it resends those messages. This is followed by another LastMessage. The LastMessage-resend sequence repeats until all messages have been received by the service. (That is not exercised in this tip.) The client sends a TerminateSequence protocol message.The service responds with an HTTP 202 response indicating thatthe request has been accepted for processing. Metro-Based Client Let's start by creating the Metro-based client. You can view the source code for the client in the file ReliableOneWay.java. Hereis a snippet of the source code in that file:   package reliableoneway.client;      import org.tempuri.IPing;   import org.tempuri.PingService;      public class ReliableOneWay {          public ReliableOneWay() {}              public static void main(final String[] args)        {        try {                    PingService service = new PingService();            IPing port = service.getCustomBindingIPing();                        msg(null, "BEFORE FIRST MESSAGE");                        msg(port, "FIRST MESSAGE");            msg(port, "SECOND MESSAGE");            msg(port, "THIRD MESSAGE");                        msg(null, "TERMINATE");                        ((com.sun.xml.ws.Closeable)port).close(); Using a reliable messaging (RM)-based web service is no different than using any SOAP-based web service. First you create a proxy to the service (see the section Running wsimport). Here, the service is PingService, which isdefined in the WSDL (see the section WSDL). Then you obtain a port defined in that service, in this case, CustomBindingIPing. Then you can send application messages to that service by calling the ping method on the port. Here the method msg calls port.ping(String) when port is not null. Inthis example, three messages are sent.These steps are the same steps you would take to use any SOAP-based web service. The one additional step is calling close on the port. This signals Metro to terminate the RM channel if the service is using RM. In general, it's a good idea to close ports when they are no longer needed. This enables Metro to reclaim any resources used by that port.WSDLYou generate the PingService proxy from the Web Service Definition Language (WSDL) file for the service. You can find the WSDL for the service by going to the Web Services Interoperability Plug-Fest Home Page. Click on the "RM Endpoints (WS-Addressing 1.0)" link. Then click on the "OneWay.svc" link. The address of the WSDL is http://131.107.72.15/ReliableMessaging_Service_WSAddressing10_Indigo/OneWay.svc?wsdl.The WSDL file is quite large because it is used for other test scenarios besides scenario 1.1, that is, scenarios that involve security. The port that this tip uses is named CustomBinding_IPing. It references the following policy binding:   <wsp:Policy wsu:Id="CustomBinding_IPing_policy">     <wsp:ExactlyOne>       <wsp:All>         <wsrm:RMAssertion>           <wsrm:InactivityTimeout Milliseconds="600000"/>           <wsrm:AcknowledgementInterval Milliseconds="200"/>         </wsrm:RMAssertion>         <wsaw:UsingAddressing/>       </wsp:All>     </wsp:ExactlyOne>   </wsp:Policy>  The RMASssertion in the policy binding specifies an RM policy assertion for the service. Within the assertion, the InactivityTimeout parameter sets then interval of time that the service remains inactive before closing. The AcknowledgementInterval parameter sets the interval of time that a destination waits before sending an acknowledgment to the message source on reliable channels. You can find out more about RM policy assertions in the WS-ReliableMessaging Policy specification. The main point here is that including the RMAssertion in the WSDL and then referencing it in the CustomBinding_IPing binding thatis used in the CustomBinding_IPing port causes operations on that port to use reliable messaging. The Structure of the TestIn this tip, you'll use ant to create the proxy, compile the code, and run the client test. You can also use NetBeans -- formore details, see the WSIT Tutorial.If you haven't already done so, download and install GlassFish v2. Then download the sample application for the tip and extract its contents. You should now see the newly extracted directory as <sample_install_dir>/interop, where <sample_install_dir> is the directory where you installed the sample application. For example, if you extracted the contents to C:\\ on a Windows machine, then your newly created directory should be at C:\\interop. Although this tip demonstrates only one scenario, the directory structure below the interop directory is set up such that common artifacts are factored out to be used with other tests. The directory structure is as follows:   common.xml  rm            build.xml       netbeans           ReliableOneWayService               ...       src           reliableoneway               build.props               build.xml               client                   ReliableOneWay.java                   ...               server                   etc                       EchoServiceRMCustomOnly.wsdl                       ReliableOneWay.xsdAt the top level of the directory structure, the build.xml file imports common.xml, where the real action takes place, and defines one target: run-reliableoneway. The run-reliableonewayfile cleans the build directory. It then:Runs wsimportCompiles the generated code and the ReliableOneWay.java codeRuns the testRunning wsimportHere is the snippet of code in the build.xml file that runs wsimport:   <target name="run-reliableoneway">                <ant target="run-wsimport"              antfile="src/reliableoneway/build.xml"              inheritall="false"/>Notice that it uses the build.xml file in the rm/src/reliableoneway directory. That file, in turn, uses thebuild.props file in the rm/src/reliableoneway directory. Here isthe contents of build.props:   test.wsdl=    http://131.107.72.15/ReliableMessaging_Service_ ...       client.dir=client   className=reliableoneway.client.ReliableOneWayThe build.props file is a property file that defines test.wsdlto be the location of the WSDL file of the service. It also sets two other parameters used by common.xml so it can be used for other tests that are not covered in this tip. The build.xml file in the rm/src/reliableoneway directory then uses the run-wsimport target from the common.xml file.The wsimport task fetches the WSDL file specified in parameter test.wsdl. It then generates the proxy code into the rm/build/classes/org/tempuri directory, and the data schema class into the rm/build/classes/com/microsoft/schemas/_2003/_10/serialization directory. This class is large because it is a superset of all data used by all the interoperability test scenarios.Compiling the Code and Running the TestThe final two steps in the run-reliableoneway target are:   <ant target="compile"         antfile="src/reliableoneway/build.xml"         inheritall="false"/>   <ant target="run-tests"         antfile="src/reliableoneway/build.xml"         inheritall="false"/>The compile step runs the Java Programming Language compiler, javac, on the developer-written code, ReliableOneWay.java. The run-tests step executes the main test class as specified in the className parameter set in build.props file. In this case, className is set to reliableoneway.client.ReliableOneWay.Note that sysproperty is set in the run-tests target of the common.xml file.    <sysproperty    key="com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump"    value="true"/>This enables the client to send and receive messages.Setting Environment VariablesFour ant parameters are set from environment variables (here shown in bash syntax):   export PROXY_HOST=-DproxyHost=my.proxy.example.com   export PROXY_PORT=-DproxyPort=8765   export METRO_HOME=/glassfish/b58g   export TEST_HOME=~/metro-wcf-interop-tests/rmIf you are not behind a firewall then explicitly set PROXY_* to nothing:   export PROXY_HOST=   export PROXY_PORT=Set METRO_HOME to the top-level installation direction of GlassFish. That setting is used to locate Metro JAR files such as webservices-rt.jar and webservices-tools.jar in $METRO_HOME/lib. (If you are using Tomcat or another web container you need to update common.xml to correctly reference the location of the Metro JAR files.) Executing the TestIf you haven't already done so, start GlassFish by entering the following command:   $METRO_HOME/bin/asadmin start-domain domain1Then change to the $TEST_HOME directory and enter the following command on the command line:   ant  Note: This test is designed to run with JDK 5. If you want to run the test with JDK6, you need to use the Java Endorsed Standards Override Mechanism. Test Results The output of the test should look similar to the content in the example-output-wcf-endpoint.txt file in the rm/src/reliableoneway/client directory.You can ignore all the WARNING messages at the beginning of the test run, such as the following:    [java] WARNING: WSP0075: Policy assertion     "{http://docs.oasis-open.org/ws-rx/wsrmp/200702}RMAssertion"     was evaluated as "UNKNOWN".These warnings are from the numerous policies for bindings in the WSDL that are not used in this test. Similarly, you can ignore the non-standard SOAP 1.2 binding warning messages in the run-wsimport step.In the output, search for BEFORE FIRST MESSAGE. This is printed to the console just before the first invocation of port.ping. When port.ping is called, the RM infrastructure holds the application message back -- it first establishes a reliable channel by sending a CreateSequence protocol message.    Content-Type: application/soap+xml;charset="utf-8";   action="http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence"The CreateSequenceResponse protocol message returned from the service contains an Identifier that will be used to identify the reliable channel.After the reliable channel is established, the application message is sent containing <Text>FIRST MESSAGE</Text> in the Body element. The header contains a Sequence element that contains the reliable channel Identifier along with a MessageNumber, in this case the number 1.   <S:Envelope xmlns:..."><S:Header>...   <ns2:MessageNumber>1</ns2:MessageNumber>...   </S:Header>...<Text>FIRST MESSAGE</Text>...   </S:Envelope>Because this is a oneway message, the response to this message contains an empty Body. The header contains a SequenceAcknowledgement element that contains the Identifier and an AcknowledgementRange with attributes Lower and Upper, in this case the numbers 1 and 1 respectively.    <s:Envelope xmlns:...><s:Header>...   <r:SequenceAcknowledgement>   <r:Identifier>urn:...</r:Identifier>   <r:AcknowledgementRange Lower="1" Upper="1"/>...   </r:SequenceAcknowledgement>...   </r:SequenceAcknowledgement>This means the lowest message number received by the service was 1 and the highest message number was 1. When there are gaps in the acknowledgement range the client RM infrastructure resends lost messages. It releases message copies (for garbage collection) after those messages have been acknowledged.Two more application messages are sent with MessageNumbers 2 and 3 respectively.   <S:Envelope xmlns:...><S:Header>...   <ns2:MessageNumber>2</ns2:MessageNumber>...   </S:Header>...><Text>SECOND MESSAGE</Text>...   </S:Envelope>      <S:Envelope xmlns:...><S:Header>...   <ns2:MessageNumber>3</ns2:MessageNumber>...   </S:Header>...<Text>THIRD MESSAGE</Text>...   </S:Envelope>The responses contain AcknowledgementRanges with Lower/Upper attributes 1/2 and 1/3 respectively.TERMINATE is printed to the console then the port.close() is called. This causes the RM infrastructure to send a message with an empty Body. The header of this message contains a Sequence element with the Identifier and a MessageNumber of 4. The header also contains an Action element specifying LastMessage to let the service know the reliable channel is going to be closed.   <S:Envelope xmlns:...><S:Header>...   <ns2:MessageNumber>4</ns2:MessageNumber>   <ns2:LastMessage/>...   </ns2:Sequence>...   <Action xmlns=...">   http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage   </Action>...The service responds with a SequenceAcknowledgement containing AcknowledgementRange 1/4 indicating all messages have been received.    <s:Envelope xmlns:...><s:Header>   <r:SequenceAcknowledgement>...>   <r:AcknowledgementRange Lower="1" Upper="4"/>...   </r:SequenceAcknowledgement>...   </s:Envelope>If messages are missing the client resends them. After the client RM infrastructure sends LastMessage and receives a SequenceAcknowledgement response indicating that all messages have been received, it sends a message with an Action header element containing TerminateSequence.     Content-Type: application/soap+xml;charset="utf-8";    action=   "http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence"This lets the service know that it can release all resources associated with the reliable channel identified by the Identifier element. The service responds with an HTTP 202 response.      null: HTTP/1.1 202 AcceptedSummaryThis tip showed you how to build and run a reliable messaging test in which a Metro-based client communicates with a WCF-based service, in other words, a public WCF endpoint. Of course, you can also run the same interoperability test orother interoperability tests using a WCF-based client or a Metro-based service. Running the tests with different combinations of Metro-based and WSF-based clients and serversshould enable you to verify interoperability between Metro and .NET. It will also enable you to become a contributor to the open source Metro project and test the interoperability of the code you contribute. About the AuthorHarold Carr is the engineering lead for enterprise web services interoperability at Sun Microsystems. Previous to this role, Harold was responsible for RMI-IIOP load-balancing and fail-over in the Sun Java System Application Server. He designed the core architecture used in Sun's CORBA ORB and in the JAX-RPC 2.0 reference implementation and the scalable socket communications architecture used in SJSAS HTTP and IIOP remoting. Harold helped write the OMG Portable Object Adapter specification and was chairperson of the OMG Portable Interceptor specification. Previous to Sun, he did distributed computing research at Hewlett-Packard Research Laboratories and Schlumberger Research Laboratories, was Chief Architect of Visual Lisp technology at Autodesk, and was a logic simulation consultant for Cirrus Logic. He holds a Ph.D., in Computer Science from the University of Utah.

By Harold Carr The March 2007 Tech Tip, Securing Web Services Using WSIT introduced Web Services Interoperability Technology (WSIT), an implementation of open web services technologies that enables...

Sun

Client-Side Polling With Dynamic Faces

By Roger KitainThe world of dynamic web applications offers various ways for a client and server to interact. Two approaches are particularlywell suited for situations when information on the server changes frequently. These approaches are:HTTP StreamingClient PollingIn HTTP streaming, the client/server connection is left open for an extended period of time so that data is streamed from the server to the client. This approach is also known as server-side push, reverse Ajax, or comet. As information changes on the server, updates are pushed to the client.With client polling, the browser periodically issues an XMLHttpRequest call to obtain new information from the server. For example, a client can send an XMLHttpRequest to the server every five seconds to get new information. This approach is also known as periodic refresh.The Dynamic Faces frameworkbrings the power of Ajax to traditional JavaServer Faces Technology (often abbreviated as JSF) applications. Ajax function calls are typically made in JavaScript, which can be unfamiliar to Java developers. With Dynamic Faces, you can add Ajax functionality to a JSF application with little or no JavaScript. Dynamic Faces provides a small "out of the box" JavaScript library that you can use with a JSF application. This tip will show you how you can use Dynamic Faces to build a real-time, stock query application that does client-side polling. You'll see that you don't have to do much JavaScript coding. A package that contains the code for the sample applicationaccompanies the tip. The code examples in the tip are taken from the source code of the sample (which is included in the package). The Stock Query ApplicationThis tip uses a stock query application to demonstrate client-side polling with Dynamic Faces. First, let's take a look at the user interface (UI) for the application.User InterfaceStock Query The UI is pretty basic. You enter one or more space-delimited stock symbols in the Symbol text field and click the Search button. In response, the application displays a table of datapertinent to the stocks represented by the symbols you entered.You enter proxy information in the Proxy Host and Proxy Port fields if you are behind a firewall. The most interesting feature of the UI is the Streaming field. The choices are On or Off. If Streaming is set to On, the client polls the server, firing Ajax transactions every 10 seconds (or a specified time interval). The Remote/Local field allows you to choose either Local or Remote. If you select Local, the application uses local data. This is the choice to make if a network connection is not available. If you select Remote, the application calls the Yahoo Stock Quoting service to get the stock data. The size of the result table dynamically changes depending on the number of symbols that you enter.Now let's take a look at the artifacts used in the application. ArtifactsThere are only three artifacts used in the application:A JavaServer Pages technology (JSP) pageA JavaScript fileA JSF Managed BeanJSP PageHere's a snippet of the JSP page for the application, home.jsp, showing the relevant parts:    <f:view>   <html>   <head>   ...   ...   <jsfExt:scripts/>   <script type="text/javascript">   ...   ...   include_js('javascripts/stock-faces.js');   </script>   </head>   <body>     <h:form id="form" prependId="false">     ...     <h:panelGrid border="1" columns="1"         styleClass="panel-input-border">             <h:panelGrid border="1" columns="7">                 <h:outputText value="Symbol:"/>                 <h:inputText id="symbol"/>                 <h:commandButton id="search" value="Search"                    onclick="DynaFaces.fireAjaxTransaction(                    this, {});return false;"               actionListener="#{bean.getStockInfo}" />               ...               <h:selectOneMenu id="streaming" value="Off"                   onchange="toggleStreaming()">               ...             </h:panelGrid>     </h:panelGrid>            <h:panelGrid id="stockdata" border="1" columns="8"       styleClass="panel-data-border" rendered="false">     ...   </body>   </html>   </f:view> Here are some things to notice in the code snippet: <jsfExt:scripts/> is the standard tag to include for Dynamic Faces applications. It includes the Dynamic Faces JavaScript library.The include_js('javascripts/stock-faces.js'); line is a utility function that loads the application's JavaScript file, stock-faces.js.The h:commandButton tag has an onclick JavaScript event handler attached to it. The event handler, DynaFaces.fireAjaxTransaction, sends an Ajax request to the server when the button is clicked. The actionListener specified by #{bean.getStockInfo} is then executed on the server. What's significant here is that any view or JSF component manipulation done on the server happens using Ajax. The "streaming" option is a h:selectOneMenu component that has an onchange JavaScript event handler. A h:panelGrid tag with an id of "stockdata" is a placeholder the dynamic table of stock data. The attribute rendered is set to "false", meaning that the table is not initially rendered.However, the application code sets the attribute to true when there is stock data to return.JavaScript FileHere is the JavaScript file, stockfaces.js, for the application:   var pollId;      /** Delay between requests to the server when polling. */    var pollDelay = 10000;      /** Start polling the server */   function start() {       pollId = setInterval(poll, pollDelay);   }        /** Stop polling the server */   function stop() {       clearInterval(pollId);   }       function poll() {       queueEvent();       DynaFaces.fireAjaxTransaction(null, {});   }      function queueEvent() {       var actionEvent =           new DynaFaces.ActionEvent("search",           DynaFaces.PhaseId.INVOKE_APPLICATION);       DynaFaces.queueFacesEvent(actionEvent);       return false;   }      function toggleStreaming() {       var menu = document.getElementById("streaming");       var idx = menu.selectedIndex;       var streaming = menu[idx].value;       if (streaming == "Off") {           stop();       } else if (streaming == "On") {           start();       }   }Here's what the JavaScript code in the file does:The polling delay, that is, the time interval between calls to the server, is set to 10 seconds.The start() function initiates the server polling.The stop() function stops server polling.The poll() function queues up a server-side JSF action event.It then fires an Ajax request to the server using the Dynamic Faces library.The queueEvent() function queues up a server-side JSF action event using the Dynamic Faces library. The action event is processed during the standard JSF lifecycle processing as the Ajax request flows to the server.The toggleStreaming() function toggles the value of the "streaming" menu control.JSF Managed BeanHere's a snippet of the JSF managed bean, Bean.java, showing the relevant parts:   /**    * This bean has methods to retrieve stock information from     * the Yahoo quote service.    */   public class Bean {          private static final String SERVICE_URL =          "http://quote.yahoo.com/d/quotes.csv";       /**        * Action method that is used to retrieve stock         * information. This method uses two helper methods - one         * to get the stock information, and the other to         * dynamically build the "data" components for the UI.        */       public void getStockInfo(ActionEvent ae) {   ...   ...                                 stockData = getStockData(symbols);                                 buildUI(stockData);   ...    }        /**     * Helper method to get the stock data (remotely).     */    private String[] getStockData(String[] symbols)        throws IOException, MalformedURLException {        String[] data = new String[symbols.length];        for (int i=0; i<symbols.length; i++) {            StringBuffer sb = new StringBuffer(SERVICE_URL);    ...    ...        }        return data;    }        /**     * Helper method to dynamically add JSF components to      * display the data.     */    private void buildUI(String[] stockData) {        FacesContext context =             FacesContext.getCurrentInstance();        UIForm form =             (UIForm)context.getViewRoot().findComponent("form");        UIPanel dataPanel =             (UIPanel)form.findComponent("stockdata");    ...    ...        // Create and add components with data values            // Symbol        ...        dataPanel.getChildren().add(outputComponent);                // Name        ...        dataPanel.getChildren().add(outputComponent);                // Open Price (if any)        ...        dataPanel.getChildren().add(outputComponent);        ...        ...        }        dataPanel.setRendered(true);    }This JSF Managed Bean has an action method, getStockInfo, that does two things:It uses a helper method, getStockData, to contact the Yahoo Stock Quote service (as defined by SERVICE_URL) to retrieve stock data for all the symbols.It uses a helper method, buildUI, to build JSF components (from the stock data) and it adds the JSF components to the JSF component view. After all the components have been createdand added, the action method sets the rendered attribute to true on the stockdata JSF component.The action method, getStockInfo, is called when the Search button is pressed. It is also called as the result of an Ajax poll request. This is because each client poll queues an action event tied to this event handler. Refer to the queueEvent method in the stock-faces.js JavaScript file.Running the Sample CodeA sample package accompanies this tip that demonstrates the techniques covered in the tip. You can deploy the sample package on any web container that supports the Servlet 2.5 API, JavaServer Pages (JSP) Technology 2.1, and JavaServer Faces Technology 1.2. These instructions assume that you are using GlassFish. To install and run the sample:If you haven't already done so, download and install GlassFish.Download the sample application for the tip and extract its contents. You should now see the newly extracted directory as <sample_install_dir>/client-poll-dfaces, where <sample_install_dir> is the directory where you installed the sample application. For example, if you extracted the contents to C:\\ on a Windows machine, then your newly created directory should be at C:\\client-poll-dfaces. Start GlassFish by entering the following command:<GF_HOME>/bin/asadmin start-domain domain1where <GF_HOME> is the directory where you installed GlassFish.Deploy the sample by copying <sample_install_dir>/client-poll-dfaces/stock-faces.war to <GF_HOME>/domains/domain1/autodeployOpen your browser to the URL: http://localhost:8080/stock-faces/.You should see the Stock Query Application UI.Stock Query  Enter one or more stock symbols delimited by a space, for example, JAVA LMT IBM. If you are behind a firewall, specify the pertinent proxy information in the Proxy Host and Proxy Port fields. Click the Search button. You should see a table of stock data displayed for the symbols you entered. Stock Query Try different combinations of streaming and Local/Remote settings, and see what happens. You'll notice that if Streaming is set to On, you don't have to press the Search button. The stock symbols that you specified in the Symbol text field are automatically sent using the Ajax mechanism to the server. If you choose Local, the names and prices are simulated, so that the data will likely be different thanthe result of a Remote selection.SummaryThis tip demonstrated how you can combine JSF with Ajax to produce dynamic applications. This application illustrated two features of Dynamic Faces:fireAjaxTransactionRemote JSF event queuing from JavaScriptYou can find out more about Dynamic Faces in the jsf-extensions project.Also see Ed Burns's blog Introducing Project Dynamic Faces.About the AuthorRoger Kitain is the JavaServer Faces technology co-specification lead. He has been extensively involved with server-side web technologies and products since 1997. Roger started working on JSF in 2001 as a member of the reference implementation team. He has experience with Java Servlet technology, JSP, and most recently has been involved with different rendering technologies for JSF.

By Roger Kitain The world of dynamic web applications offers various ways for a client and server to interact. Two approaches are particularly well suited for situations when information on the serverch...

Sun

Improving JSF Security Configuration With Secured Managed Beans

By Vinicius SengerJava EE allows you to protect web resources through declarative security, but this approach does not allow you to protect local beans used by servlets and JavaServer Pages (JSPs). Also, although you can protect JavaServer Faces technology (JSF) pages using declarative security, this is often not sufficient.This tip will show you a way to extend JSF security configuration beyond web pages using managed bean methods.IntroductionJava EE allows you to protect web pages and other web resources such as files, directories, and servlets through declarative security. In this approach you declare in a web.xml file specific web resources and the security roles that can access those resources. For example, based on the following declarations in a web.xml file, only authenticated users who are assigned the admin security role can access the secured resources identified by the URL pattern /members.jsf:   <security-constraint>     <display-name>Sample</display-name>        <web-resource-collection>          <web-resource-name>members</web-resource-name>          <description/>          <url-pattern>/members.jsf</url-pattern>          <http-method>GET</http-method>          <http-method>POST</http-method>        </web-resource-collection>        <auth-constraint>          <description/>          <role-name>admin</role-name>        </auth-constraint>        </security-constraint>    <security-role>        <description/>        <role-name>admin</role-name>    </security-role>Notice that you identify the resources you want to protect by specifying their URLs in a <url-pattern> element. Unfortunately, because local beans used by servlets and JavaServer Pages (JSP) cannot be mapped to a <url-pattern> element, you can't use declarative security to protect local beans. Also, although you can protect JSF pages using declarative security, this is often not sufficient. For example, you might want a JSF application to present the same page to users with different roles, but only allow some of those roles to perform specific operations. For instance, you might allow users with all of those roles to read and update data, but allow userswith specific roles to create and delete data. In that case, you need a way to extend JSF security beyond web pages.Additionally, declarative security doesn't check roles during the request processing commonly used by MVC frameworks and JSF. As a result, a managed bean can return any view id even if it's for a protected resource. This can potentially expose protected resources to a role that should not have access to them.One solution is to use JBoss Seam Web Beans or JSR 299: Web Beans. Web Beans allow you to configure page security, component security, and even Java Persistence Architecture entity security. However, many companies are adopting simpler security solutions without Seam, Spring, EJB, or security-specific frameworks. The technique covered in this tip demonstrates a simple approach that extends JSF security using annotations in managed beans methods. A sample application accompanies this tip. The code examples in the tip are taken from the source code of the sample application.Declare the Extended JSF ActionListener and NavigationHandlerTo provide managed bean method protection you need to declare the extended JSF ActionListener and NavigationHandler. These custom classes analyze each user action and check for authentication and authorization.To enable the classes, you declare the following elements inside the faces-config.xml file:   <!-- JSF-security method-->   <application>     <action-listener>       br.com.globalcode.jsf.security.SecureActionListener     </action-listener>     <navigation-handler>       br.com.globalcode.jsf.security.SecureNavigationHandler     </navigation-handler>   </application> SecureActionListener intercepts calls to managed bean methods and checks for annotated method permissions. NavigationHandler forwards the user to a requested view if the user has the required credentials and roles.For example, the following code renders a JSF page with a View button and a Delete button.    <h:form id="sampleSecurity">     <h:commandButton value="View" id="unprotectedButton"                action="#{CustomerCRUD.view}"/>     <h:commandButton value="Delete"                id="protectedButtonprotectedButton"                action="#{CustomerCRUD.delete}"/>   </h:form>When the user clicks on the Delete button, a call is made to the CustomerCRUD.delete method. The method includes an annotation that declares a required role for the method.   public class CustomerCRUD {          public String view() {       return "view-customer";     }          @SecurityRoles("customer-admin-adv, root")     public String delete() {       System.out.println("I'm a protected method!");       return "delete-customer";     }     ...SecureActionListener intercepts calls to CustomerCRUD.delete and checks for the customer-admin-adv and root permissions. NavigationHandler forwards the user to a requested view if the user has the required credentials and roles.Set Up User Object ProvidersBy adding a context parameter into web.xml, you can set up different user object providers, as follows:ContainerUserProvider: Integrate with container/declarative security.SessionUserProvider: Look up Http session for object named "user".Your Provider: Implement the UserProvider interface:     <context-param>       <param-name>jsf-security-user-provider</param-name>       <param-value>           YourClassImplementsUserProvider       </param-value>     </context-param>Set Up the ContainerUserProvider The web container provider approach is integrated with declarative security, so it can be used with applications that already use declarative security. Add the following context parameter to set up the default container user provider:  <context-param>    <param-name>jsf-security-user-provider</param-name>    <param-value>        br.com.globalcode.jsf.security.usersession.ContainerUserProvider    </param-value>  </context-param>Here is what the default web container user provider class looks like:   public class ContainerUserProvider implements UserProvider {     ContainerUser user = new ContainerUser();     public User getUser() {       if(user.getLoginName()==null ||                user.getLoginName().equals("")) {         return null;       } else {         return user;       }     }ContainerUserProvider references the ContainerUser class. Here's what the ContainerUser class looks like (some of the code lines are cut to fit the width of the page):   public class ContainerUser implements User {     public String getLoginName() {       if(FacesContext.getCurrentInstance().getExternalContext().       getUserPrincipal()==null) return null;       else return FacesContext.getCurrentInstance().       getExternalContext().getUserPrincipal().toString();     }     public boolean isUserInRole(String roleName) {       return         FacesContext.getCurrentInstance().getExternalContext().        isUserInRole(roleName);     }Using a SessionUserProviderIf your solution uses a custom security authentication and authorization process, you can provide a user class adapter that implements the given user interface and bind a user object instance into the HTTP Session with the key name "user". This approach works well for legacy Java EE or J2EE applications that don't use declarative security.Follow these steps to set up your application to use a SessionUserProvider:Add the following context parameter to the web.xml file to set up the user provider to look up the HTTP Session for the "user"object:     <context-param>       <param-name>jsf-security-user-provider</param-name>       <param-value>           br.com.globalcode.jsf.security.usersession.SessionUserProvider       </param-value>     </context-param>  Create your User class adapter implementation:      package model;      public class MyUser         implements br.com.globalcode.jsf.security.User {        //Your user instance object         public String getLoginName() {          //your user bridge          return "me";        }        public boolean isUserInRole(String roleName) {        //your user roles bridge        return true;        }      }   Provide page login with a navigation case called login:       //Login page         <h:form id="loginForm">          <h:outputText value="Login:"/>            <h:inputText value="#{LoginMB.userName}">            </h:inputText>                      <h:outputText value="Password:"/>          <h:inputText value="#{LoginMB.password}"/>          <h:commandButton value="Login" action="#{LoginMB.login}"/>          <h:messages/>        </h:form>         <navigation-case>        <from-outcome>login</from-outcome>        <to-view-id>/login.xhtml</to-view-id>      </navigation-case>Write a login managed bean that checks the user credentials and puts (or not) the user object into the HTTP session.      public class LoginMB {        private String userName;        private String password;      @SecurityLogin      public void login() {        //Your login process here...        MyUser user = new MyUser();        HttpSession session =         (HttpSession) FacesContext.getCurrentInstance().        getExternalContext().getSession(false);        session.setAttribute("user", user);      }    } Running the Sample Code A sample package accompanies this tip. This sample runs with a SessionUserProvider and has a very simple user and login page.To install and run the sample: Download the sample package and extract its contents. You should now see a newly extracted directory <sample_install_dir>/facesannotations-glassfish, where <sample_install_dir> is the directory where you installed the sample package. For example, if you extracted the contents to C:\\ on a Windows machine, then your newly created directory should be at C:\\facesannotations-glassfish.Notice that the faces-config.xml file in the expanded sample package contains the declarations for the SecureActionListener and SecureNavigationHandler. Start the NetBeans IDE. Open the facesannotations-glassfish project as follows:Select Open Project from the File menu.Browse to the facesannotations-glassfish directory from the sample application download. Click the Open Project Folder button. Run facesannotations-glassfish as follows: Right click on the facesannotations-glassfish node in the Projects window. Select Run Project. Open your browser to the following URL: http://localhost:8080/facesannotations-glassfish/index.jsfYou should see a page that contains two buttons: one button invokes an unprotected method. The other button invokes a protected method.   Click on both buttons and see what happens. You'll see thatyou can run the unprotected method, but the protected methodrequires you to have a special role.  About the Author Vinicius Senger is a performance researcher, Java EE architect, and instructor. He started his career at Sun Microsystems and Oracle as independent consultant and official instructor, and later founded Globalcode, a leading Java-related training company in Brazil. Vinicius is a member of the JSF 2.0 Expert Group, the leader of the Global Education and Learning Community, a NetBeans Dream Team Member, and project leader of JAREF, an educational and research framework. He is also a Sun Certified Enterprise Architect and Programmer P1.

By Vinicius Senger Java EE allows you to protect web resources through declarative security, but this approach does not allow you to protect localbeans used by servlets and JavaServer Pages (JSPs)....

Sun

Using Type Substitution with Web Services

By Doug KohlertJava Architecture for XML Binding (JAXB) 2.1 introduced a new annotation, @XmlSeeAlso, that you can use to make JAXB aware of additional types. Java API for XML-Based Web Services (JAX-WS) 2.1 also uses the @XmlSeeAlso annotation to allow use of abstract classes in a service endpoint interface (SEI). JAX-WS 2.1 allows you to specify the @XmlSeeAlso annotation on a SEI. JAX-WS reads this annotation at runtime making sure to pass all of the classes referenced by the annotation to JAXB via the JAXBContext. The use of the @XmlSeeAlso annotation in JAXB and JAX-WS enables support for type substitution, a subclassing concept that complements inheritance.This tip will show you how to develop a simple web service that uses type substitution as well as a client that consumes the web service. You'll see how to build the web service from a Java class and from a WSDL file.A sample application accompanies this tip. The code examples in the tip are taken from the source code of the sample application.Using Type Substitution in a Web ServiceSuppose you want to build a web service that manages the inventory for a store that sells wakeboards and related equipment. Wakeboards are short boards made of buoyant material that are used to ride over the surface of a body of water, typically behind a boat or with a cable-skiing apparatus.For simplicity, let's assume that the store sells only three types of items: wakeboards, bindings, and towers for boats. You want the web service to be fairly simple to use and have a minimal amount of exposed operations. So to keep things simple, the web service uses an abstract Item class in its operations instead of using type-specific operations. The following Item class can be used to model any inventory object that you might want to expose through your web service:   public abstract class Item implements Serializable {       private long id;       private String brand;       private String name;       private double price;        ...          }Extending the Item class, you can define the following Wakeboard, WakeboardBinding and Tower classes:   public class Wakeboard extends Item {       private String size;          }      public class WakeboardBinding extends Item {       private String size;          }   public class Tower extends Item {       private Fit fit;           private String tubing;           public static enum Fit { Custom, Exact, Universal };          }Because this example is about type substitution, let's make the inheritance hierarchy a little more interesting by introducing a Wearable abstract class. Wearable holds the size attribute for both the Wakeboard and WakeboardBinding classes. The Wearable class is defined as follows:   public abstract class Wearable extends Item {        protected String size;          }And the resulting Wakeboard and WakeboardBinding classes are:    public class Wakeboard extends Wearable {      }   public class WakeboardBinding extends Wearable {      }Also, because the web service manages inventory, you'll want the inventory items to be persisted to a database using the Java Persistence API (sometimes referred to as JPA). To do this, you need to add an @Entity annotation to each of the classes that will be persisted. The only class that you probably don't want to persist is the Wearable class. You can add the @MappedSuperclass annotation to this class so that the JPA will use the attributes of this class for persisting subclasses. Next, you need to add the @Id and the @GeneratedValue(strategy = GenerationType.AUTO) annotations to the Item.Id field. As a result, the field will be used as the primary key in the database and the Id will be automatically generated if not provided. Finally, because you might add new types of Items into the system at a later time, you should add the @Inheritance(strategy=InheritanceType.JOINED) annotation to the Item class. This will store each subclass in its own database table. The final data classes look like the following:   @Entity   @Inheritance(strategy=InheritanceType.JOINED)   public abstract class Item implements Serializable {       @Id       @GeneratedValue(strategy = GenerationType.AUTO)       private Long id;       private String brand;       private String itemName;       private double price;       // Getters & setters       ...          }   @MappedSuperclass   public abstract class Wearable extends Item {        protected String size;       ...   }   @Entity   public class Wakeboard extends Wearable {}   @Entity   public class WakeboardBinding extends Wearable {}   @Entity   public class Tower extends Item {       private Fit fit;           private String tubing;           public static enum Fit { Custom, Exact, Universal };       ...          }Now that you defined the data model for the application, you can now define the web service interface. Because the application manages information about wakeboard equipment, let's call the web service WakeRider and let's expose four operations in the web service: addItem, updateItem, removeItem, and getItems. Here is what the WakerRider class looks like:   @WebService()   public class WakeRider {       ...       public List<Item> getItems() {...}         public boolean addItem(Item item) {...}           public boolean updateItem(Item item) {...}       public boolean removeItem(Item item) {...}   }If you deployed this web service and then looked at the generated WSDL and schema, you would notice that only the Item type is defined -- there is no mention of Wearable, Wakeboard, WakeboardBinding, or Tower. This is because when JAX-WS introspects the WakeRider class there is no mention of the other classes. To remedy that you can use the new @XmlSeeAlso annotation and list the other classes that you want to expose through the WakeRider web service. Here is what the WakeRider class looks like with the @XmlSeeAlso annotation:   @WebService()   @XmlSeeAlso({Wakeboard.class,                 WakeboardBinding.class,                 Tower.class})      public class WakeRider {       ...   }Now when you deploy the WakeRider service and look at the generated schema, you will see types for Item, Wearable, Wakeboard, WakeboardBinding, and Tower as well as some other types used internally by JAX-WS and JAXB.Starting From WSDLYou can use type substitution in a web service that is built from a WSDL file. What's particularly nice about this is thatusing type substitution when starting from WSDL is totally transparent. When you import a WSDL file with JAX-WS 2.1, the generated proxy class is required to have the appropriate @XmlSeeAlso annotation. For example, the imported WakeRider proxy from the web service example in the previous section would have an @XmlSeeAlso annotation like the following:   @WebService(name="WakeRider",                           targetNamespace="http://wakerider/")   @XmlSeeAlso({ObjectFactory.class})   public interface WakeRider {       ...   }Notice that the @XmlSeeAlso annotation in the proxy contains the ObjectFactory.class instead of listing the classes. The ObjectFactory class is a JAXB required class that provides information about all of the Java types that JAXB needs to be aware of in the given package. In this example, the ObjectFactory class will have references to the Item, Wearable, Wakeboard, WakeboardBinding and Tower classes. There is nothing that you need to do to enable type substitution when starting from WSDL.The WakeRider ClientInvoking the WakeRider web service from a client is the same as invoking any other web service using JAX-WS. All you need to do is get a WakeRider proxy from the generated WakeRider web service and invoke the operations on the proxy. The sample application that accompanies this tip contains a NetBeans 5.5.1 project for a Java Platform, Standard Edition (Java SE) application named wrmanager. You can use the application to add, remove, or edit items in the WakeRider web service inventory. There is also a NetBeans 5.5.1 project for a JavaServer Faces (JSF) technology application named wrviewer. The application uses the WakeRider web service to view the current inventory. Both of these client applications contain code similar to the following for invoking an operation on the WakeRider web service:   WakeRiderService service = new WakeRiderService();   port = service.getWakeRiderPort();   List<Item> items = port.getItems();   for (Item item : items) {       if (item instanceof Wakeboard) {           ...       } else if (Item instance of WakeboardBinding) {        ...       } else if (Item instance of Tower) {           ...       }   }Running the Sample CodeThe sample code for this tip is available as three NetBeans projects:wrservice. Defines the WakeRider endpoint.wrviewer. A JSF page for viewing the WakeRider inventory.wrmanager. A Java SE application for adding, removing, and editing items in the WakeRider. You can build and run the sample code using the NetBeans 5.5.1 IDE as follows: If you haven't already done so, download and install the NetBeans 5.5.1 IDE. If you haven't already done so, download and install GlassFish V2 RC 4 or later.Download the sample application for the tip and extract its contents. You should now see the newly extracted directory as <sample_install_dir>/wakerider, where <sample_install_dir> is the directory where you installed the sample application. For example, if you extracted the contents to C:\\ on a Windows machine, then your newly created directory should be at C:\\wakerider. The wakerider directory contains one directory for each of the NetBeans projects: wrservice, wrviewer, and wrmanager.Start the NetBeans IDE. Run Netbeans with JDK 5.0. You can also use JDK 6, however in that case, you will also need to follow the instructions in Running on top of JDK 6.Add GlassFish V2 to the NetBeans Application Servers as follows:Right click on Servers node in the Runtime window.Select Add Server.Leave the Server as Sun Java System Application Server.Click the Next button.Click the Browse button and browse to the location that you installed GlassFish V2.Click the Choose button.Click the Next button.Set the Admin Password to the default, adminadmin, unless you chose a different password for GlassFish.Click the Finish button.Open the wrservice project as follows:Select Open Project from the File menu.Browse to the wrservice directory from the sample application download.Click the Open Project Folder button. If you are alerted to a "Missing Server Problem", resolve it by right clicking on the wrservice node in the Projects window and selecting Resolve Missing Server Problem. Then select Sun Java System Application Server.Deploy the wrservice project as follows:Right click the wrservice node in the Projects window.Select Deploy Project.Open the wrviewer project as follows:Select Open Project from the File menu.Browse to the wrviewer directory from the sample application download.Click the Open Project Folder button.You may need to resolve a missing server problem as described in step 6.Run wrviewer as follows:Right click on the wrviewer node in the Projects window.Select Run Project. This should open a window in your web browser that displays the current WakeRider inventory. The inventory should be empty the first time you run wrviewer.WakeRider Inventory Open the wrmanager project as follows:Select Open Project from the File menu.Browse to the wrmanager directory from the sample application download.Click the Open Project Folder button.Run wrmanager as follows:Right client on the wrmanager node in the Projects window.Select Run Project. This should open the WakeRider Inventory Manager application.WakeRider Inventory Manager Add, delete, edit, or view inventory items as follows:To add an item, click the Add button in the WakeRider Inventory Manager application, fill in the Add Item dialog and click the OK button.To edit an item, select the item in the appropriate inventory window in the WakeRider Inventory Manager application and click the Edit button. Modify the contents of the Edit Item dialog and click the OK button.To delete an item, select the item in the appropriate inventory window in WakeRider Inventory Managerapplication and click the Remove button.To view current inventory items in the wrmanager application, view or refresh the wrviewer page in your browser.WakeRider Inventory About the AuthorDoug Kohlert is a senior staff engineer in the Web Technologies and Standards division of Sun Microsystems where he is the specification lead for JAX-WS.

By Doug Kohlert Java Architecture for XML Binding (JAXB) 2.1 introduced a new annotation, @XmlSeeAlso, that you can use to make JAXB aware of additional types. Java API for XML-Based Web Services...

Sun

Supporting Tokens and Issued Token Delegation in WSIT

By Shyam RaoThe March, 2007 Tech Tip Securing Web Services Using WSIT introduced Web Services Interoperability Technology (WSIT), an implementation of open web services technologies that enables interoperability between Java EE and .Net. Built on Java API for XML Web Services (JAX-WS), WSIT addresses key aspects of web services interoperability such as reliable messaging, transaction handling, and security. After introducing WSIT, the tip showed how to use the WS-Security support in WSIT so that a client can access a service in the same security domain. It also showed how to use the WS-Trust support in WSIT to access a service in a different security domain.This tip expands on the earlier tip. It focuses on:Supporting tokens with sender-vouches SAML assertionsSecurity Token Service (STS)-issued tokensUsed in combination, supporting tokens with sender-vouches SAML assertions and STS-issued tokens can be used to issue a token from an STS and delegate it to a user who is different than the web service client.Note that an issued token may not be for the web service client directly, but for an another entity with which the web service client has a direct trust relationship. In this kind of scenario, the web service client acts as a proxy. The actual user logs into this proxy using his or her trusted credentials. The web service client then acts on behalf of the actual user to ask for a token from the STS, that is, the web service client trust STS. The STS issues a token, which is intended for use only by the actual user and not by the web services client.In this tip, you'll learn about:Supporting tokens Sender-vouches SAML assertions WS-Trust extensions in WSITYou'll also learn how to:Populate detail for an actual user in an SAML