Miles to go …

November 18, 2010

TOTD #150: Collection of GlassFish, NetBeans, JPA, JSF, JAX-WS, EJB, Jersey, MySQL, Rails, Eclipse, and OSGi tips

This is the 150th tip published on this blog so decided to make it a collection of all the previous ones. Here is a tag cloud (created from wordle.net/create) from title of all the tips:

As expected GlassFish is the most prominent topic. And then there are several entries on NetBeans, JRuby/Rails, several Java EE 6 technologies like JPA, JAX-WS, JAX-RS, EJB, and JSF, and more entries on Eclipse, OSGi and some other tecnhologies too. Here is a complete collection of all the tips published so far:

  • #149: How to clean IntelliJ cache, preferences, etc on Mac OS X ?
  • #148: JPA2 Metamodel Classes in NetBeans 7.0 – Writing type-safe Criteria API
  • #147: Java Server Faces 2.0 Composite Components using NetBeans – DRY your code
  • #146: Understanding the EJB 3.1 Timer service in Java EE 6 – Programmatic, Deployment Descriptor, @Schedule
  • #145: CDI Events – a light-weight producer/consumer in Java EE 6
  • #144: CDI @Produces for container-managed @Resource
  • #143: Retrieve Twitter user timeline using using Jersey and OAuth
  • #142: GlassFish 3.1 – SSH Provisioning and Start/Stop instance/cluster on local/remote machines
  • #141: Running GlassFish 3.1 on Ubuntu 10.04 AMI on Amazon EC2
  • #140: Moving GlassFish Installation – Referenced file does not exist "osgi-main.jar"
  • #139: Asynchronous Request Processing using Servlets 3.0 and Java EE 6
  • #138: GlassFish 3.1 Milestone 1 – Clustering and Application Versioning Demos
  • #137: Asynchronous EJB, a light-weight JMS solution – Feature-rich Java EE 6
  • #136: Default Error Page using Servlets 3.0 – Improved productivity using Java EE 6
  • #135: JSF2 Composite Components using NetBeans IDE – lightweight Java EE 6
  • #134: Interceptors 1.1 in Java EE 6 – What and How ?
  • #133: JPA2 (JPQL & Criteria), JavaDB, and embedded GlassFish – perfect recipe for testing
  • #132: Servlets 3.0 in Embedded GlassFish Reloaded – lightweight Java EE 6
  • #131: Dynamic OSGi services in GlassFish – Using ServiceTracker
  • #130: Invoking a OSGi service from a JAX-WS Endpoint – OSGi and Enterprise Java
  • #129: Managed Beans 1.0 in Java EE 6 – What and How ?
  • #128: EJBContainer.createEJBContainer: Embedded EJB using GlassFish v3
  • #127: Embedding GlassFish in an existing OSGi runtime – Eclipse Equinox
  • #126: Creating an OSGi bundles using Eclipse and deploying in GlassFish
  • #125: Creating an OSGi bundles using NetBeans and deploying in GlassFish
  • #124: OSGi Declarative Services in GlassFish – Accessed from a Java EE client
  • #124: Using CDI + JPA with JAX-RS and JAX-WS
  • #123: f:ajax, Bean Validation for JSF, CDI for JSF and JPA 2.0 Criteria API – all in one Java EE 6 sample application
  • #122: Creating a JPA Persistence Unit using NetBeans 6.8
  • #121: JDBC resource for MySQL and Oracle sample database in GlassFish v3
  • #120: Deployment Descriptor-free Java EE 6 application using JSF 2.0 + EJB 3.1 + Servlets 3.0
  • #119: Telnet to GlassFish v3 with NetBeans 6.8 – "Could not open connection to the host"
  • #118: Managing OSGi bundles in GlassFish v3 – asadmin, filesystem, telnet console, web browser, REST, osgish
  • #117: Invoke a JAX-WS Web service from a Rails app deployed in GlassFish
  • #116: GlassFish v3 Administration using JavaFX front-end – JNLP available
  • #115: GlassFish in Eclipse – Integrated Bundle, Install Stand-alone or Update Existing plugin
  • #114: How to enable Java Console in Mac OS X, Windows, … ?
  • #113: JavaFX front-end for GlassFish v3 Administration – Using REST interface
  • #112: Exposing Oracle database tables as RESTful entities using JAX-RS, GlassFish, and NetBeans
  • #111: Rails Scaffold for a pre-existing table using Oracle and GlassFish
  • #110: JRuby on Rails application using Oracle on GlassFish
  • #109: How to convert a JSF managed bean to JSR 299 bean (Web Beans) ?
  • #108: Java EE 6 web application (JSF 2.0 + JPA 2.0 + EJB 3.1) using Oracle, NetBeans, and GlassFish
  • #107: Connect to Oracle database using NetBeans
  • #106: How to install Oracle Database 10g on Mac OS X (Intel) ?
  • TOTD #105: GlassFish v3 Monitoring – How to monitor a Rails app using asadmin, JavaScript, jConsole, REST ?
  • #104: Popular Ruby-on-Rails applications on GlassFish v3 – Redmine, Typo, Substruct
  • #103: GlassFish v3 with different OSGi runtimes – Felix, Equinox, and Knoplerfish
  • #102: Java EE 6 (Servlet 3.0 and EJB 3.1) wizards in Eclipse
  • #101: Applying Servlet 3.0/Java EE 6 “web-fragment.xml” to Lift – Deploy on GlassFish v3
  • #100: Getting Started with Scala Lift on GlassFish v3
  • #99: Creating a Java EE 6 application using MySQL, JPA 2.0 and Servlet 3.0 with GlassFish Tools Bundle for Eclipse
  • #98: Create a Metro JAX-WS Web service using GlassFish Tools Bundle for Eclipse
  • #97: GlassFish Plugin with Eclipse 3.5
  • #96: GlassFish v3 REST Interface to Monitoring and Management – JSON, XML, and HTML representations
  • #95: EJB 3.1 + Java Server Faces 2.0 + JPA 2.0 web application – Getting Started with Java EE 6 using NetBeans 6.8 M1 & GlassFish v3
  • #94: A simple Java Server Faces 2.0 + JPA 2.0 application – Getting Started with Java EE 6 using NetBeans 6.8 M1 & GlassFish v3
  • #93: Getting Started with Java EE 6 using NetBeans 6.8 M1 & GlassFish v3 – A simple Servlet 3.0 + JPA 2.0 app
  • #92: Session Failover for Rails applications running on GlassFish
  • #91: Applying Java EE 6 "web-fragment.xml" to Apache Wicket – Deploy on GlassFish v3
  • #90: Migrating from Wicket 1.3.x to 1.4 – "Couldn’t load DiskPageStore index from file" error
  • #89: How to add pagination to an Apache Wicket application
  • #88: How add pagination to Rails – will_paginate
  • #87: How to fix the error undefined method `new’ for "Rack::Lock":String caused by Warbler/JRuby-Rack ?
  • #86: Getting Started with Apache Wicket on GlassFish
  • #85: Getting Started with Django Applications on GlassFish v3
  • #84: Using Apache + mod_proxy_balancer to load balance Ruby-on-Rails running on GlassFish
  • #83: Eclipse Tools Bundle for GlassFish 1.0 – Now Available!
  • #82: Getting Started with Servlet 3.0 and EJB 3.1 in Java EE 6 using NetBeans 6.7
  • #81: How to use nginx to load balance a cluster of GlassFish Gem ?
  • #80: Sinatra CRUD application using Haml templates with JRuby and GlassFish Gem
  • #79: Getting Started with Sinatra applications on JRuby and GlassFish Gem
  • #78: GlassFish, EclipseLink, and MySQL efficient pagination using LIMIT
  • #77: Running Seam examples with GlassFish
  • #76: JRuby 1.2, Rails 2.3, GlassFish Gem 0.9.3, ActiveRecord JDBC Adapter 0.9.1 – can they work together ?
  • #75: Getting Started with Grails using GlassFish v3 Embedded
  • #74: JRuby and GlassFish Integration Test #5: JRuby 1.2.0 RC2 + Rails 2.x.x + GlassFish + Redmine
  • #73: JRuby and GlassFish Integration Test #4: JRuby 1.2.0 RC2 + Rails 2.2.x + GlassFish v2 + Warbler
  • #72: JRuby and GlassFish Integration Test #3: JRuby 1.2.0 RC2 + Rails 2.2.x + GlassFish v3
  • #71: JRuby and GlassFish Integration Test #2: JRuby 1.2.0 RC1 + Rails 2.2.x + GlassFish v3 Prelude
  • #70: JRuby and GlassFish Integration Test# 1: JRuby 1.2.0 RC1 + Rails 2.2.x + GlassFish Gem
  • #69: GlassFish High Availability/Clustering using Sun Web Server + Load Balancer Plugin on Windows Vista
  • #68: Installing Zones in Open Solaris 2008/11 on Virtual Box
  • #67: How to front-end a GlassFish Cluster with Apache + mod_jk on Mac OSX Leopard ?
  • #66: GlassFish Eclipse Plugin 1.0.16 – Install v3 Prelude from the IDE
  • #65: Windows 7 Beta 1 Build 7000 on Virtual Box: NetBeans + Rails + GlassFish + MySQL
  • #64: OpenSolaris 2008/11 using Virtual Box
  • #63: jmx4r gem – How to manage/monitor your Rails/Merb applications on JRuby/GlassFish ?
  • #62: How to remotely manage/monitor your Rails/Merb applications on JRuby/GlassFish using JMX API ?
  • #61: How to locally manage/monitor your Rails/Merb applications on JRuby/GlassFish using JMX ?
  • #60: Configure MySQL 6.0.x-alpha to NetBeans 6.5
  • #59: How to add Twitter feeds to blogs.sun.com ? + Other Twitter Tools
  • #58: Jersey and GlassFish – how to process POST requests ?
  • #57: Jersey Client API – simple and easy to use
  • #56: Simple RESTful Web service using Jersey and Embeddable GlassFish – Text and JSON output
  • #55: How to build GlassFish v3 Gem ?
  • #54: Java Server Faces with Eclipse IDE
  • #53: Scaffold in Merb using JRuby/GlassFish
  • #52: Getting Started with Merb using GlassFish Gem
  • #51: Embedding Google Maps in Java Server Faces using GMaps4JSF
  • #50: Mojarra 2.0 EDR2 is now available – Try them with GlassFish v3 and NetBeans 6.5
  • #49: Converting a JSF 1.2 application to JSF 2.0 – @ManagedBean
  • #48: Converting a JSF 1.2 application to JSF 2.0 – Facelets and Ajax
  • #47: Getting Started with Mojarra 2.0 nightly on GlassFish v2
  • #46: Facelets with Java Server Faces 1.2
  • #45: Ajaxifying Java Server Faces using JSF Extensions
  • #44: JDBC Connection Pooling for Rails on GlassFish v3
  • #43: GlassFish v3 Build Flavors
  • #42: Hello JavaServer Faces World with NetBeans and GlassFish
  • #41: How I created transparent logo of GlassFish using Gimp ?
  • #40: jQuery Autcomplete widget with MySQL, GlassFish, NetBeans
  • #39: Prototype/Script.aculo.us Autcomplete widget with MySQL, GlassFish, NetBeans
  • #38: Creating a MySQL Persistence Unit using NetBeans IDE
  • #37: SQLite3 with Ruby-on-Rails on GlassFish Gem
  • #36: Writing First Test for a Rails Application
  • #35: Rails Database Connection on Solaris
  • #34: Using Felix Shell with GlassFish
  • #33: Building GlassFish v3 Workspace
  • #32: Rails Deployment on GlassFish v3 from NetBeans IDE
  • #31: CRUD Application using Grails – Hosted on GlassFish and MySQL
  • #30: CRUD Application using Grails – Hosted on Jetty and HSQLDB
  • #29: Enabling "Available Plugins" tab in NetBeans IDE
  • #28: Getting Started with Rails 2.0 Scaffold
  • #27: Configurable Multiple Ruby Platforms in NetBeans 6.1 M1
  • #26: Overriding Database Defaults in Rails 2.0.2
  • #25: Rails application with PostgreSQL database using NetBeans
  • #24: Getting Started with Rails 2.0.x in JRuby 1.0.3 and JRuby 1.1RC1
  • #23: JavaFX Client invoking a Metro endpoint
  • #22: Java SE client for a Metro endpoint
  • #21: Metro 1.1 with GlassFish v2 UR1 and NetBeans 6
  • #20: How to create a new jMaki widget ?
  • #19: How to Add Metro Quality-of-Service to Contract-First Endpoint ?
  • #18: How to Build The GlassFish v3 Gem for JRuby ?
  • #17: Backing Up your Blog Posts on Roller
  • #16: Optimizing Metro Stubs by locally packaging the WSDL
  • #15: Delete/Update Row from Database using jMaki Data Table
  • #14: How to generate JRuby-on-Rails Controller on Windows (#9893)
  • #13: Setup Mongrel for JRuby-on-Rails applications on Windows
  • #12: Invoking a Java EE 5 Web service endpoint from JRuby
  • #11: Setup Mongrel cluster for JRuby-on-Rails applications on Unix
  • #10: Consuming JSON and XML representations generated by a Jersey endpoint in a jMaki Table widget
  • #9: Using JDBC connection pool/JNDI name from GlassFish in Rails Application
  • #8: Generating JSON using JAXB annotations in Jersey
  • #7: Switch between JRuby and CRuby interpreter in NetBeans 6
  • #6: Difference between Ruby Gem and Rails Plugin
  • #5: Loading data from beans in jMaki widgets
  • #4: How to convert a Session EJB to a Web service ?
  • #3: Using JavaDB with JRuby on Rails
  • #2: Change the endpoint address on a pre-generated Web services Stub
  • #1: SOAP Messaging Logging in Metro

