SLIDE 1
Lab-S313674 : Build a GlassFish JavaFX Monitoring Application using REST monitoring API
David Delabassée
Senior Solution Architect, Oracle Belgium
Sébastien Stormacq
Senior Solution Architect, Oracle Luxembourg
SLIDE 2 JavaOne|Oracle Develop Build a GlassFish JavaFX Monitoring Application using REST monitoring API Hands-on Lab: S313674
Introduction
Building Rich Internet Applications using the traditional Java SE™ platform is a cumbersome task, often reserved to the most seasoned Java™ developers, those mastering Java 2D and Java 3D APIs. JavaFX, introduced in December 2008, is changing the rules of the game. JavaFX provides Java™ developers and graphic designers alike a powerfull scripting language and graphic API, allowing developers to build rich graphical applications very easily. But JavaFX alone will only help to build a graphical front end, while most business oriented applications will require some backend services to provide the data to the end user. Efficient web services communication will therefore be a requirement to any business JavaFX project. This lab introduces web communications between JavaFX graphical applications and server based web services. This lab uses GlassFish's RESTful web service monitoring API on the backend, JSON as the data format to be exchanged between the web service and the graphical application and Jersey (JAX-RS) API as REST API to be used from JavaFX.
Prerequisites
This hands-on lab assumes you have basic experience with the following technologies:
- Java™ language programming
- Basic JavaFX understanding, i.e. this lab will not teach you the basic of the JavaFX syntax, the Scene
graph etc ... You can refer to the officials JavaFX Tutorials to help you to start with JavaFX.
Notations Use In This Documentation
<lab_root> The directory into which the lab contents were placed, i.e. where this document lives <netbeans_project> The directory where the NetBeans project is created. By default, this $HOME/NetBeansProjects/S313674_JavaFX_GF_Monitoring unless you will specify a different directory and/or project name when you will create the project.
Lab Exercises
1. Create a reusable JavaFX LineChart component 2. Get use to and test GlassFish's REST monitoring API 3. Call GlassFish's Monitoring API from JavaFX 4. Add polling to your JavaFX application
Please feel free to seek assistance from the instructor or Oracle Demo staff at any point during the lab.
Page 2 of 49
SLIDE 3 Exercise 1: Create a reusable JavaFX line chart component
This exercise provides the instructions to build our first JavaFX component. We will create an animated line chart component, i.e. a component that will display a line graph, with a single line. When an application will add values to the graph, the line will move to the left side to display the new value and discard the oldest values, creating the appearance of an animation.
Background Information
Creating a custom JavaFX component.
Creating a custom component for JavaFX is a three step process :
- Create a class that will extend javafx.scene.CustomNode
- Override the init { } block to create your own scene graph and included into the children property of
the CustomNode
- Add whatever public properties and functions that make sense for your component. This will be the
interface clients can use to interact with your component. CustomNode class has a special property named children. It is an array of javafx.scene.Node objects. Laying out your own components is done through adding your Node to the children array. This is usually done in the init block of your CustomNode The interface that clients will use to create and communicate with your custom component is made of properties, i.e. values that you can set or read. And, functions that you can call or that are called back for notifications. A well designed component will only provide public access properties and function as interface. The interface must be designed as the contract between your component and its clients. This exercise is divided in two parts :
- 1. The first part gives instructions to create an Animated Line Chart component
- 2. The second part explains how to create a test application to actually display the Animated Line Chart
component created during step #1 The video above shows the end result at the end of this exercise.
Steps to Follow
Step 1.1: Create the Project
- 1. If NetBeans is not already running, start it.
- 2. When NetBeans has started, select "New Project" from the "File" menu.
Page 3 of 49
SLIDE 4
- 3. Browse to the JavaFX category, choose JavaFX Script Application and click Next
- 4. Type a name in Project Name: (such as Lab-S313674 for example), and click Finish:
Page 4 of 49
SLIDE 5
- 5. NetBeans will create a project and an application skeleton. The main class is Main in package
labs313674 Page 5 of 49
SLIDE 6
Tip - How to reuse our source code ? The full source code, without line number for easy copy/paste, is provided in <lab-root>/solutions directory
1 /* 2 * To change this template, choose Tools | Templates 3 * and open the template in the editor. 4 */ 5 6 package lab_s313674; 7 8 import javafx.stage.Stage; 9 import javafx.scene.Scene; 10import javafx.scene.text.Text; 11import javafx.scene.text.Font; 12 13 /** 14 * @author sst 15 */ 16 17 Stage { 18 title: "Application title" 19 scene: Scene { 20 width: 250 21 height: 80 22 content: [ 23 Text { 24 font : Font { 25 size : 16 26 } 27 x: 10 28 y: 30 29 content: "Application content" 30 } 31 ] 32 } 33 }
Show Line Numbers in NetBeans Editor You can turn on the line numbers in NetBeans' editor, select the "View" menu and click on "Show Line Numbers", as shown below. Page 6 of 49
SLIDE 7 Let's have a look at your first JavaFX application !
- Line 8-11 are traditional package declarations and import statements, just like you are used to.
- Line 17 is the declaration of the top-level Window, the Stage. Stage is a JavaFX class, with its attributes
being defined between the braces.
- title is a Stage attribute.
- scene at line 19 will define the content of the Stage. Its is another class instance, a Scene, having its own
set of attributes, between braces.
- width, height are Scene attributes.
- The content of the Scene is a single Text component (line 23), itself having a Font attribute (line 24) and
a text content (line 29) To launch the application, select "Run Main Project" from NetBeans' "Run" menu (or click on the green right arrow in the NetBeans' toolbar) Tip Page 7 of 49
SLIDE 8 Depending on the platform and the NetBeans version used : when running JavaFX for the first time after installing the NetBeans plugin, an "accept" window might be displayed before the application runs. Should this "accept" window appears, click on "Accept" to further proceed. The application should look like this :
Step 1.2: Create a custom Animated Line Chart Component
The second step from this Exercise 1 is to create a new class to define our Animated Line Chart Component. This class will offer a very simple interface to its clients and will be based on the JavaFX javafx.scene.chart.LineChart component.
- 1. Select the labs313674 package in your project, right click the mouse button and choose "New..." then
"JavaFX Class" Name your class AnimatedLineChart and define its package. To do this you click on the 'Package' drop- down to have the list of available packages in your project. Page 8 of 49
SLIDE 9 Click Finish and the class will be created. NetBeans should open an editor window that will let us edit the source code of the class.
- 2. Add the extends JavaFX keyword to inherit from javafx.scene.CustomNode
public class AnimatedLineChart extends CustomNode {
- 3. Define the public interface properties of your component, these are the attributes any client class will use to
customize this component :
//public properties public var title : String; public var lineName : String; public var xMaxValue : Integer; public var yMaxValue : Integer;
- title and linename will hold the graph's title and the line legend respectively
- xMaxValue and ymaxValue will define the upper bound on the X and Y axis respectively
Page 9 of 49
SLIDE 10
- 4. Define the public method that will be used to add values to the graph. This method will be implemented
later
//public function public function addValue(v:Integer) {}
This method will be called by our clients when they want to add a value to the graph. This is where "the animation" logic will be added.
- 5. The last step before actually implementing our interface is to define the components that we will assemble
to create our custom component, in our case a single LineChart component. This is done by defining a content for the init block. The init block is an optional block of code which is executed as the final step of instance initialization.
init { insert LineChart { showSymbols: false; title: bind title legendSide: Side.RIGHT legendVisible: true xAxis: NumberAxis { label: "Time (sec.)" lowerBound: 0 upperBound: bind xMaxValue minorTickVisible: true tickUnit: 5 minorTickCount: 5 tickLabelsVisible: false } yAxis: NumberAxis { lowerBound: 0 upperBound: bind yMaxValue formatTickLabel: function(value) { "{%.0f value}" } } data: [ LineChart.Series { name: bind lineName data: bind values } ] } into children; }
Let's examine this block of code :
- This init block is made of a single statement insert ... into .... It does create a
LineChart JavaFX component and insert it into CustomNode's children array of child nodes.
- The LineChart itself is made of four main blocks
- 1. a set of properties that will define how the LineChart will look like
- 2. a xAxis object defining the properties and the look and feel of the XAxis
- 3. a yAxis object defining the properties and the look and feel of the YAxis
- 4. a data property, defined as an array of LineChart.Series objects. This is the actual
value to be displayed on the graph, i.e. a set of (x,y) coordinates and a name to be displayed Page 10 of 49
SLIDE 11 as a legend. Graphs with multiple lines will define several of these. In our case, one instance is enough. We do propose to refer to JavaFX API documentation for a detailed description of these properties. Do pay attention to the use of the bind keyword. This is a key feature of the JavaFX scripting language : it allows to bind the value of a property to an expression. Whenever the expression's value is changing, the property's value will be modified accordingly. In this projects, it means that whenever a client class modify the value of any of our four public properties (title, lineName, xMaxValue or data the LineChart properties will be updated automatically. Finally, notice that the values variable is used but never declared. It is one of our private variable that we will define during the following step. This code will therefore not compile - this is intended.
- 6. It is now time to implement the public function that will allow our clients to add values to the graph. Let's fist
define a couple of private variables
//private property var values : LineChart.Data[];
- values will hold the actual coordinates of the points to be displayed on the graph. It is an array of
(x,y) coordinate containers (LineChart.Data objects) Notice that this value is bound to the data property of LineChart.Serie used by our LineChart component. This means that whenever this array is modified, the graph will be updated automatically.
- 7. Last step will be to actually implement the addvalue function.
This is the part where lies our secret sauce to get the graph animated. The graph is based on an array of (x,y) coordinates. To actually make it animated, the algorithm is simple. When the number of points is smaller than the X axis of the graph, just add the point at the end of the array When the number of point did exceed the X axis of the graph,
- Remove the first element of the array (element [0])
- Shift all values from one position to the left
- Insert the new value at the end
This technique will cause the illusion of the line moving to the right side of the graph. We will use the size of array as counter to know whether we need to shift our values or not. Resulting code should look like this :
//public function public function addValue(v:Integer) { var arraySize : Integer = sizeof values; //when the line reached the right border of the graph if (arraySize >= xMaxValue) { //delete the first (left most) element in the graph delete values[0];
Page 11 of 49
SLIDE 12
//and shift all values left for (data in values) { data.xValue = data.xValue - 1; } } insert LineChart.Data { xValue:arraySize , yValue: v } into values; }
NetBeans should complain by displaying many errors (red dot) on the left side of your source code. To fix this, we need defines the appropriate #import. Some errors have a small 'yellow bulb'; if you click on this bulb, NetBeans will do some suggestions that could be used to fix the error. You should have the following import defined at the beginning of the class. import javafx.scene.CustomNode; import javafx.scene.chart.LineChart; import javafx.scene.chart.part.Side; import javafx.scene.chart.part.NumberAxis; To compile the code, right click the project name and select "Build Project" Review and correct any compilation error before proceeding to the next step. Page 12 of 49
SLIDE 13 The last step from this Exercise 1 is to create a Main application that will display the AnimatedLineChart.
Step 2.1: Create a simple application to test the AnimatedLineChart component
Now it's time to actually use this AnimatedLineChart component we just built. We will first create a main JavaFX application and include our custom component in its Scene graph. In a second step, we will add code to randomly generate values and add them to the graph, to see the animation in motion.
- 1. Let's go back to Main.fx created automatically by NetBeans at the beginning of this exercise and let's add
a AnimatedLineChart component before the Stage definition.
var randomGraph : AnimatedLineChart = AnimatedLineChart { title: "JavaONE 2010 Java FX HOL" lineName: "Random Data " xMaxValue:50 yMaxValue:150; }
- The var defines a new variable (randomGraph, gives its type and define the object
- We are defining values for the four properties exposed by the component
- 2. We will now modify the Stage definition to include the component in the top level window.
Stage { title: "MyApp" scene: Scene { width: 500 height: 400 content: [randomGraph] } }
- The Stage's title defines the name of the top-level Window
- The Scene has an height and width property. It's content property is an array containing only
- ne Node : the randomGraph variable (of type AnimatedLineChart extending CustomNode
Complete source code should be as below :
package lab_s313674; import javafx.stage.*; import javafx.scene.*; var randomGraph : AnimatedLineChart = AnimatedLineChart { title: "JavaONE 2010 Java FX HOL" lineName: "Random Data " xMaxValue:50 yMaxValue:150; } Stage { title: "MyApp" scene: Scene { width: 500 height: 400
Page 13 of 49
SLIDE 14
content: [randomGraph] } }
To launch the application, select "Run Main Project" from NetBeans' "Run" menu (or click on the green right arrow in the NetBeans' toolbar) The application should look like this : Page 14 of 49
SLIDE 15 At this stage, the graph does not display any data, there is no code for this, yet. The next and last step from this exercise will provide instructions to do so. Step 2.2: Add random values at regular intervals The last step of this exercise will make sure our code does generate some random data to add the graph. This code will be called at regular intervals to provide an illusion of animation. As support for threading, background tasks and pseudo random number generator in JavaFX is limited, we will use our old well-know Java classes : java.util.Timer, java.util.TimerTask and java.util.Random
- 1. Create a class extending Java'sTimeTask. This class contains a public void run() method that will
be called by our Timer thread. This class definition can be added either above or below previous randomGraph variable definition.
class LineChartDataTask extends TimerTask { def rand: Random = new Random(new java.util.Date().getTime()); def base: Number = 150 / 2;
var b: Boolean = rand.nextBoolean();
Page 15 of 49
SLIDE 16 var r: Number; if (b) { r = base + rand.nextInt(25); } else { r = base - rand.nextInt(25); } randomGraph.addValue(r); } };
- The rand variable is our pseudo random number generator
- The base variable is the graph middle line, it is used to center the line on the graph
- verride function run() is where we define the code to be called from the Time thread
- The r variable is the random number. Basically, it is a random value 25 units above or below our
average line
- The most important line of this method is the last one, where we actually add the value to the graph
Remember how the magic goes within AnimatedLineChart: the addValue function modifies value private property, which is bound to LineChart's LineChart.Serie.data property. Any change to our value property will cause the graph line to be modified.
- 2. Now we just need to add a couple of lines of code to create a timer and start it.
def timer: Timer = new Timer("TimerThread"); def task: LineChartDataTask = new LineChartDataTask(); timer.schedule(task, 0, 1000);
- The timer variable is a Java timer
- The task is the instance of the LineChartTask defined just above
- The schedule method will ensure our timer will call our task every second
This code can be added just below the LineChartTask definition and before the Stage declaration. The full code is provided at the end of this exercise.
- 3. Be sure to include all required import statements : right click anywhere in the source code and click on
"Fix Import" menu option. Page 16 of 49
SLIDE 17
- 4. To launch the application, select "Run Main Project" from NetBeans' "Run" menu (or click on the green right
arrow in the NetBeans' toolbar) You should have a result similar to the one presented in the video above. Page 17 of 49
SLIDE 18
Summary
In this exercise, you create your first JavaFX custom component. You created a JavaFX application to test your custom component, and you finally added timer support to add randomly generated numbers at regular intervals. During the next exercise, you will create a component consuming GlassFish monitoring data through a REST interface. Page 18 of 49
SLIDE 19 Exercise 2: Practice with GlassFish REST monitoring API
This exercise will guide you through your first steps while exploring and testing GlassFish's REST monitoring API. This exercise is not about coding, you will learn how to enable the monitoring capabilities of GlassFish and you will learn how to test the API using a regular web browser, such as Firefox.
Background Information
Introducing to RESTful Web Services
REST stands for REpresentational State Transfer and was first defined within a PhD thesis by Roy Fielding. REST is a set of architectural principles that leverages the core principles of the World Wide Web such as HTTP, URI,
- etc. to build light-weight distributed applications.
Main RESTful principles :
- RESTful architectures are built with resources, each of which is addressable. Every resource on the
network has an ID. For example, with REST over HTTP, every resource has its own specific URI.
- REST is representation oriented. Resources are manipulated through representations. A ressource
referenced by one URI can have different formats available, as different platforms may need different
- formats. For example, AJAX may need JSON while a Java applications may need XML.
- REST services have a Uniform, Constrained Interface. When applying REST over HTTP, you need to stick
to the methods provided by this protocol. The meaning of GET, POST, PUT, and DELETE must be applied religiously.
- REST services are stateless. REST services should not require state stored on the server, and server
sessions should not be used. Having all the state information reside in the client improves stability and
- scalability. Cacheability is required too.
As REST architecture leverages core Web principles in their static forms, REST offers several benefits on the server side such as the ability to scale horizontally, a simple caching mechanism, and a simple failover strategy. In addition, REST also offers advantages on the client side : the ability to cache and bookmark representations, the ability for a client to choose the most appropriate data format, the ability to be implemented on many different clients' platforms, etc. This exercise is divided in two parts :
- 1. The first part gives instructions to enable monitoring API for GlassFish
- 2. The second part explains how to test the API using a regular browser, such as Firefox
Steps to Follow
Step 1: Enable GlassFish Monitoring
- 1. If GlassFish is not already running, start it.
Page 19 of 49
SLIDE 20 Within NetBeans, click "Services" tab, then select "GlassFish v3", right click and select "Start" menu. When the "Start" menu is grayed, this means that GlassFish is already started, you can then proceed to the next bullet. Wait a couple of seconds to let GlassFish start.
- 2. Open GlassFish administration console
Within NetBeans, click "Services" tab, then select "GlassFish v3", right click and select "View Admin Console" menu. Your default browser will start and connect to GlassFish's web based administration console, it might take a minute or two to fully load. Page 20 of 49
SLIDE 21
Page 21 of 49
SLIDE 22
- 3. The very first time you start GlassFish console, it will ask you to register the product. You can safely ignore
this step right now and click on any of the three last buttons.
- 4. Once GlassFish console is loaded, click on the "Monitoring" option under the "Configuration" node in the
left side tree. Page 22 of 49
SLIDE 23
Page 23 of 49
SLIDE 24
- 5. In the "Monitoring Service" screen, select the services you want to monitor (in our case, all services), set
the level to "HIGH" Click on "Change Level" and do not forget to click on "Save" on the upper right side of the screen. Page 24 of 49
SLIDE 25
Page 25 of 49
SLIDE 26 This all you need to activate monitoring - no restart is necessary.
Step 2: Experiment with GlassFish REST Monitoring API
Now that GlassFish monitoring is enabled, we can easily experiment it using a regular browser. As explained above, you can easily test any REST based web service with any browser, you just need to type the address of the web service to call. For the purpose of this lab, we will query the "JVM" service from the running instance, and query the "memory" sub
- service. Finally, we will ask GlassFish to provide us with the used heap size, i.e. the size of the heap part of the
memory currently being used by GlassFish.
- 1. Start your favorite browser. We tested Firefox for the purpose of this lab.
On the JavaONE provided LAB machines, just click on the upper Safari icon.
- 2. Once your browser is open, type the following address in the URL bar (or simply click on the link) :
http://localhost:4848/monitoring/domain/server/jvm/memory/usedheapsize-count If everything is going well, you should receive a screen similar to the one below. If you reload the page several times, you should notice that the count value is evolving. The "count" parameter is the one we'll need for the next step. It does express the amount of bytes currently allocated on the heap. Page 26 of 49
SLIDE 27
Tip GlassFish Monitoring API is returning either XML or JSON formatted data. Not all browsers are able to display these non HTML content. Should you receive a blank page (when using Chrome or Safari for example), ask the browser to view the source of the page to see actual content. This step is NOT required with Firefox, as Firefox is able to recognize, parse and display XML content. Page 27 of 49
SLIDE 28
Experimenting with the API
Feel free to change the URL (by going up or down in the hierarchy) to experiment with the API. You will be surprised by the number of parameters you can have access to. This is the end of Exercise 2. Please proceed to the next exercise only if you are successfully reading data from GlassFish. Page 28 of 49
SLIDE 29 Exercise 3: Invoking REST calls to GlassFish
In this exercise, we will build a JavaFX class that will query GlassFish in order to use metrics we want to monitor. We have previously learned that GlassFish expose some montioring metrics via a REST interface. So this section is about building the necessary JavaFX code that will invoque the GlassFish REST interface to obtain the metrics we need for our monitoring application.
Background Information
This exercise is divided in two parts :
- 1. Manage the network connection to the GlassFish instance. In this case, we will use the HTTP protocol.
- 2. Parse the result sent by the GlassFish instance in order to only keep relevant data. In this case, GlassFish
will output results in JSON format so our application will have to parse JSON data. JavaFX comes with built-in HTTP support and JSON capabilities, so this will be relatively easy to achieve. For the HTTP connection, we rely on the HttpRequest class located in the javafx.io.http package. This class is used to asynchronously make HTTP calls. It should be noted that this class is obviously not limited to HTTP REST calls. Using HttpRequest is straightforward, we just need to specify the location (i.e. the URL of the value we want to monitor - see Exercice 2 - step 2). In addition, by setting the HttpHeader.Accept to "application/json", we specify to GlassFish that we want to receive the result formatted using JSON. We specify a callback function that will be invoked when there is a response; this callback function will parse the response. Finally, we call the start() method to initiate the HTTP connection.
Steps to Follow
Step 0: Create the GfMetric class
Make sure to have your existing project selected and select "New File" from the main menu. To create a JavaFX class, just select "JavaFX" in the left category column, then select "JavaFX class". Page 29 of 49
SLIDE 30
Click the "Next" button and give a meaningful name to your created class (ex. GfMetric). Make sure to put this class in the package you have defined previously; click on the Package drop-down list to select it. Page 30 of 49
SLIDE 31
Click the "Finish" button to let NetBeans create for you an empty JavaFX class. If everything went fine, NetBeans will open your newly created JavaFX class. If not, just click on its name in the left column. Page 31 of 49
SLIDE 32
Step 1: Add the networking logic to the GfMetric class.
We will now add the logic to the class. Under the class declaration (public class GfMetric { ), add the following public and private variables.
public class GfMetric { //public variables public var url: String; public var onResultAvailable: function(r : Integer): Void; //private variable var result : Integer;
As mentioned earlier, we will use HttpRequest to do the HTTP calls. So, next to variables declarations we just did, let's define gfRequest as follow :
def gfRequest = HttpRequest { location: url method: HttpRequest.GET headers: [ HttpHeader { name: HttpHeader.ACCEPT; value: "application/json"; }];
Page 32 of 49
SLIDE 33
- nException: function(ex: java.lang.Exception) {
println("GfMetric exception: {ex.getClass()} {ex.getMessage()}"); }
- nInput: function(inputStream: InputStream): Void {
parseResponse(inputStream); }
- nDone: function(): Void {
- nResultAvailable( result / 1024 / 1024 ) ;
} }
The nice thing about JavaFX is that the code is readable and fairly easy to understand:
- We declare gfRequest, it will be an HttpRequest instance.
- The location to call is set by using the url variable.
- By setting the method variable to HttpRequest.GET, we specify that we are limiting our HTTP requests
to the HTTP GET verb.
- We configure the HTTP headers to only accept JSON responses whenever a HTTP request is made by
gfRequest.
- Finally, we define the various callback functions that needs to be invoked :
- nException will be called when something is wrong. For the sake of simplicity, the code just
display the exception and some of its details.
- nInput is called when we receive content. In this case, we will invoke the parseResponse
function.
- nDone is called when the request is finished.
Step 2: Add the JSON parsing logic
We will now define the function that will be invoked to parse the response. In the GfMetric class, define the parseResponse function as follows:
function parseResponse( is:InputStream ) { try { var parser = PullParser { input: is documentType: PullParser.JSON; } parser.seek("count"); if (parser.event.type == PullParser.START_VALUE) { parser.forward();
Page 33 of 49
SLIDE 34 result = parser.event.integerValue; } } finally { is.close(); } }
Let's examine the parseResponse code...
- By looking at the parseResponse signature, we see that this function expect one parameter, i.e. an
InputStream.
- We define the parser object, it will be an PullParser instance. It is configured, its input will be the
- InputStream. By setting documentType to PullParser.JSON, we specify the type of document this
parser will have to parse, JSON document in this case.
- parser.seek("count") is used to specify to the parser which token it should look for ("count" in this
case).
- The parser will react to event. So whenever a token "count" is found, the result data will be casted in a
integer and stored in the result variable. This is done in by the result = parser.event.integerValue; code. Finally, we need to invoke the start function of HttpRequest. We will do this in the GfRequest constructor so the start function will be invoked whenever a gfRequest object is instanced. At the end of the GfRequest class, add the following code :
init { gfRequest.start(); }
We should now fix the imports. Just right click anywhere in the code and select Fix Imports. Page 34 of 49
SLIDE 35
You should now have the following imports at the begining of the source code : import javafx.data.pull.PullParser; import javafx.io.http.HttpHeader; import javafx.io.http.HttpRequest; import java.io.InputStream; This is the end of Exercise 3. Please proceed to the next exercise to add the logic required to update the chart whenever new monitoring data is obtained from the GlassFish instance. Page 35 of 49
SLIDE 36
Exercise 4: Update the chart with data coming from GlassFish
In this exercise, we will refactor the main class so that the chart is regularly updated with monitoring information coming from the GlassFish instance.
Background Information
In the first exercise, we have defined a Timer that is invoked every seconds. To do that, we have defined in Main.fx the LineChartDataTask class that extend TimerTask. We then have overridden the run method with our own implementation. In the first exercise, that implementation was generating random values and added those values to the chart. We will now refactor this part of the code so that every seconds the chart is updated with real data coming from the GlassFish instance.
Steps to Follow
Step 1: Refactor the Main class
In your project, select Main.fx created during the first exercise. You can select either in the "Source Package" in the "Project" window or if it is already open, just click on the "Main.fx" tab to make its code window visible. In the first exercise, we have created the randomGraph variable, that name was appropriate since the chart was displaying randomly generated data. It would make sense to now use a more appropriate name since the chart will now display data coming from a GlassFish instance. To rename randomGraph we can leverage NetBeans JavaFX refactoring capabilities. In Main.fx, locate randomGraph and right clik on it. Select "Refactoring" and then "Rename..." Page 36 of 49
SLIDE 37
... and give it a meaningful name such as "heapGraph"; finally click on "Refactor". You should now have every occurrence of "randomGraph" set to "heapGraph" instead. In Main.fx locate the run method defined within the LineChartDataTask class. You can safely delete the code of this function and replace it with the following code : Page 37 of 49
SLIDE 38 class LineChartDataTask extends TimerTask {
def myHeap = GfMetric { url: "http://localhost:4848/monitoring/domain/server/jvm/memory/usedheapsize- count"
- nResultAvailable: function (r:Integer) : Void {
heapGraph.addValue(r); } } } }
Let's look at this code... First, we have to keep in mind that the run function is invoked ervery seconds. We define myHeap as an instance of GfMetric. We then set its url variable to the URL of the REST ressource we want to monitor. In this case, we are monitoring GlassFish HeapUsage usage. Tip Refer to Exercise 2 step 2 to make sure you are suing the correct url. In this particular case, we are using http://localhost:4848/monitoring/domain/server/jvm/memory/usedheapsize-count but yours may be slightly different depending on your exact setup. In case of doubt, you can always use a browser to double check to URL you are using is correct. In the previous Exercise, we have declared onResultAvailable in GfResult but we haven't provided any actual implementation. The onResultAvailable function will be invoked whenever a new data has been
So we define in Main.fx an implementation of onResultAvailable; this function add to heapGraph the result (i.e. r - see previous Exercise) coming from the GlassFish instance.
Step 2: Test the Application
You can now run the application and if everything is fine you should observe after a few seconds something like
- this. Since this chart reflect the HeapSize of our GlassFish instance, we can deduct that Garbage Collection
happens when we have a down-peak on the chart. Page 38 of 49
SLIDE 39
Tip Your local GlassFish instance is obviously not doing much. To generate some activity and thus consume some memory, just launch the GlassFish Web Console by pointing your browser to http://localhost:4848/ The section of the code that generate random numbers is now useless, you can either let it there, comment or remove it. Page 39 of 49
SLIDE 40 Summary
Congratulations! You have successfully completed LAB-313674 – Building a JavaFX GlassFish monitoring application using GlassFish REST monitoring API. Where to send questions or feedbacks on this lab and public discussion forums:
- You can send technical questions via email to the authors of this Hands-on lab (and experts on the subject)
- r you can post the questions to the web.
For additional information about the technologies used in this lab, please see the following links:
- JavaFX API documentation
- GlassFish Administration Guide
- Introduction to REST
- Introduction to JSON
- Introduction to JAX-RS (aka Jersey)
If you have questions or comments about the lab, you can post them on the public product forum here: http://www.oracle.com/product_forum You can also contact the lab authors directly at: david.delabassee@oracle.com sebastien.stormacq@oracle.com Thank you for participating! Page 40 of 49
SLIDE 41 Performing This Lab Outside of the JavaOne Environment
System Requirements
- Supported OSes: Windows 2000, XP, Vista or 7, Mac OS X 10.6+, OpenSolaris
- Memory requirement: 1024MB
- Disk space requirement: 500Mb
Install and Configure Lab Environment
In addition to the contents of this lab's zip file you should have the following installed on your computer:
- A Java SE software installation, version 1.6.0 or more recent.
- NetBeans 6.9 or more recent.
- JavaFX SDK 1.3 or more recent.
- GlassFish v3.0.1 or more recent.
This exercise will guide through the step by step installation procedure. Prerequisites We do assume you have a valid Java SE development platform (JDK) installed. This exercise will not give installation instructions for the Java Development Kit itself. You will find the JDK and appropriate instructions at java.sun.com/javase/6/.
Step 1: Download and Install NetBeans, GlassFish V3
- 1. Open your favorite web browser and point it to www.netbeans.org
Page 41 of 49
SLIDE 42
- 2. Click on "Download Free - NetBeans IDE 6.9"
- 3. Several distributions of NetBeans are available, pick the most complete one as it is preconfigured with
GlassFish v3 and JavaFX SDK. Nothing else is required, the NetBeans package has all required plugins for this lab. Click on "Download" below the "All" column (261 Mb). Page 42 of 49
SLIDE 43
- 4. Enjoy a cup of coffee or tea while downloading (screen shot vary depending on your browser and operating
system).
- 5. When the download completes, start NetBeans 6.9 installer (the application might be started automatically
- n some OSes).
Click on "Continue" Page 43 of 49
SLIDE 44
- 6. Accept the terms of the license.
Click on "Continue". Page 44 of 49
SLIDE 45 Click on "Agree"
- 7. You have the possibility to change the installation location. We do suggest to keep the default values.
Click on "Continue" Page 45 of 49
SLIDE 46
- 8. Enjoy your second cup of coffee or tea while installing. Installation can last up to 5 or 10 minutes depending
- n your machine.
Page 46 of 49
SLIDE 47
- 9. Click on "Close" to terminate the installation procedure.
Page 47 of 49
SLIDE 48 At this stage, NetBeans and GlassFish v3 are installed and configured, ready to be started.
Step 2: Start NetBeans
- 1. Windows : The installation program created a NetBeans icon on your Windows' desktop.
Mac : The installation program created a NetBeans folder and icon in your "/Applications" folder. Double Click on the NetBeans icon to start NetBeans. Page 48 of 49
SLIDE 49
NetBeans is ready with GlassFish v3 and the JavaFX SDK and plugins. You're ready for this lab ! Page 49 of 49