Phobos is a lightweight, scripting-friendly, web application
environment that runs on the Java platform. Using Phobos, you can take advantage of the benefits offered by
scripting languages and leverage the power of the Java platform. Being scripting-friendly, Phobos provides
which Phobos supports using the Mozilla Rhino scripting engine.
Scripting languages can be powerful and convenient. They also enable an interactive form of development in which
you can progressively refine the behavior of an application until it is ready for deployment and use. This is especially
important in developing Ajax-enabled web applications. These applications typically require a lot of
interactive in-browser testing and refinement. In addition to enabling an interactive mode of development, Phobos allows
scripting developers to call into any Java code at any time. As a scripting developer, you can reuse APIs,
libraries, and frameworks that run on the Java platform. Using Phobos offers a "best of both worlds" approach,
in which you can write "soft" -- often changing code -- in a scripting language, and write
"hard" -- rarely modified code -- in a compiled language such as the Java programming language.
In this tip, you'll use Phobos and jMaki to create a simple Ajax-enabled web application. The jMaki framework
is a lightweight framework for creating Web 2.0 applications using standards-based technologies such as
Introduction to jMaki.
You will build the application using the NetBeans IDE and
deploy the application to the GlassFish application server.
The tip assumes that you have NetBeans IDE 6.1
GlassFish v2ur2 application server
installed. You can install them together by installing the
Web & Java EE
version of NetBeans IDE 6.1.
that contains the code for the sample application accompanies the tip.
The code examples in the tip are taken from the source code of the sample (which is included in the package).
The Phobos Framework
In Phobos, whenever a request comes in to the servlet container, the container invokes the Phobos servlet. The Phobos
attempts to match the request URI with a certain number of predefined patterns. When a match is found, the framework
invokes the script or controller associated with that pattern.
In Phobos there are many ways to handle a HTTP request. The simplest way is by writing a plain script which has access
to two predefined variables called
response. These variables hold a reference to
HttpServletResponse that the servlet container creates. The
user-written script can then perform the appropriate request-handling logic and produce a response.
Although scripts are in principle sufficient to cover every task, it is better to follow a more structured
To learn more about the Phobos framework, see
An Overview of Phobos.
This tip uses Phobos to reimplement the PHP application that Ludovic Champenois presented in the
June 16, 2008 Tech Tip
Using jMaki with
PHP on OpenSolaris.
See "The Sample Application" section of that tip for a description of the application.
Figure 1 shows a web page displayed by that application.
Figure 1. A Web Page from the PHP Application
Notice that the PHP application uses MySQL as the database. However, the Phobos version of the application uses
JavaDB, rather than MySQL. You'll find the Java DB database bundled with GlassFish v2ur2.
Install the Phobos Plugins in NetBeans IDE 6.1
Before building the application, you need to add support for Phobos to the NetBeans 6.1 IDE. This support
is provided by Phobos-related plugins which include functionality such as a new Phobos project type
and a syntax-aware editor for EJS pages
To install the Phobos plugins:
Figure 2. Selecting the Phobos Plugins
Configure the Java DB Database
Next, let's create a new database for the application.
data. This is the database name preconfigured in Phobos.
APP, and a password,
Figure 3. Driver List
Create a Project for the Web Application
Now that you have added the Phobos plugins to the NetBeans IDE and created and configured a Java DB database, it's time
to create the application. Start by creating a new project in the NetBeans IDE, as follows:
PhobosSamplein the name field and select an appropriate location for the project.
Figure 4. Selecting the Phobos and jMaki Frameworks
PhobosSampleproject in the Projects tab. Figure 5 shows that
PhobosSampleproject includes Phobos-specific elements that reside in the Phobos Application folder.
Figure 5. PhobosSample Project
Customize the Scripts for the Application
A Phobos application contains a set of scripts that are executed in response to web requests. Additionally, it contains
executed when the page is rendered. This allows dynamic content to be generated.
The application you created contains a predefined model/view pair. If you run the application as it currently exists,
you will see the web page displayed in Figure 6. You can see this default page by right-clicking
PhobosSample in the Projects tab and selecting Run.
Figure 6. Default Page Displayed by a Phobos Application
You need to customize the model and view to produce the results you want for the application. That requires you to
update a number of pregenerated scripts. In addition, you need to create some other scripts to do things such as
connect to the database. The remainder of the tip focuses on these scripting actions.
Connect to the Database
For the application to work, it needs to connect to the database. In Phobos, you implement the connection using a startup
script. This is a special script that the Phobos runtime executes when the web application is initialized. The script
initializes the database layer, connects to the database, and checks that the table required by the application exists. If
the table does not exist, the script creates it.
Note that these actions were performed by the
setup.php page in the PHP version of the application.
In the Phobos version of the application, there is no need to manually point the browser to a setup page because the
application will do that automatically at startup.
To create the startup script:
applicationas the script file name. Ensure that the full name of the resource in
application.jsfile.Replace the contents of the
application.jsfile with the following:
library.common.define function call that wraps the code below it is the Phobos way of creating a package.
You can think of that line as being equivalent to the statement
package module.application; in the Java
had to define its own construct.
The body of the package defines and exports the
onStartup function. That function is invoked by the Phobos
runtime when the application starts up. The
onStartup function selects the client database as the preferred
database and initializes it. Its configuration parameters are predefined in Phobos as follows:
As you can see, the
data, which matches the name of the database you created
earlier in the NetBeans IDE. If you want to use a different database, you need to copy the code shown above, paste it into
the application module, and edit it to suit your needs.
The rest of the code in the
application.js script tries to connect to the database and execute a SQL query.
If it fails, it executes an
SQL CREATE statement to create the table that holds the product information. This code
uses the Phobos db library (
more details about this library in the
Phobos Library Documentation.
Run the application again to ensure that the added code is correct and to test that the application can connect to
the database. If everything is correct, you'll see the same page as before -- the contents of the page won't change until
you modify the main controller for the application. In case of an error, you should see a Phobos error page with a complete
Change the Main Page
If the application can connect to the database, it's time to start implementing the rest of the code, starting with the main
page. This page is the equivalent of the
index.php page in the PHP version of the application.
However, there are some notable differences. Unlike PHP, Phobos uses a full MVC framework, so the application logic is split
between view and controller.
Let's update the view first -- it's the
main.ejs file in the view package under Phobos Application in the
project. The contents of the view are similar to those of the
index.php page in the PHP version. The main
enclosed within <% %>.
Replace the code in the
main.ejs file with the following:
light-green color) to point out that the sections render dynamic content. This differentiates these sections from
the rest of the page, which is rendered as entered.
library.jmaki.insert function in the
main.ejs file. This function is used in Phobos to
insert jMaki widgets. If you compare the function to the
addWidget function in the
index.php file of the PHP version of the application, you'll see that
the arguments to both are similar. They also resemble the arguments that the jMaki JSP tag library expects. This makes the
transition from PHP to Phobos straightforward.
One important difference between the way the Phobos version and the PHP version use jMaki widgets is that in Phobos the
values and arguments (
one of the most interesting features in Phobos. The client (that is, the scripts running inside the browser) and the
and so, is a particularly appealing data format.
Another thing to point out in the EJS page is the call to the library function,
library.httpserver.makeUrl("/main/listProducts"). Phobos views are stored in a separate directory tree
from static content, so that referencing other resources or even controllers from a view is error-prone. The
library.httpserver.makeUrl function helps here because it allows you to specify an absolute URL as an argument.
The URL is then replaced with the correct URL at runtime. In the example, the URL points to the main controller and
triggers invocation of the
listProducts method when it is accessed.
Add jMaki Glue
Because the application uses jMaki, you need to create a jMaki Glue file,
glue.js, that "glues"
the widgets on the page together using a publish-subscribe event model. Replace the contents of the glue file,
resources/glue.js, which you can find under Web Pages in the project, with the following:
Update the Controller
The modified view relies on some additional behavior from the controller, the
listProducts action, which
you need to implement. However, first, let's rewrite the generated
main.js file in the controller package below Phobos Application with the following:
Notice the similarity between this code and the code in the
application.js file defined earlier. A controller
is itself a module, but defined under the
controller node in the project. A controller module defines
a controller class, represented
Main. In addition, a controller class has one or more
so it may appear strange at first.
You modified some code, so let's test it by running the application again. When you run the application, you should see
the page displayed in Figure 7. Although part of the page renders properly, it also displays some error
Figure 7. The Application Page Displaying Errors
The reason for these errors is that the application is trying to insert some jMaki widgets into the page, but the resources
for those widgets are not in the application. The easiest way to fix the problem is to do the following:
Figure 8 shows the part of the code generated by the drag and drop.
Figure 8. Code Generated by Dragging and Dropping jMaki Yahoo Widgets
You can safely delete these snippets because the page already contains that code. A side benefit of dragging and dropping
the widgets is that the necessary resources are added to the project. You can find the added resources
Web Pages/resources/yahoo folder in the project.
Run the application again. As Figure 9 shows, the resource-related error messages have disappeared
and the button near the top of the page is rendered correctly. However, at the bottom of the page, where the table should
be, there is still an error message.
Figure 9. The Application Page Displaying a Failed to Load Data Error
The error message is an indicator that the
listProducts method in the controller has not yet been defined.
Define it now by adding the following code inside the
Add a Persistence Layer
In keeping up with the incremental nature of development in Phobos, let's now implement a persistence layer. This allows
you to test the
listProducts functionality in the browser. To do this, create a
module. You can follow the same process you did to create the
application.js module, that is, the
After you create the
persistence.js module, replace its contents with the following code:
As is the case in the startup script, the persistence module uses the Phobos db library to avoid having to directly
interact with JDBC. The
addProducts functions are exported from the module
by adding them to this object, which in this context is the module itself. The code to add a new product is simple.
The code does not validate the input data. Neither does it handle exceptions, which are simply passed back
to the caller. A production application would include many more checks to make sure no illegal or malicious data is sent to the
The two mapping objects at the bottom deserve an explanation. Because Java DB converts all column names to uppercase,
if you retrieve data from the database you would find properties with the names NAME, CATEGORY, and PRICE. But if you
main.ejs page, you'll notice that it expects properties called name, category and price, respectively.
It is easier to do the conversion in the database layer by specifying two mappings of column names to
property names and back. This approach is also useful when you want to map names written in camel case that are commonly
streetAddress, to underscore-rich names that database professionals typically use,
Now that the persistence layer is completed, you can test the
addProducts controller action by pointing the browser
to the URL http://localhost:8080/PhobosSample/main/listProducts. You should see the following text in the browser:
This is an expected result because the database table is currently empty.
Add the Products
When a user of the application clicks on the add a Product button to add a product, the application sends an Ajax POST
request to the
addProduct method of the main controller. It's now time to implement this method by adding the following
code to the
main.js controller script:
This function uses the
parseRequestParameters library function to parse the body of the POST request into
Here, because all the property names match, the function could have been designed to pass the
directly. However, in general, it is safer to insulate the web-facing layer from the database layer. This avoids
exposing the database to attacks by malicious clients.
Test the Application
The application is complete and ready for testing. Run it and try adding a few products. You should see the updates
immediately reflected in the UI as shown in Figure 10.
Figure 10. Adding Products to the Database
You can also directly point the browser to the listProducts action at http://localhost:8080/PhobosSample/main/listProducts.
This will display the data in JSON format:
This tip showed you how to build an Ajax-enabled application using Phobos and jMaki with the help of the NetBeans IDE.
For persistence, the application used a simple JDBC wrapper library provided with Phobos. If the data model were more complex,
the application could have used a full-featured Java persistence library such as the Java Persistence API (JPA) or
use the language most appropriate for each task without compromising productivity.
About the Author
Roberto Chinnici is a senior staff engineer at Sun Microsystems. He currently serves as the specification lead for the
Java Platform, Enterprise Edition (Java EE) 6. Roberto is a long-standing advocate of scripting and dynamic languages
on any platform and the creator of Phobos.