Just for fun, here is another tag cloud:

You can access all the tips here. And keep those suggestions coming!

Technorati: totd glassfish netbeans jpa jsf jaxws jersey mysql rails osgi eclipse

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

August 4, 2010

TOTD #143: Retrieve Twitter user timeline using using Jersey and OAuth

Filed under: glassfish, totd, webservices — arungupta @ 10:12 pm

The Basic Authentication for authorizing with Twitter API will be turned off on Aug 16th. After that OAuth will be the only way to invoke the API.

Beginner’s guide to OAuth provide an excellent explanation to OAuth. The typical analogy for OAuth is a "valet key" to the car which is a stripped down version of your regular key. These keys are meant for valet drivers who don’t need to open trunk or glove compartment and don’t need to drive the car for longer distance. So even though they have access to the entire car but are restricted to the limited functionality.

OAuth is used to share your resources (photos, videos, bank accounts, etc) stored on one site with another site without having to share your username and password. The site storing the resources is "Service Provider", the site requesting the access is "Consumer", you are the "User", "Tokens" are "valet key" that provide required access to the resources.

This Tip Of The Day (TOTD) explains how Jersey, the Reference Implementation for JAX-RS, provides seamless support for OAuth by creating a simple desktop application that retrieves user timeline on Twitter using OAuth. This blog is going to combine the instructions outlined in Understanding the guts of Twitter’s OAuth for client apps and Using Jersey client OAuth support with Smugmug to achieve that.

Lets get started!

  1. Create a Maven project as:

    mvn -DarchetypeVersion=1.0 -DgroupId=org.glassfish.samples -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0-SNAPSHOT -DarchetypeGroupId=org.apache.maven.archetypes -Dpackage=org.glassfish.samples.twitter -DartifactId=twitter
    
  2. Update the generated "pom.xml" with the following fragments:
    <repositories>
      <repository>
        <id>glassfish-repository</id>
        <name>Java.net Repository for Glassfish</name>
        <url>http://download.java.net/maven/2/</url>
      </repository>
    </repositories>
    <dependencies>
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
      </dependency>
      <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-client</artifactId>
        <version>1.1.3-SNAPSHOT</version>
      </dependency>
      <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.1.3-SNAPSHOT</version>
      </dependency>
      <dependency>
        <groupId>com.sun.jersey.oauth</groupId>
        <artifactId>oauth-signature</artifactId>
        <version>1.1.2-ea-SNAPSHOT</version>
      </dependency>
      <dependency>
        <groupId>com.sun.jersey.oauth</groupId>
        <artifactId>oauth-client</artifactId>
        <version>1.1.2-ea-SNAPSHOT</version>
       </dependency>
    </dependencies>
    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>2.0.2</version>
          <configuration>
            <source>1.6</source>
            <target>1.6</target>
          </configuration>
        </plugin>
      </plugins>
     </build>
    

    The Jersey dependencies add the core Jersey libraries and OAuth functionality in Jersey.

  3. Register your app with Twitter – Register your application with Twitter by clicking on Register a new application >>. The complete list of registered applications can be seen at Applications using Twitter. Select "Client" as the app type, select "Yes, use Twitter for login" and leave the "Callback URL" empty. The registration gives you "consumer key" and "consumer secret". These are used to obtain temporary credentials (or request tokens) from Twitter.
  4. Obtain Twitter OAuth credentials – Each OAuth request is an HTTP request with "Authorization" header specifying the information by OAuth service provider. Jersey provides a OAuthClientFilter to add this header to the outbound client request. Twitter API Wiki explains the authentication as multiple step process for desktop applications. Each step involves sending some parameters to twitter and getting a result back and the intent of each method/request is clearly explained in Understanding the guts of Twitter’s OAuth for client apps. In our case, each request is created by using Jersey Client API and attaching OAuthClientFilter and is explained next.

    1. Request temporary credentials, a.k.a request token, from Twitter using oauth/request_token.

      1. In "App.java", create an instance of Jersey client in the constructor and attach a LoggingFilter to dump inbound/outbound messages as:

        public App() {
            // Create a Jersey client
            client = Client.create();
        
            client.addFilter(new LoggingFilter());
        }
        
      2. Request temporary credentials by adding the following method:

        public void getRequestToken() {
            client.removeAllFilters();
        
            // Create a resource to be used to make Twitter API calls
            WebResource resource = client.resource(REQUEST_TOKEN_URL);
        
            // Set the OAuth parameters
            OAuthSecrets secrets = new OAuthSecrets().consumerSecret(CONSUMER_SECRET);
            OAuthParameters params = new OAuthParameters().consumerKey(CONSUMER_KEY).
                    signatureMethod("HMAC-SHA1").version("1.0");
            // Create the OAuth client filter
            OAuthClientFilter oauthFilter =
                    new OAuthClientFilter(client.getProviders(), params, secrets);
        
            // Add the filter to the resource
            resource.addFilter(oauthFilter);
        
            // make the request and print out the result
            System.out.println(resource.get(String.class));
        }
        

        Note, "OAuthClientFilter" is used to populate the "Authorization" header instead of handcrafting it. The REQUEST_TOKEN_URL is "http://twitter.com/oauth/request_token", CONSUMER_SECRET and CONSUMER_KEY are the values obtained from registering your application.

      3. Edit "AppTest.java" and change "testApp" method such that it looks like:

        public void testApp() {
            App app = new App();
            app.getRequestToken();
        }
        
      4. Obtain the temporary credentials by running this application as:

        mvn test
        

        and see an output as:

        oauth_token=REQUEST_OAUTH_TOKEN&oauth_token_secret=REQUEST_OAUTH_TOKEN_SECRET&oauth_callback_confirmed=true
        

        REQUEST_OAUTH_TOKEN, a temporary token, is used to authorize on twitter.com.

    2. Authorize the user and obtain PIN

      1. Go to "https://twitter.com/oauth/authorize?oauth_token=REQUEST_OAUTH_TOKEN" in a browser window.
      2. If not already logged in, enter your twitter credentials and click "Allow".
      3. Copy the PIN.
    3. Request permanent credentials, a.k.a access token, from Twitter using oauth/access_token.

      1. Request permanent credentials by adding the following method in "App.java"

        public void getAccessToken() {
                client.removeAllFilters();
        
                // Set the OAuth parameters
                OAuthSecrets secrets = new OAuthSecrets().consumerSecret(CONSUMER_SECRET);
                OAuthParameters params = new OAuthParameters().consumerKey(CONSUMER_KEY).
                        signatureMethod("HMAC-SHA1").
                        version("1.0").
                        token(REQUEST_OAUTH_TOKEN).
                        verifier(PIN);
                // Create the OAuth client filter
                OAuthClientFilter oauthFilter =
                        new OAuthClientFilter(client.getProviders(), params, secrets);
        
                // Create a resource to be used to make Twitter API calls
                WebResource resource = client.resource(ACCESS_TOKEN_URL);
        
                // Add the filter to the resource
                resource.addFilter(oauthFilter);
        
                // make the request and print out the result
                System.out.println(resource.get(String.class));
            }
        

        REQUEST_OAUTH_TOKEN is the temporary token obtained earlier, ACCESS_TOKEN_URL is "https://twitter.com/oauth/access_token".

        Notice, REQUEST_OAUTH_TOKEN and PIN are now added to the OAuthClientFilter.

      2. Invoke this method by editing "AppTest.java" as:

        public void testApp() {
             App app = new App();
        //     app.getRequestToken();
             app.getAccessToken();
        }
        
      3. Obtain the permanent credentials by running this application as:

        mvn test
        

        and see an output as:

        oauth_token=ACCESS_OAUTH_TOKEN&oauth_token_secret=ACCESS_OAUTH_TOKEN_SECRET&user_id=USER_ID&screen_name=USER_NAME
        

        ACCESS_OAUTH_TOKEN is the authorized token that can be used for making any future requests, USER_ID and USER_NAME are identifiers for the user who signed in on twitter.com. 

  5. Get the last 20 status messages for the user from Twitter

    1. Add the following method in "App.java:
      public void getUserTimeline() {
          client.removeAllFilters();
      
          // Set the OAuth parameters
          OAuthSecrets secrets = new OAuthSecrets().consumerSecret(CONSUMER_SECRET);
          OAuthParameters params = new OAuthParameters().consumerKey(CONSUMER_KEY).
                  signatureMethod("HMAC-SHA1").
                  version("1.0").
                  token(ACCESS_OAUTH_TOKEN);
          // Create the OAuth client filter
          OAuthClientFilter oauthFilter =
                  new OAuthClientFilter(client.getProviders(), params, secrets);
      
          // Create a resource to be used to make Twitter API calls
          WebResource resource = client.resource(USER_TIMELINE_URL);
      
          // Add the filter to the resource
          resource.addFilter(oauthFilter);
      
          // Parse the JSON array
          JSONArray jsonArray = resource.get(JSONArray.class);
          List<String> statuses = new ArrayList<String>();
      
          try {
              for (int i = 0; i < jsonArray.length(); i++) {
                  JSONObject jsonObject = (JSONObject) jsonArray.get(i);
                  StringBuilder builder = new StringBuilder();
                  builder.append(jsonObject.getString("text")).
                          append(jsonObject.getString("created_at"));
                  statuses.add(builder.toString());
              }
          } catch (JSONException ex) {
              Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
          }
      }
      

      USER_TIMELINE_URL is "http://api.twitter.com/1/statuses/user_timeline.json". The "getTimelineElements" method can be updated to pick other elements from the return JSON object. The complete JSON schema for the response is described here.

    2. Edit "AppTest.java" as:

      public void testApp() {
          App app = new App();
      //    app.getRequestToken();
      //    app.getAccessToken();
          app.getUserTimeline();
      }
      
    3. Finally get the last 20 status updates by giving the command:

      mvn test
      

      and see the output similar to:

      Running org.glassfish.samples.twitter.AppTest
      [Developing OSGi-Enabled Java EE Applications- http://bit.ly/aOim34 (via
      @JavaOneConf) #javaone10Wed Aug 04 23:53:13 +0000 2010, Google Wave goes
       bye bye (via @google:)Update on Google Wave http://bit.ly/bIoDWAWed Aug
       04 21:16:07 +0000 2010, @gdaniels Yeah, I expected #wave to bye bye as
       well, but this is fairly quick!Wed Aug 04 21:15:41 +0000 2010,
      

