Miles to go …

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

      January 31, 2008

      TOTD #23: JavaFX Client invoking a Metro endpoint

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

      This TOTD is inspired by Learning JavaFX Script – Part 3. The original article explains how to invoke a Web service from a JavaFX client using NetBeans 5.5.1 and GlassFish v1. Newer version of both NetBeans and GlassFish are available since the article was written. This TOTD (tip of the day) explains how to invoke a Metro endpoint deployed on GlassFish v2 from a JavaFX client – all using NetBeans 6.

      1. Following screencast #ws7, create a plain (without Security or Reliability enabled) Metro endpoint using NetBeans 6 and GlassFish v2.
      2. In NetBeans 6 IDE, install the JavaFX plugin as described here.
      3. Create Web service client library – Creating a Web service client in JavaFX Script Application is causing a NullPointerException (issue #126352). The workaround I used is to create a separate library with client-side artifacts and then include it as dependency in the JavaFX client project.
        1. Create a new project of type "Java Class Library" as shown below:

          and click on "Finish".

        2. Enter the project name as "MetroClientLibrary" as shown below:

          and click on "Finish".

        3. Right-click on the newly created project, select "New", "Web Service Client...".
        4. Click on "Browse..." button next to "Project" radio button and select the deployed Web service from Metro endpoint project. If the Web service is deployed on a different machine then you may specify the WSDL URL. Specify the package name "client" as shown below:

          and click on "Finish".

        5. Once the Web service client-side artifacts are generated (indicated by expandable Web Service References tree node), right-click on the project and select "Build". This generates a JAR file that will be utilized later. The location of this jar file is shown in the Output console. In our case, it is

          C:\workarea\samples\javafx\MetroClientLibrary\dist\MetroClientLibrary.jar.

      4. Create JavaFX project
        1. Create a new JavaFX project by right-clicking in the Project explorer, selecting "New Project" and entering the values as shown below:

        2. Click on "Next >" and enter the values as shown below:

          and click on "Finish".

        3. Right-click on the newly created project, "Properties", "Libraries", "Add JAR/Folder" and select the JAR file created in "MetroClientLibrary" project as shown below:

          and click on "OK".

          Notice, Java SE 6 U4 is used to compile and run this project. If you are using an earlier version of Java SE 6, then you need to override JAX-WS 2.1 and JAXB 2.1 jars using endorsed mechanism as explained here. The classes in these jars are already bundled in Java SE 6 U4.

        4. In metroclient.Main.fx file, replace "// place your code here" with the following code:

          import java.lang.*;
          import javafx.ui.*;

          import client.NewWebServiceService;
          import client.NewWebService;

          class InputModel {
              attribute name: String?;
          }
          var inputModel = InputModel { };
          var nameField = TextField { };
          nameField.action = operation() {
              inputModel.name = nameField.value;
          };

          class ButtonClickModel {
              attribute result: String;
          }
          var model = new ButtonClickModel();

          Frame {
              title: "JavaFX Client -> Metro endpoint"
              width: 350
              height: 200
              content: GridPanel {
                  rows: 3
                  vgap: 5
                  cells:
                  [SimpleLabel {
                      text: "Name : "
                  },
                  nameField,
                  SimpleLabel {
                      text: "Result from endpoint : "
                  },
                  Label {
                      text: bind "{model.result}"
                  },
                  Button {
                      text: "Invoke Web Service!"
                      action: operation() {
                          do {
                              try {
                                  var service: NewWebServiceService = new NewWebServiceService();
                                  var port: NewWebService = service.getNewWebServicePort();
                                  var name: String = "{nameField.value}";
                                  var result: String = port.sayHello(name);
                                  System.out.println("response: {result}");
                                  model.result = result;
                          &nb
          sp;   } catch (e:Exception) {
                                  System.out.println("exception: {e}");
                              }
                          }
                      }
                  }
                  ]
              }
              visible: true
          };

      5. Invoke the JavaFX client project
        1. Right-click on the recently create project ("MetroClient") and select "Run Project". The following window is displayed:

        2. Enter "Duke" in the text box and click on "Invoke Web Service!" button to see the result as shown below:

      After following these steps, you have created a JavaFX client that can invoke a Metro endpoint project deployed on GlassFish – all using NetBeans IDE.

      Now Metro provides secure, reliable, transactional and .NET 3.0 interoperable Web service. Have you tried/used any of those features in Metro ?

      Please leave suggestions on other TOTD that you’d like to see. A complete archive is available here.

      Technorati: totdd javafx metro glassfish netbeans webservices

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

      September 5, 2007

      jMaki + JavaFX @ The Rich Web Experience 2007

      Filed under: web2.0 — Tags: , — arungupta @ 12:02 am

      Sun Microsystems is a silver sponsor of The 2007 Rich Web Experience. This conference is targeted for web designers, software architects, programmers, developers, and technical managers interested in learning about the hot areas in Web. JavaScript, Ajax, CSS, RIA, Design and much more content related to Web will be covered in 6 parallel tracks in 50 sessions by over 35 speakers.

      Venue: Fairmont San Jose
      Dates: Sep 6-8, 2007
      Session Schedule

      Here is the list of Sun’s presence:

      Project jMaki – Enabling Web 2.0 Application Developers Greg Murray Sep 6, Thu 11am-12:30pm
      Web Design for Server-Side Developers Greg Murray Sep 6, Thu 4:45pm-6:15pm
      JavaFX: Evolution of the Java client Nandini Ramani Sep 7, Fri 3pm-4:30pm

      There will be table tops also where you can mingle with the speakers and the rest of us. We will be showing jMaki and JavaFX demos and open for discussions on any other related topic. And if you drop your visiting card with you,

      We have a brand new COOL tee-shirt as a give away. Just talk to one of us and listen to our demos and it’ll be yours :)

      Technorati: jmaki javafx richwebexperience conf sun

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

      Powered by WordPress