And that’s it!

This Tip Of The Day explained how to use Jersey to retrieve last 20 status messages that a user posted on twitter. Here are some other future possible additions:

  • POST status update
  • Integrate Search API using OAuth (is it possible ?)
  • Integrate Streaming API (need more investigation)
  • Create a web-base client that automatically redirects the user from application to twitter.com and then back to the application.

Jersey and OAuth wiki provides more details about how to use OAuth with Jersey.

Technorati: totd jaxrs jersey restful webservices oauth twitter glassfish

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

April 27, 2010

TOTD #130: Invoking a OSGi service from a JAX-WS Endpoint – OSGi and Enterprise Java

Filed under: frameworks, glassfish, javaee, webservices — arungupta @ 6:15 am

Sahoo blogged about JAX-WS Web service in an OSGi bundle. This Tip Of The Day (TOTD) provides complete steps to create such an application from scratch.

We will create an OSGi service, a JAX-WS compliant Web service as hybrid application, and a JAX-WS Web service client.

Lets create an OSGi service first.

  1. Create a simple OSGi service as explained in TOTD #36. Generate the maven project as:

    mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes \
    -DgroupId=org.glassfish.samples.osgi.hello.service -DartifactId=osgi-pure
    

    The updated directory structure looks like:

    osgi-pure
    osgi-pure/pom.xml
    osgi-pure/src
    osgi-pure/src/main
    osgi-pure/src/main/java
    osgi-pure/src/main/java/org
    osgi-pure/src/main/java/org/glassfish
    osgi-pure/src/main/java/org/glassfish/samples
    osgi-pure/src/main/java/org/glassfish/samples/osgi
    osgi-pure/src/main/java/org/glassfish/samples/osgi/hello
    osgi-pure/src/main/java/org/glassfish/samples/osgi/hello/service
    osgi-pure/src/main/java/org/glassfish/samples/osgi/hello/service/Hello.java
    osgi-pure/src/main/java/org/glassfish/samples/osgi/hello/service/impl
    osgi-pure/src/main/java/org/glassfish/samples/osgi/hello/service/impl/App.java
    osgi-pure/src/main/java/org/glassfish/samples/osgi/hello/service/impl/HelloImpl.java
    

    "Hello.java" is the OSGi service interface and looks like:

    public interface Hello {
        public String sayHello(String name);
    }
    

    "HelloImpl.java" is a trivial implementation of the service and looks like:

    public class HelloImpl implements Hello {
        public String sayHello(String name) {
            return "Hello " + name;
        }
    }
    

    "App.java" is the Bundle Activator and looks like:

    import org.glassfish.samples.osgi.hello.service.impl.HelloImpl;
    import java.util.Properties;
    import org.glassfish.samples.osgi.hello.service.Hello;
    import org.osgi.framework.BundleActivator;
    import org.osgi.framework.BundleContext;
    
    /**
     * Hello world!
     */
    public class App implements BundleActivator {
    
        public void start(BundleContext bc) throws Exception {
            bc.registerService(Hello.class.getName(), new HelloImpl(), new Properties());
        }
    
        public void stop(BundleContext bc) throws Exception {
            bc.ungetService(bc.getServiceReference(Hello.class.getName()));
        }
    }
    

    The "start" method registers the OSGi service using the name "Hello" and "stop" method un-registers the service.

  2. The updated "maven-bundle-plugin" from TOTD #36 looks like:

    <plugin>
      <groupId>org.apache.felix</groupId>
      <artifactId>maven-bundle-plugin</artifactId>
      <extensions>true</extensions>
      <configuration>
        <instructions>
          <Export-Package>${pom.groupId}</Export-Package>
          <Bundle-Activator>${pom.groupId}.impl.App</Bundle-Activator>
        </instructions>
      </configuration>
    </plugin>
    

    Notice, only the package that contains the service interface, i.e. "org.glassfish.samples.osgi.hello.service", is exported and the activator and service implementation are in a different package.

  3. Create the OSGi service bundle as:

    mvn install
    

    This also installs the OSGi bundle in the local maven repository. Deploy this bundle in GlassFish v3 by copying to "glassfish/domains/domain1/autodeploy/bundles" directory. Make sure GlassFish is running or start it as:

    asadmin start-domain --verbose
    

Lets create a hybrid application that consists of a JAX-WS compliant Web service, queries the OSGi service registry, invokes the OSGi service and return a response to the client.

  1. Create the Maven project as:

    mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes \
    -DgroupId=org.glassfish.samples.osgi.jaxws.webservice -DartifactId=helloservice
    
    
  2. Change the generated "src/main/java/org/glassfish/samples/osgi/jaxws/webservice/App.java" such that it looks like:

    import javax.jws.WebService;
    import org.glassfish.samples.osgi.hello.service.Hello;
    import org.osgi.framework.BundleContext;
    import org.osgi.framework.BundleReference;
    import org.osgi.framework.ServiceReference;
    
    /**
     * Hello world!
     */
    @WebService
    public class App {
        public String sayHello(String name) {
            Hello service = getService(Hello.class);
            return service.sayHello(name);
        }
    
        /**
         * This method looks up service of given type in OSGi service registry and returns if found.
         * Returns null if no such service is available,
         */
       private static  T getService(Class type) {
           BundleContext ctx = BundleReference.class.cast(
               App.class.getClassLoader()).getBundle().getBundleContext();
           ServiceReference ref = ctx.getServiceReference(type.getName());
           return ref != null ? type.cast(ctx.getService(ref)) : null;
       }
    }
    

    The "getService" method queries the OSGI service registry and returns the service reference. The "sayHello" method looks for the "Hello" service and invokes a method on it. The name "Hello" is the same as registered during the OSGi bundle creation earlier.

  3. In the generated "pom.xml":

    1. Change the packaging to "war".
    2. Add the following repository:

      <repositories>
        <repository>
          <id>java.net</id>
          <name>GlassFish Maven Repository</name>
          <url>http://maven.glassfish.org/content/groups/glassfish</url>
        </repository>
      </repositories>
      

      so that Java EE API dependency can be resolved.

    3. Add the following dependencies in "provided" scope:

      <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>6.0</version>
        <scope>provided</scope>
      </dependency>
      <dependency>
        <groupId>org.osgi</groupId>
        <artifactId>org.osgi.core</artifactId>
        <version>4.2.0</version>
        <scope>provided</scope>
      </dependency>
      <dependency>
        <groupId>org.glassfish.samples.osgi.hello.service</groupId>
        <artifactId>osgi-pure</artifactId>
        <version>1.0-SNAPSHOT</version>
        <scope>provided</scope>
      </dependency>
      

      Notice "osgi-pure" bundle is specified as dependency as that is used to invoke the service.

    4. Add the following plugins to "pom.xml" to create the hybrid application:

      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>2.0.2</version>
          <configuration>
            <source>1.5</source>
            <target>1.5</target>
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.apache.felix</groupId>
          <artifactId>maven-bundle-plugin</artifactId>
          <configuration>
            <supportedProjectTypes>
              <supportedProjectType>war</supportedProjectType>
              <supportedProjectType>bundle</supportedProjectType>
              <supportedProjectType>jar</supportedProjectType>
            </supportedProjectTypes>
            <instructions>
              <Import-Package>javax.jws; version=2.0, *</Import-Package>
              <Web-ContextPath>${pom.artifactId}</Web-ContextPath>
            </instructions>
          </configuration>
          <executions>
            <execution>
              <id>bundle-manifest</id>
              <phase>process-classes</phase>
              <goals>
                <goal>manifest</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
        <plugin> <!-- Need to use this plugin to build war files -->
          <artifactId>maven-war-plugin</artifactId>
          <version>2.1-beta-1</version>
          <configuration>
            <archive>
              <!-- add bundle plugin generated manifest to the war -->
              <manifestFile>
                ${project.build.outputDirectory}/META-INF/MANIFEST.MF
              </manifestFile>
              <!-- For some reason, adding Bundle-ClassPath in maven-bundle-plugin
                   confuses that plugin and it generates wrong Import-Package, etc.
                   So, we generate it here.
              -->
              <manifestEntries>
                <Bundle-ClassPath>WEB-INF/classes/</Bundle-ClassPath>
              </manifestEntries>
            </archive>
            <failOnMissingWebXml>false</failOnMissingWebXml>
          </configuration>
        </plugin>
      </plugins>
      

      The "maven-bundle-plugin" is used to generate the appropriate OSGi metadata and "maven-war-plugin" is used to bundle the WAR file.

  4. Generate the deployable archive as:

    mvn clean package
    

    This generates "target/helloservice-1.0-SNAPSHOT.war". The generated manifest in "target/helloservice-1.0-SNAPSHOT/WEB-INF/classes/META-INF/MANIFEST.MF" looks like:

    Manifest-Version: 1.0
    Export-Package: org.glassfish.samples.osgi.jaxws.webservice;uses:="org
     .glassfish.samples.osgi.hello.service,javax.jws,org.osgi.framework";v
     ersion="1.0.0.SNAPSHOT"
    Bundle-Version: 1.0.0.SNAPSHOT
    Tool: Bnd-0.0.357
    Bundle-Name: helloservice
    Bnd-LastModified: 1272315464139
    Created-By: 1.6.0_17 (Apple Inc.)
    Bundle-ManifestVersion: 2
    Bundle-SymbolicName: org.glassfish.samples.osgi.jaxws.webservice.hello
     service
    Web-ContextPath: helloservice
    Import-Package: javax.jws;version="2.0",org.glassfish.samples.osgi.hel
     lo.service,org.glassfish.samples.osgi.jaxws.webservice;version="1.0",
     org.osgi.framework;version="1.5"
    
  5. Now this archive is a hybrid application, i.e. its a WAR file and an OSGi bundle. So lets deploy this file by copying the file to "domains/domain1/autodeploy/bundles" and see a message like:

    WS00018: Webservice Endpoint deployed App listening at address at http://localhost:8080/helloservice/AppService
    
  6. Accessing "http://localhost:8080/helloservice/AppService" in a browser window shows the following page:

Lets create the client project now to invoke this Web service.

  1. Create a new directory "client" and invoke the following command to generate the client-side artifacts:

    wsimport -keep http://localhost:8080/helloservice/AppService?wsdl
    
  2. Create a new directory "client" and a new file "HelloClient" in that directory as:

    package client;
    
    import org.glassfish.samples.osgi.jaxws.webservice.*
    
    public class HelloClient {
            public static void main(String[] args) throws Exception {
                    App port = new AppService().getAppPort();
                    System.out.println(port.sayHello("Duke"));
            }
    }
    

    This "main" method gets a reference to the generated service class, gets the port from it, and then invokes the method by passing an argument.

  3. Compile the client code as:

    javac -d . -cp . client/HelloClient.java
    
  4. Invoke the client as:

    java -cp . client.HelloClient
    

    to see the result as:

    Hello Duke
    

    This result is coming from the OSGi service implementation.

All the three projects explained above are available in this download.

Using similar concept, a pure OSGi client can invoke a pure OSGi service which can then delegate the actual business method implementation to a JAX-WS endpoint and then use all the goodness of the underlying stack. This way, the benefits of JAX-WS are extended to a pure OSGi client and vice versa.

Also see other OSGi entries on this blog.

Technorati: totd jaxws osgi glassfish v3 webservice

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

January 13, 2010

TOTD #117: Invoke a JAX-WS Web service from a Rails app deployed in GlassFish

Filed under: glassfish, rails, totd, webservices — arungupta @ 8:24 am

A user on GlassFish Forum tried invoking a JAX-WS Web service from a Rails application and faced some issues. This Tip Of The Day (TTOD) will discuss the different approaches and shows their current status.

A Rails app can be deployed on GlassFish in 3 different ways:

  1. Directory Deployment in GlassFish v3 Server – TOTD #72 explains how to deploy a trivial Rails application (with just a scaffold) on GlassFish v3 server. Even though the blog uses a Rails application, any Rack-based application can be deployed on the server. This server is also the Reference Implementation for Java EE 6 and can also run Grails and Django applications.
  2. Directory Deployment using light-weight GlassFish Gem – GlassFish Gem is a light-weight version of the full-blown server and is stripped to run, just like the server, any Rack-based application such as Merb, Rails, and Sinatra. TOTD #70 shows how to deploy the same application using GlassFish Gem.
  3. WAR file in GlassFish v2.x or v3 – TOTD #73 explains how to deploy a Rails application as WAR file on GlassFish v2. The JNDI connection pooling part of the blog may be skipped to simplify the steps but the concepts are still valid. TOTD #44 shows how to do JNDI connection pooling for GlassFish v3. As GlassFish v2 has in-built support for session replication, TOTD #92 demonstrate how Rails application can leverage that functionality.

Now lets get to the issue reported by the user using these 3 deployment models.

First, lets deploy a simple Web service endpoint and generate a JAR file of the client-side artifacts:

  1. This blog will use a simple Web service as defined in screencast #ws7. The Web service endpoint looks like:

    package server;
    
    import javax.jws.WebService;
    
    /**
     * @author arungupta
     */
    @WebService()
    public class HelloService {
     public String sayHello(String name) {
     return "Hello " + name;
     }
    }
    

  2. Generate Web service client-side artifacts as:

    ~/samples/v3/rails/webservice/tmp >wsimport -keep http://localhost:8080/HelloWebService/HelloServiceService?wsdl
    parsing WSDL...
    
    generating code...
    
    compiling code...
    
  3. Create a Web service client jar file as:

    jar cvf wsclient.jar ./server
    

Now lets write a Rails application and invoke this Web service:

  1. Create a simple Rails application as:

    jruby -S rails webservice
    

    Optionally you may specify "-d mysql" to use MySQL database. Or better un-comment the following line:

    # config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
    

    in "config/environment.rb" as no database interaction is required.

  2. Create a controller and view as:

    jruby script/generate controller home index
    
  3. Update the Controller in "app/controllers/home_controller.rb" as:

    include Java
    
    class HomeController < ApplicationController
     def index
     service = Java::server.HelloServiceService.new
     port = service.getHelloServicePort
    
     @result = port.sayHello("Duke")
     end
    
    end
    
  4. Change the View in "app/views/home/index.html.erb" as:

    <h1>Home#index</h1%gt;
    <p>Find me in app/views/home/index.html.erb</p>
    
    <%= @result %>
    

Now lets deploy this Web service using the 3 different deployment models mentioned above.

GlassFish v3 allows a directory-based deployment of Rails applications. This application needs to locate the Web service client classes. The "wsclient.jar" can be copied to the "lib" directory of Rails application ("webservice/lib" in our case), "domains/domain1/lib/ext" or "JRUBY_HOME/lib". The library can also be passed during deployment using "–libraries" switch. None of this approach seem to work correctly as explained in issue# 11408. So for now, invoking a JAX-WS Web service from a Rails application deployed directly on GlassFish v3 is not possible, at least until the bug is fixed.

In order to deploy the same application using GlassFish Gem, you can copy "wsclient.jar" to the "lib" directory of your Rails application. And also add the following line to "app/controllers/home_controller.rb":

require 'lib/wsclient.jar'

Alternatively you can copy it to "JRUBY_HOME/lib" directory if this Web service client is accessed my multiple applications. In this case there is no need to add any "require" statement to your Controller. Anyway, running the application as:

jruby -S glassfish

and accessing "http://localhost:3000/home/index" shows the following output:

And finally as explained in TOTD #73, bundle up your original Rails application as WAR and then deploy on GlassFish v3 as:

asadmin deploy webservice.war

Make sure to copy "wsclient.jar" to the "lib" directory of your Rails application and then Warbler will copy it to "WEB-INF/lib" of the generated WAR file. The output is shown as below:

So if you want to invoke a Metro/JAX-WS Web service from a Rails application, then run your Rails application using GlassFish Gem or deploying as a WAR file. It’ll work on GlassFish v3 server when issue# 11408 is fixed.

Here are some additional links:

  • TOTD #104 also shows how popular Rails applications such as Redmine, Typo, and Substruct can be easily deployed on GlassFish.
  • Rails applications can be easily clustered using Apache + mod_proxy or  nginx.

A complete archive of all the TOTDs is available here.

Technorati: totd glassfish v3 jruby rails webservice jax-ws metro

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

October 8, 2009

TOTD #112: Exposing Oracle database tables as RESTful entities using JAX-RS, GlassFish, and NetBeans

Filed under: frameworks, glassfish, javaee, netbeans, totd, webservices — Tags: , , , , — arungupta @ 2:29 am

This Tip Of The Day explains how to expose an existing Oracle database table as a RESTful Web service endpoint using NetBeans tooling and deployed on GlassFish.

Lets get started!

  1. Configure GlassFish v3 10/7 or a later nightly in a recent NetBeans 6.8 build (latest nightly). As issue# 9885 is fixed, so copy ojdbc6.jar in the "domains/domain1/lib/ext" directory.
  2. Create a Web application

    1. Create a new "Web application" and name the project "RestfulOracle":

      click on "Next >".

    2. Choose the newly added server and "Java EE 6 Web" as the Java EE version:

      and click on "Finish".

  3. Create JPA entities for "HR" schema. The steps outlined below uses NetBeans solely for creating the JPA entities. Alternatively, TOTD #108 explains how to define a JDBC connection pool and JDBC resource using "asadmin" CLI and then use that resource from within NetBeans. Either way, the JDBC resource is stored in the underlying "domain.xml".

    1. Right-click on the project and select "New", "Entity Classes from Database…".
    2. In "Data Source:" select "New Data Source…" as shown below:

    3. Specify the JNDI name as "jdbc/hr" and choose the pre-configured database connection as shown below:

      TOTD #107 explains how to configure Oracle database in NetBeans.

    4. In the list of "Available Tables:", select "EMPLOYEES" and click on "Add >" to see the following:

      Notice the list of related tables are included as well. Click on "Next >".

    5. Specify the package name as "model".
    6. Click on "Create Persistence Unit…", take the defaults, and click on "Create":

      and click on "Finish". Notice EclipseLink, the reference implementation for JPA 2.0, is used as the persistence provider. This generates POJOs that provide database access using JPA 2.0 APIs. These APIs are included as part of the Java EE 6 platform.

  4. Create RESTful entities

    1. Right-click on the project and select "RESTful Web Services from Entity Classes…":

    2. Select "Employees (model.Employees)" from "Available Entity Classes:" and click on "Add >" to see the following:

      click on "Next >", take the defaults, and click on "Finish". This generates a bunch of wrapper classes using JAX-RS to expose the JPA Entity classes as RESTful Web services. JAX-RS 1.1 is also included as part of the Java EE 6 platform.

  5. Run the Web service

    1. Right-click the project and select "Test RESTful Web Services":

      This deploys the created Web application on the selected GlassFish build and displays the following page in the default browser:

    2. Click on "deparmentss" and then on "Test" button to see the output as:

      Clicking the "Test" button issues a GET request to "http://localhost:8080/RestfulOracle/resources/departmentss". This uses the generated JAX-RS wrapper classes to talk to the database using JPA entity classes and query the first 10 rows from the "DEPARTMENTS" table. The response is then JSON formatted using JAX-RS wrapper classes and is returned to the requesting page which then displays it nicely formatted in the table. It also shows l-level deep department’s relationship to other entities. If the "expandLevel" on the above page is set to "0", then the following output is shown:

      The "Raw View" (JSON data) of the original output looks like:

      Notice this is the raw JSON output generated by the JAX-RS wrapper classes. The "Http Monitor" traffic looks like:

      The format of data returned can be changed from "application/json" to "application/xml" as shown below:

      And even a POST request can be generated.

Do you have the need to expose your Oracle database tables as RESTful entities ?

A complete archive of all the TOTDs is available here.

This and other similar applications will be demonstrated at the upcoming Oracle Open World.

Technorati: totd oracle database glassfish v3 netbeans javaee jax-rs jpa rest

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

August 24, 2009

TOTD #98: Create a Metro JAX-WS Web service using GlassFish Tools Bundle for Eclipse

Filed under: eclipse, totd, webservices — Tags: , , , , , , — arungupta @ 11:05 pm

Now that you’ve installed GlassFish Tools Bundle for Eclipse 1.1, lets use this bundle to create a simple Metro/JAX-WS compliant Web service and deploy on GlassFish. These steps will work with either Eclipse 3.4.2 or 3.5 with WTP Java EE support.

  1. Lets create a simple “Dynamic Web Project” as shown below:

  2. Name the project “HelloMetro” and take all other defaults:

    Click on “Finish” to complete the project creation.

  3. Metro allows to create a Web service from a POJO class. So let’s add a POJO to the project by right-clicking on the project and selecting “New”, “Class” as shown below:

      

    Specify the package name as “server”, class name as “HelloService” and click on “Finish”.

  4. Add a simple method to the newly generated class as:

    
    public String sayHello(String name) {
          return "Hello " + name + "!!";
    }
    

  5. Expand the project, go to “HelloService.java” in “server” package, right-click, select “Web Services”, “Create Web service”.
  6. Click on “Web service runtime: Apache Axis” and select “Metro (JAX-WS) Runtime” as the Web service runtime as shown below:

  7. Move the slider on the left to top. This will enable testing of the deployed Web service. The completed configuration looks like:

    and click on “Next >”.

  8. Select the checkbox “Copy Metro library jars to the project” to resolve the references correctly as shown below:

    and click on “Next >”. This bundles the application and deploys to GlassFish and provides an option to test the deployed Web service as shown below:

    Clicking on the “Launch” button shows the following output in the browser:

    The WSDL is hosted at “http://localhost:8083/HelloMetro/HelloServiceService?wsdl”.

  9. Click on “sayHello” method, click on “Add” and enter the value as “Duke” as shown below:

    Click on “Go” and the response is shown as:

    Clicking on “Source” in the response window shows the SOAP request/response messages as shown below:

  10. Alternatively, you can click on “Finish” to complete the dialog. Then click on “Run” menu item, “Launch the Web Services Explorer” to see a screen as:

    Enter the URL of the WSDL in “WSDL URL” box as “http://localhost:8083/HelloMetro/HelloServiceService?wsdl” and click on “Go”. Now you are seeing the similar screen to test the Web service within the integrated browser as shown below:

A future blog will cover how to write a database-enabled application using the bundled Dali JPA Tools and MySQL pre-registered JDBC driver.

Please send your questions and comments to .
Please leave suggestions on other TOTD that you’d like to see. A complete archive of all the tips is available here.

Technorati: totd glassfish eclipse galileo webservices metro jax-ws

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

December 4, 2008

JavaFX 1.0 launched – access services hosted on embedded GlassFish

Filed under: webservices — Tags: , , — arungupta @ 6:30 am

Today Sun announces the availability of Java FX 1.0.

JavaFX 1.0 is a rich client platform for creating and delivering Rich Internet Applications across all screens (desktop, browser, and mobile) of your life. It consists of the following key components:


    • JavaFX SDK includes JavaFX script compiler and runtime tools, and a host of libraries to create RIAs for desktop, browser and mobile platforms, command-line tools & Ant tasks and other goodies.
    • NetBeans 6.5 support (as plugin or bundled with IDE) that allows to build, preview and debug JavaFX applications using NetBeans IDE. If you prefer CLI support then SDK can be downloaded.
    • Production Suite is a suite of tools and plugins for creative tools (such as Illustrator CS3+) that allows graphical assets to be exported to JavaFX applications.

      The beauty of JavaFX is that its fully integrated with the Java Runtime and takes advantage of the performance and ubiquity of Sun’s Java Runtime Environment that is installed on literally billions of devices worldwide. Hence, JavaFX applications will run on any desktop, browser, mobile device or any other connected device that runs the Java Runtime Environment.

      This blog shows how to create a simple JavaFX application using NetBeans IDE. The application plays a movie, allows the viewer to cast a vote if they liked it, and see aggregate response from other viewers. The application is developed using NetBeans 6.5, JavaFX 1.0 plugin, and coded using JavaFX Script. The voting engine is deployed as a RESTful Web service using Jersey on GlassFish.

      In terms of user experience, running the NetBeans project shows a window playing the movie. The first mouse hover over the window allows the viewer to click on “I love it” or “Not so great” and cast their vote as shown below:

      Any subsequent mouse hover shows aggregated results from other viewers as shown below:

      The results are not interesting if there is a single viewer of the movie. But for a production environment, this movie will be played by multiple users concurrently and the percentage numbers will be more meaningful. You can close the window and run the project again to vote again, as many times as you like :)

      For those who like to see quick results, here is a 4-step guide to get started:

      1. In NetBeans 6.5 IDE, install JavaFX plugin as explained here and RESTful Web services plugin as explained here. Both the plugins may be installed in one step by selecting the required plugins together.
      2. Download NetBeans project for JavaFX client from here and add Jersey dependencies as explained in bullet #5 below. 
      3. Download Web service endpoint Maven project from here and deploy the endpoint as explained in bullet #4 below.
      4. Run the JavaFX application as explained here.

      The remainder of this blog explains the details and shows how to construct the demo from scratch.

      Lets first create the JavaFX application that plays the video movie.

      1. In NetBeans 6.5, install “JavaFX SDK” plugin.  In the “Tools” menu, “Plugins”, search on “JavaFX”, select “JavaFX SDK” and click on “Install”.
      2. Create a new project of type “JavaFX”, “JavaFX Script Application”. Take the default values as shown below:

        and click on “Finish”.

      3. The source code for this class can be downloaded from here or alternatively constructed as explained in the sub-bullets.
        1. In the newly created class, change the Stage (root area for all scene content) to:

          Stage {
             title: “GlassFish Media Player”
             width: 625
             height: 360
             resizable: false
             scene: myScene
          }
        2. Create a scene that contains the view of the media to be played and controls the display of the Vote or Result nodes:
          var myScene: Scene = Scene {
             content: MediaView {
                     fitWidth: 625
                     fitHeight: 360
                     mediaPlayer: bind myPlayer

                     onMouseEntered: function( e: MouseEvent ):Void {
                         println(“mouse entered”);
                         if (voted == false) {
                             insert Vote{} into myScene.content;
                         } else {
                             insert Result{} into myScene.content;
                         }
                     }

              &nbs
          p;      onMouseExited: function( e: MouseEvent ):Void {
                         delete myScene.content[1]
                     }

                 }
          }

        3. Create a Media Player to use with the scene:
          var myPlayer: MediaPlayer = MediaPlayer{
              autoPlay: true
              media: bind myMedia
          };
        4. Create the media object to be used with the Media Player:
          var myMedia: Media = Media {
              source: “http://sun.edgeboss.net/download/sun/media/1460825906/1460825906_2957290001_DayEarth-Bluray.flv”
             };

          You can change the location of the movie here in the media player. For example, changing it to “http://mediacast.sun.com/users/ArunGupta/media/v3prelude-nb65-webapp.flv” will start playing the screencast #27.

        5. Create a Vote class that is a CustomNode and appears when a user’s mouse enters the scene where the video is playing. The user can select whether he likes the clip or not and the vote is recorded making a Web service call using Jersey Client APIs:
          class Vote extends CustomNode {
             override function create():Node {
                 return Group {
                     content: [
                         Rectangle {
                             fill: Color.GREEN
                             x: 185
                             y: 145
                             width: 243
                             height: 38
                             arcWidth: 20
                             arcHeight: 20
                         },

                         Text {
                             x: 195
                             y: 170
                             fill: Color.WHITE
                             font: Font {
                                 size: 18
                             }
                             content: "I love it"
                         },

                         Rectangle{
                             x: 191
                             y: 148
                             smooth: false
                             width: 73
                             height: 32
                             fill: Color.TRANSPARENT

                             onMouseClicked: function( e: MouseEvent ):Void {
                                 println("clicked I love it");
                                 voted = true;
                                 wsClient.voteLoveIt();
                                 delete myScene.content[1]
                             }
                         },

                         Text{
                             x: 305
                             y: 170
                             fill: Color.WHITE
                             font: Font {
                                 size: 18
                             }
                             content: “Not so great”
                             },

                         Rectangle {
                             x: 301
                             y: 148
                             smooth: false
             &nbsp
          ;               width: 118
                             height: 32
                             fill: Color.TRANSPARENT
                            
                             onMouseClicked: function( e: MouseEvent ):Void {
                                 voted = true;
                                 println(“clicked Not so great”);
                                 wsClient.voteNotSoGreat();
                                 delete myScene.content[1]
                             }
                         }
                     ]
                 }
             }
          };

        6. Create a Result class that is a CustomNode and simply reports on how many voters like this clip:
          class Result extends CustomNode {
             override function create():Node {
                 var resultPercent = wsClient.showResults();
                 var resultString = “{resultPercent} voters liked this clip”;

                 return Group {
                     content: [
                         Rectangle {
                             fill: Color.BLUE
                             x: 187
                             y: 145
                             width: 244
                             height: 38
                             arcWidth: 20
                             arcHeight: 20

                             onMouseClicked: function( e: MouseEvent ):Void {
                                 delete myScene.content[1]
                             }
                         },

                         Text {
                             x: 199
                             y: 170
                             fill: Color.WHITE
                             font: Font {
                                 size: 18
                             }
                             content: resultString
                         }
                     ]
                 }
             }
          };

        7. Add two instance variables:
          var voted = false;
          var wsClient = new WebserviceClient;

          The first variable captures if the viewer has already voted and the second variable is an instance to the RESTful Web service client.

        8. Add the following import statements:
          import javafx.scene.*;
          import javafx.scene.input.MouseEvent;
          import javafx.scene.media.Media;
          import javafx.scene.media.MediaPlayer;
          import javafx.scene.media.MediaView;
          import javafx.scene.paint.Color;
          import javafx.scene.shape.Rectangle;
          import javafx.scene.text.Font;
          import javafx.scene.text.Text;
          import javafx.stage.Stage;

          “Fix Imports” should be able to fix them and bug #154307 is already filed for that.

      4. Create a new class that is used to capture the Vote as:
        @javax.xml.bind.annotation.XmlRootElement
        public class VoteBean {
            public static enum VOTE { LOVE_IT, NOT_SO_GREAT };
           
            public VOTE vote;

            public VoteBean() { vote = VOTE.LOVE_IT; }
            public VoteBean(VOTE vote) {
                this.vote = vote;
            }
        }

        This is a simple Javabean with a standard JAXB annotation. This ensures that XML is used as the data format for transfering results between client and endpoint. The source code for this class is available here.

      5. Add Jersey libraries to the project by right-clicking on Project, select Libraries, click on “Add Library…”, select “JAX-RS 1.0″ and “Jersey 1.0 (JAX-RS RI)”, and click on “Add Library”.


        ="" src="/wp-content/uploads/2009/08/javafx1.0-nb65-add-jersey-client-libs.png">

        If these libraries are not available then install the “RESTful Web Services” plugin from the Plugin Center.

      6. And finally add the class that invokes the RESTful Webservice endpoint:
        public class WebserviceClient {

            private static com.sun.jersey.api.client.WebResource createWebResource() {
                return com.sun.jersey.api.client.Client.create().
                        resource(“http://localhost:8080/movie-feedback-webapp/webresources/myresource”);
            }

            public static void voteLoveIt() {
                createWebResource().type(“application/json”).
                        post(new VoteBean(VoteBean.VOTE.LOVE_IT));
            }

            public static void voteNotSoGreat() {
                createWebResource().type(“application/json”).
                        post(new VoteBean(VoteBean.VOTE.NOT_SO_GREAT));
            }

            public static String showResults() {
                return createWebResource().get(String.class);
            }
        }

        The Webservice endpoint will be hosted at “http://localhost:8080/movie-feedback-webapp/webresources/myresource”. A WebResource is created from the Client. The POST methods are used to cast the user vote and GET method is used to retrieve the aggregated results. The source code for this class is available here.

      Now lets create the RESTful endpoint using Jersey and deploy on GlassFish.

      1. Create and deploy a RESTful Web service endpoint
        1. Create a template RESTful Web service endpoint as described in TOTD #56. Lets use the artifactId as “movie-feedback-webapp”.
        2. Create the bean “VoteBean” in “org.glassfish.samples” package. This is the exactly same bean used earlier by the client:
          @javax.xml.bind.annotation.XmlRootElement
          public class VoteBean {
              public static enum VOTE { LOVE_IT, NOT_SO_GREAT };
              public VOTE vote;

              public VoteBean() { vote = VOTE.LOVE_IT; }
              public VoteBean(VOTE vote) {
                  this.vote = vote;
              }
          }

        3. Update the generated resource
          1. Add @com.sun.jersey.spi.resource.Singleton as class annotation so that only one instance of the resource is created for the entire web application. This allows to save state (preferences from other users) in the RESTful resource.
          2. Add two instance variables:
                int loveIt;
                int noSoGreat;
          3. Add a method that will process HTTP POST requests as:
                @POST
                public void postOneVote(VoteBean bean) {
                    if (bean.vote == VoteBean.VOTE.LOVE_IT) {
                        loveIt++;
                    } else {
                        noSoGreat++;
                    }
                    System.out.println(“In POST: ” + bean.vote);
                }

            This method stores the vote in the resource. The handling of POST request messages by Jersey is explained in TOTD #58.

          4. Add a method that will process HTTP GET requests as:
                @GET
                @Produces(“text/plain”)
                public String getOpinion() {
                    if (loveIt == 0 && noSoGreat == 0)
                        return “No votes cast yet!”;
                    return (loveIt * 100) / (loveIt + noSoGreat) + “%”;
                }

            This method calculates the percentage of viewers who liked the movie.

        4. Deploy the endpoint using “mvn glassfish:run” in “movie-feedback-webapp” directory.

      Now run the JavaFX application by right-clicking on the project and selecting “Run Project” and start voting! The percentage results will vary if the movie is voted upon more than once.

      This blog showed:

      • How to install JavaFX capabilities to an existing NetBeans 6.5 installation
      • How to create a simple JavaFX application that plays media files
      • Integrate it with existing Java libraries (Jersey client libraries in this case)
      • Invoke services hosted on GlassFish

      The steps followed in this blog allows for rapid development/debugging of JavaFX application accessing resources using embeddable GlassFish but are not ideal for production deployments. A future blog will show how this JavaFX application can be deployed as a Java Web Start application and scaled for mulitple users.

      The javafx.com/samples has loads of samples and javafx.com/tutorials shows how to build your own applications. The JavaFX Community Wiki is a great place to collaborate.

      Send your Jersey questions to , GlassFish questions to GlassFish Forum, and JavaFX questions to JavaFX Forums.

      Technorati: glassfish v3 jersey webservices javafx netbeans

      Share and Enjoy:
      • Print
      • Digg
      • Sphinn
      • del.icio.us
      • Facebook
      • Google Bookmarks
      • DZone
      • StumbleUpon
      • Technorati
      • Twitter
      • Slashdot

      December 1, 2008

      TOTD #58: Jersey and GlassFish – how to process POST requests ?

      Filed under: totd, webservices — arungupta @ 5:00 am

      Lets extend the Jersey endpoint (TOTD# 56) and client (TOTD# 57) such that it can accept a POST request and then invoke it.

      1. Add a new method to “MyResource.java” from TOTD# 56 as:

            @POST
            @Consumes(“application/json”)
            @Produces(“application/json”)
            public Greeting postIt(Greeting greeting) {
                System.out.println(“In POST: ” + greeting.greeting);
                return greeting;
            }

        The first line indicates that the Java method will process HTTP POST requests. The second and third line shows that the method consumes and produces JSON data format.

      2. Add a new method to “AppTest.java” from TOTD# 57 as:
            public void testPost() {
                Greeting result = createResource().
                        type(“application/json”).
                        post(Greeting.class, new Greeting(“yo!”));
                assertTrue(result.greeting.equals(“yo!”));
            }

        The main difference from the “testApp()” method is specifying the MIME type of the generated outbound request as “application/json”.

      3. Running the test as “mvn test” shows the following output:
        Running org.glassfish.samples.AppTest
        1 * Out-bound request
        1 > GET http://localhost:8080/helloworld-webapp/webresources/myresource
        1 >
        1 < 200
        1 < X-Powered-By: Servlet/2.5
        1 < Transfer-Encoding: chunked
        1 < Content-Type: text/plain
        1 < Server: GlassFish/v3
        1 < Date: Tue, 25 Nov 2008 20:19:34 GMT
        1 <
        <?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes”?><greeting><greeting>Hi there!</greeting></greeting>
        1 * In-bound response
        1 * Out-bound request
        1 > POST http://localhost:8080/helloworld-webapp/webresources/myresource
        1 > Content-Type: application/json
        1 >
        {“greeting”:”yo!”}
        1 < 200
        1 < X-Powered-By: Servlet/2.5
        1 < Transfer-Encoding: chunked
        1 < Content-Type: application/json
        1 < Server: GlassFish/v3
        1 < Date: Tue, 25 Nov 2008 20:19:34 GMT
        1 <
        {“greeting”:”yo!”}
        1 * In-bound response
        Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.191 sec

        The output shows request/response messages when both the tests are run together. Here are some highlights:

        1. “GET” and “POST” methods are clearly highlighted.
        2. The two “Content-Type” headers with value “text/plain” and ”application/json” are output from two tests. The output from POST method has two Content-Type headers, one for outbound request and another one for inbound response.
        3. The body content of POST method is using JSON format.

      Jersey and GlassFish provides a complete server-side and client-side API and framework for deploying and invoking RESTful Web service endpoints.

      How are you using Jersey ?

      Send all your questions to .

      Please leave suggestions on other TOTD (Tip Of The Day) that you’d like to see. An archive of all the tips is available here.

      Technorati: totd glassfish v3 embeddable jersey jsr311 rest json webservices

      Share and Enjoy:
      • Print
      • Digg
      • Sphinn
      • del.icio.us
      • Facebook
      • Google Bookmarks
      • DZone
      • StumbleUpon
      • Technorati
      • Twitter
      • Slashdot

      November 26, 2008

      TOTD #57: Jersey Client API – simple and easy to use

      Filed under: totd, webservices — Tags: , , , , , , , , — arungupta @ 5:00 am

      TOTD #56 explains how to create a RESTful Web service endpoint using Jersey and publish the resource using JSON representation. The blog entry showed how the endpoint can be accessed from a Web browser. This Tip Of The Day explains how to use Jersey Client APIs to invoke the published endpoint.

      Lets get started!

      1. Create a new directory “./src/test/java/org/glassfish/samples”
      2. Add a test
        1. Add a template test file “AppTest.java” as shown below:

          package org.glassfish.samples;

          import junit.framework.Test;
          import junit.framework.TestCase;
          import junit.framework.TestSuite;

          /**
           * Unit test for simple App.
           */
          public class AppTest
              extends TestCase
          {
              /**
               * Create the test case
               *
               * @param testName name of the test case
               */
              public AppTest( String testName )
              {
                  super( testName );
              }

              /**
               * @return the suite of tests being tested
               */
              public static Test suite()
              {
                  return new TestSuite( AppTest.class );
              }

              /**
               * Rigourous Test :-)
               */
              public void testApp()
              {
                  assertTrue(true);
              }
          }

        2. Add a new method “createResource()” as:
              private WebResource createResource() {
                  Client client = Client.create();
                  WebResource resource = client.resource(“http://localhost:8080/helloworld-webapp/webresources/myresource”);
                  return resource;
              }

          This code creates a default instance of Jersey Client and creates a Web resource from that client for the URI passed as an argument.

        3. Change the implementation of “testApp()” method as:
                  Greeting result = createResource().get(Greeting.class);
                  assertTrue(result.greeting.equals(“Hi there!”));

          This invokes the GET method on the resource by passing specific type and compares the returned and expected value.

        4. Add the following “imports”:
          import com.sun.jersey.api.client.Client;
          import com.sun.jersey.api.client.WebResource;
        5. Copy “Greeting.java” from TOTD #56 to ”./src/test/java/org/glassfish/samples” directory.
      3. Run the test
        1. Deploy the endpoint as “mvn glassfish:run”.
        2. Run the test as “mvn test”. The following output is shown:
          ~/samples/jersey/helloworld-webapp >mvn test
          [INFO] Scanning for projects…
          [INFO] ————————————————————————
          [INFO] Building helloworld-webapp Jersey Webapp
          [INFO]    task-segment: [test]
          [INFO] ————————————————————————
          [INFO] [resources:resources]
          [INFO] Using default encoding to copy filtered resources.
          [INFO] [compiler:compile]
          [INFO] Nothing to compile – all classes are up to date
          [INFO] [resources:testResources]
          [INFO] Using default encoding to copy filtered resources.
          [INFO] [compiler:testCompile]
          [INFO] Compiling 1 source file to /Users/arungupta/samples/jersey/helloworld-webapp/target/test-classes
          [INFO] [surefire:test]
          [INFO] Surefire report directory: /Users/arungupta/samples/jersey/helloworld-webapp/target/surefire-reports

          ——————————————————-
           T E S T S
          ——————————————————-
          Running org.glassfish.samples.AppTest
          Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.587 sec

          Results :

          Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

          [INFO] ————————————————————————
          [INFO] BUILD SUCCESSFUL
          [INFO] ————————————————————————
          [INFO] Total time: 4 seconds
          [INFO] Finished at: Mon Nov 24 16:50:17 PST 2008
          [INFO] Final Memory: 18M/43M
          [INFO] ————————————————————————

      4. View request and response messages
        1. Change the implementation of “createResource()” method as (changes highlighted in bold):

                  Client client = Client.create();
                  WebResource resource = client.resource(“http://localhost:8080/helloworld-webapp/webresources/myresource”);
                  resource.addFilter(new LoggingFilter());
                  return resource;
        2. Running the tests as “mvn test” now shows the output, with request and response messages, as shown below:
          Running org.glassfish.samples.AppTest
          1 * Out-bound request
          1 > GET http://localhost:8080/helloworld-webapp/webresources/myresource
          1 >
          1 < 200
          1 < X-Powered-By: Servlet/2.5
          1 < Transfer-Encoding: chunked
          1 < Content-Type: application/json
          1 < Server: GlassFish/v3
          1 < Date: Tue, 25 Nov 2008 07:07:51 GMT
          1 <
          {“greeting”:”Hi there!”}
          1 * In-bound response
          Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.074 sec

      Really easy!

      Even though the APIs are used to invoke a RESTful endpoint deployed using Jersey but are very generic and can be used to invoke any RESTful endpoint. Paul’s blog explain in detail on the usage. You can also see how these APIs can be used to consume a service hosted using Apache Abdera.

      com.sun.jersey.api.client, com.sun.jersey.api.client.config, and com.sun.jersey.api.client.filter packages documents all the classes that provide support for client-side communication with HTTP-based RESTful Web services.

      Technorati: totd glassfish v3 embeddable jersey jsr311 rest json webservices

      Share and Enjoy:
      • Print
      • Digg
      • Sphinn
      • del.icio.us
      • Facebook
      • Google Bookmarks
      • DZone
      • StumbleUpon
      • Technorati
      • Twitter
      • Slashdot

      November 25, 2008

      TOTD #56: Simple RESTful Web service using Jersey and Embeddable GlassFish – Text and JSON output

      Filed under: totd, webservices — arungupta @ 5:00 am


      Jersey is the open source, production quality, JAX-RS (JSR 311) Reference Implementation for building RESTful Web services in the GlassFish community. It also provides an API that allows developers to extend Jersey to suite their requirements.

      This Tip Of The Day (TOTD) shows how to create a simple RESTful Web service using Jersey and run it using embeddable GlassFish (glassfish:run). Maven is used to create and run the application. It also shows how the output format can be easily coverted from Text to JSON.

      Lets get started!

      1. Create a simple web app using Maven as:

        ~/samples/jersey >mvn archetype:generate -DarchetypeCatalog=http://download.java.net/maven/2
        [INFO] Scanning for projects…
        [INFO] Searching repository for plugin with prefix: ‘archetype’.
        [INFO] ————————————————————————
        [INFO] Building Maven Default Project
        [INFO]    task-segment: [archetype:generate] (aggregator-style)
        [INFO] ————————————————————————
        [INFO] Preparing archetype:generate
        [INFO] No goals needed for project – skipping
        [INFO] Setting property: classpath.resource.loader.class => ‘org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader’.
        [INFO] Setting property: velocimacro.messages.on => ‘false’.
        [INFO] Setting property: resource.loader => ‘classpath’.
        [INFO] Setting property: resource.manager.logwhenfound => ‘false’.
        [INFO] [archetype:generate]
        [INFO] Generating project in Interactive mode
        [INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
        Choose archetype:
        1: remote -> jersey-quickstart-grizzly (Archetype for creating a RESTful web application with Jersey and Grizzly)
        2: remote -> jersey-quickstart-webapp (Archetype for creating a Jersey based RESTful web application WAR packaging)
        Choose a number:  (1/2): 2
        [INFO] snapshot com.sun.jersey.archetypes:jersey-quickstart-webapp:1.0.1-SNAPSHOT: checking for updates from jersey-quickstart-webapp-repo
        Define value for groupId: : org.glassfish.samples
        Define value for artifactId: : helloworld-webapp
        Define value for version:  1.0-SNAPSHOT: :
        Define value for package: : org.glassfish.samples
        Confirm properties configuration:
        groupId: org.glassfish.samples
        artifactId: helloworld-webapp
        version: 1.0-SNAPSHOT
        package: org.glassfish.samples
         Y: :
        [INFO] —————————————————————————-
        [INFO] Using following parameters for creating OldArchetype: jersey-quickstart-webapp:1.0.1-SNAPSHOT
        [INFO] —————————————————————————-
        [INFO] Parameter: groupId, Value: org.glassfish.samples
        [INFO] Parameter: packageName, Value: org.glassfish.samples
        [INFO] Parameter: package, Value: org.glassfish.samples
        [INFO] Parameter: artifactId, Value: helloworld-webapp
        [INFO] Parameter: basedir, Value: /Users/arungupta/samples/jersey
        [INFO] Parameter: version, Value: 1.0-SNAPSHOT
        [INFO] ********************* End of debug info from resources from generated POM ***********************
        [INFO] OldArchetype created in dir: /Users/arungupta/samples/jersey/helloworld-webapp
        [INFO] ————————————————————————
        [INFO] BUILD SUCCESSFUL
        [INFO] ————————————————————————
        [INFO] Total time: 21 seconds
        [INFO] Finished at: Mon Nov 24 14:09:27 PST 2008
        [INFO] Final Memory: 12M/30M
        [INFO] ————————————————————————
      2. Edit the generated “pom.xml” to add dependencies on GlassFish plugin
        1. Add the following plugin in the “pom.xml” under <build>/<plugins>:

                      <plugin>
                          <groupId>org.glassfish</groupId>
                          <artifactId>maven-glassfish-plugin</artifactId>
                      </plugin>
        2. Add the following plugin repositories:
              <pluginRepositories>
                  <pluginRepository>
                      <id>maven2-repository.dev.java.net</id>
                      <name>Java.net Repository for Maven</name>
                      <url>http://download.java.net/maven/2/</url>
                      <layout>default</layout>
                  </pluginRepository>
                  <pluginRepository>
                      <id>maven-repository.dev.java.net</id>
                      <name>Java.net Maven 1 Repository (legacy)</name>
                      <url>http://download.java.net/maven/1</url>
                      <layout>legacy</layout>
                  </pluginRepository>
              </pluginRepositories>
        3. Optionally, if the generated dependencies in “pom.xml” as shown below:
                  <dependency>
                      <groupId>org.glassfish.distributions</groupId>
                      <artifactId>web-all</artifactId>
           
                     <version>10.0-build-20080430</version>
                      <scope>test</scope>
                  </dependency>
                  <dependency>
                      <groupId>org.glassfish.embedded</groupId>
                      <artifactId>gf-embedded-api</artifactId>
                      <version>1.0-alpha-4</version>
                      <scope>test</scope>
                  </dependency>

          are changed to:

                  <dependency>
                      <groupId>org.glassfish.distributions</groupId>
                      <artifactId>web-all</artifactId>
                      <version>10.0-SNAPSHOT</version>
                      <scope>test</scope>
                  </dependency>
                  <dependency>
                     <groupId>org.glassfish.embedded</groupId>
                     <artifactId>glassfish-embedded-all</artifactId>
                     <version>3.0-Prelude-SNAPSHOT</version>
                  </dependency>

          then the latest version of Embedded GlassFish APIs are used.

        4. Also optionally, if you want to run against Jersey 1.0 bits then change the following property from “1.0.1-SNAPSHOT” to “1.0″.
              <properties>
                  <jersey-version>1.0</jersey-version>
              </properties>
      3. Run the application
        1. The generated source code is:

          package org.glassfish.samples;

          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 “/helloworld”
          @Path(“/myresource”)
          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!”;
              }
          }

          Invoking “mvn glassfish:run” starts the embedded GlassFish and shows the following output:

          ~/samples/jersey/helloworld-webapp >mvn glassfish:run
          [INFO] Scanning for projects…
          [INFO] Searching repository for plugin with prefix: ‘glassfish’.
          [INFO] ————————————————————————
          [INFO] Building helloworld-webapp Jersey Webapp
          [INFO]    task-segment: [glassfish:run]
          [INFO] ————————————————————————
          [INFO] Preparing glassfish:run
          [INFO] [resources:resources]
          [INFO] Using default encoding to copy filtered resources.
          [INFO] [compiler:compile]
          [INFO] Compiling 1 source file to /Users/arungupta/samples/jersey/helloworld-webapp/target/classes
          [INFO] [glassfish:run]
          Nov 24, 2008 2:36:05 PM com.sun.enterprise.v3.server.AppServerStartup run
          INFO: HK2 initialized in 229 ms
          Nov 24, 2008 2:36:05 PM com.sun.enterprise.v3.server.AppServerStartup run
          INFO: com.sun.enterprise.naming.impl.ServicesHookup@2470b02c Init done in 237 ms
          Nov 24, 2008 2:36:05 PM com.sun.enterprise.v3.server.AppServerStartup run
          INFO: com.sun.enterprise.v3.server.Globals@13b3d787 Init done in 239 ms
          Nov 24, 2008 2:36:05 PM com.sun.enterprise.v3.server.AppServerStartup run
          INFO: com.sun.enterprise.v3.server.SystemTasks@61bedd7d Init done in 244 ms
          Nov 24, 2008 2:36:05 PM com.sun.enterprise.v3.server.AppServerStartup run
          INFO: com.sun.enterprise.v3.services.impl.HouseKeeper@2b9f7952 Init done in 245 ms
          Nov 24, 2008 2:36:05 PM com.sun.enterprise.v3.server.AppServerStartup run
          INFO: com.sun.enterprise.v3.services.impl.CmdLineParamProcessor@5249d560 Init done in 248 ms
          JMXMP connector server URL = service:jmx:jmxmp://localhost:8888
          Nov 24, 2008 2:36:05 PM com.sun.enterprise.v3.services.impl.GrizzlyProxy start
          INFO: Listening on port 8080
          Nov 24, 2008 2:36:06 PM com.sun.enterprise.v3.server.AppServerStartup run
          INFO: com.sun.enterprise.v3.services.impl.GrizzlyService@1baa56a2 startup done in 551 ms
          Nov 24, 2008 2:36:06 PM com.sun.enterprise.v3.services.impl.ApplicationLoaderService postConstruct
          INFO: loader service postConstruct started at 1227566166208
          Nov 24, 2008 2:36:06 PM com.sun.enterprise.v3.server.AppServerStartup run
          INFO: Application Loader startup done in 740 ms
          Nov 24, 2008 2:36:06 PM com.sun.enterprise.v3.server.AppServerStartup run
          INFO: Glassfish v3 started in 740 ms
          Nov 24, 2008 2:36:07 PM com.sun.enterprise.web.WebModuleContextConfig authenticatorConfig
          SEVERE: webModuleContextConfig.missingRealm
          Nov 24, 2008 2:36:07 PM com.sun.jersey.api.core.PackagesResourceConfig init
          INFO: Scanning for root resource and provider classes in the packages:
            org.glassfish.samples
          Nov 24, 2008 2:36:07 PM com.sun.jersey.api.core.PackagesResourceConfig init
          INFO: Root resource classes found:
            class org.glassfish.samples.MyResource
          Nov 24, 2008 2:36:07 PM com.sun.jersey.api.core.PackagesResourceConfig init
          INFO: Provider classes found:
          Hit ENTER for redeploy

          Notice how GlassFish v3 starts up in sub-second (740 ms in this case).

        2. “http://localhost:8080/helloworld-webapp” shows the following output:

        3. Clicking on “Jersey resource” redirects to “http://localhost:8080/helloworld-webapp/webresources/myresource” and shows the following output:

      4. Change the output representation to produce JSON representation
        1. Add a new JAXB bean:

          package org.glassfish.samples;

          import javax.xml.bind.annotation.XmlRootElement;

          /**
           * @author arungupta
           */
          @XmlRootElement
          public class Greeting {
              public String greeting;

              public Greeting() { }
              public Greeting(String greeting) {
                  this.greeting = greeting;
              }
          }

        2. Change the method implementation in MyResource as:
          //    @Produces(“text/plain”)
              @Produces(“application/json”)
              public Greeting getIt() {
                  return new Greeting(“Hi there!”);
              }
        3. And now “http://localhost:8080/helloworld-webapp/webresources/myresource” shows the following output:

          Notice the output is now in JSON format.

      5. Optionally a WAR file can be created using the command:
        mvn clean package

        and the WAR file is generated in “target/helloworld-webapp.war”. If Jersey is installed using GlassFish v3 Update Center then you can use “maven-assembly-plugin” to customize packaging of WAR and drastically reduce the size.

      The JSON representation can be configured in multiple ways as explained in Configuring JSON for RESTful Web Services in Jersey 1.0. This has certainly come a long way from TOTD #8 and is much more effecient now.

      The Jersey Wiki documents an extensive set of resources to get started.

      Send all your questions to .

      Please leave suggestions on other TOTD (Tip Of The Day) that you’d like to see. An archive of all the tips is available here.

      Technorati: totd glassfish v3 embeddable jersey jsr311 rest json webservices

      Share and Enjoy:
      • Print
      • Digg
      • Sphinn
      • del.icio.us
      • Facebook
      • Google Bookmarks
      • DZone
      • StumbleUpon
      • Technorati
      • Twitter
      • Slashdot
      Older Posts »

      The views expressed on this blog are my own and do not necessarily reflect the views of Oracle.
      Powered by WordPress