Please click on any Advertisement, if you like this blog.

Friday, January 14, 2011

Java on Cloud - Google App Engine

Java On CLOUD- Google App Engine


Now a days, java on cloud is supported by several parties but among them, 3 major brands are important:
  • Google App Engine
  • Aptana Cloud
  • Stax for EC2

Lets take a look on these 3 java cloud brands:


Java clouds at a glance



Pros Cons Bottom line
Google App Engine

  • Automatically scales up and down without asking permission
  • Free trial layer for small applications
  • A big set of tools integrated with Eclipse and GWT
  • You must store data in the way Google wants you to store data
  • Some class files are absent
  • Every step is bound by strict quotas
Great for lightweight shells that wrap Java code around big tables
Aptana Cloud
  • Deep integration with Aptana's nice set of Eclipse plug-ins
  • All of the familiar buttons are available including root
  • All of the familiar databases are waiting for you on their regular ports
  • Pricing options are narrow (you get only four choices)
  • No clusters yet
All of your server controls are now available from Eclipse
Stax for EC2
  • Web-based tool lets you choose your development platform
  • A wide range of clustering options available
  • A good collection of startup frameworks
  • All of Amazon's service offerings are in the same datacenter
  • You need to manually switch to bigger clusters when the hordes arrive
  • Limited access to resources under the hood
A simple Web-based tool makes it easy to whip up a Tomcat server

Google App Engine: Creating java application in Google App Engine Environment is very much similar to python programming. Here any java guys will find several strange things like Google App Engine does not support MySQL, Oracle, or even the embedded database included with the JVM, Derby. It's a proprietary data store with a small subset of SQL called GQL. You can't use JDBC (Java Database Connectivity) to link up with it; you need to use Google's own proprietary layer.
This is just the beginning of the changes. You can't just open up a socket and suck down a Web page; you have to use the URL fetching code. If you want to keep a cache of commonly used information, you should store your objects with the Memcache implementation that Google offers. Google's code will keep everything consistent so that the Memcache on all machines will offer the same thing when the synchronization is finished.
There are also a number of restrictions on the classes you can use. Google's version of the JVM isn't fully stocked. You won't be able to spin off a thread to handle processing and you can't write to the disk -- ever. You have to use Google's data store if you want to save the data.
All of these changes have some advantages. Google's data store is stripped down and optimized for working with many machines at once. The Memcache service saves calls to the data store -- something to be wary about because the meter is clicking whenever your servlet is churning. The image processing tool handles some of the work with native code, another advantage.
There are also a number of restrictions on the classes you can use. Google's version of the JVM isn't fully stocked. You won't be able to spin off a thread to handle processing and you can't write to the disk -- ever. You have to use Google's data store if you want to save the data.
All of these changes have some advantages. Google's data store is stripped down and optimized for working with many machines at once. The Memcache service saves calls to the data store -- something to be wary about because the meter is clicking whenever your servlet is churning. The image processing tool handles some of the work with native code, another advantage.
For all of these reasons, I think App Engine will be most attractive to projects that need to give people shared access to several big tables filled with data. It's not really for all Java programmers, but for people who are familiar with Java and like to use it to write some glue code to wrap around a big table. You can't do too much to the data on the way in or the way out because there are limits on the amount of time that each request can spin the meter.
I think these restrictions will mean that there will be relatively few applications that just pick up and migrate to the App Engine. All of the data access will need to be rewritten and some of the common tricks that use flat files will need to be re-engineered. Moving your application out of the App Engine will probably be a bit easier, but it will require changing your mindset because the App Engine used to handle some of the scaling and synchronization issues for you. It may be technically possible to run the App Engine debugging environment on your own server, but the Terms of Service say Google is giving you a license for the "sole purpose of enabling you to use and enjoy the benefit of the Service as provided by Google, in the manner permitted by the Terms."
Google is well aware of this issue and is trying to address it as it encourages people to use the system. IBM is even offering tips on how to migrate App Engine code to its platform. It's just a matter of getting the JDO (Java Data Objects) calls to talk with IBM's DB2 instead of Google's back end. I'm guessing that IBM hopes to grab customers who build the first rev in App Engine and then decide that some threading or slow cron jobs are absolutely necessary.
There are real advantages to what may at first seem like a straightjacket to any programmer who grew up opening sockets on a whim and writing to the file system whenever it felt good. The explicit limitations help architects create better applications that run more smoothly because they prevent overreaching the limits of the system. Many of the early adopters of the Java EE found themselves pulling out their hair when one of the automatic tools would take forever to deliver the magic that the API documentation promised. Making the limitations of the architecture apparent by writing a tightly limited API is more of a gift than a curse.
If there are no joins in the data store, then it will be easier to generate massive reports because the database table will be denormalized from its inception. If the jobs can't run that long, the architect can make living documents that let the user drill down to generate the necessary information on demand. That can be much more efficient than spending the entire night pre-computing something that won't be read by many people.
It's worth noting that Google has done a nice job of integrating the system with Eclipse. There is a wide variety of tools, and they do more than just upload WAR (Web archive) files to the App Engine. The standard application shell is integrated with Google Web Toolkit, the mind-bending tool that converts your Java code into JavaScript that runs on the client. The dashboard is simple but responsive. The spikes I generated in my jobs started showing up within seconds.
To work on Google App Engine:
1)      Download and Install google app engine for Java from following url:
2)      Download google plugin for eclipse

Installing the Java SDK

You develop and upload Java applications for Google App Engine using the App Engine Java software development kit (SDK).
The SDK includes software for a web server that you can run on your own computer to test your Java applications. The server simulates all of the App Engine services, including a local version of the datastore, Google Accounts, and the ability to fetch URLs and send email from your computer using the App Engine APIs.

Getting Java

Google App Engine supports Java 5 and Java 6. When your Java application is running on App Engine, it runs using the Java 6 virtual machine (JVM) and standard libraries. Ideally, you should use Java 6 for compiling and testing your application to ensure that the local server behaves similarly to App Engine.
For developers that don't have easy access to Java 6 (such as developers using Mac OS X), the App Engine SDK is compatible with Java 5. You can upload compiled classes and JARs made with Java 5 to App Engine.
If necessary, download and install the Java SE Development Kit (JDK) for your platform. Mac users, see Apple's Java developer site to download and install the latest version of the Java Developer Kit available for Mac OS X.
Once the JDK is installed, run the following commands from a command prompt (for Windows, Command Prompt; for Mac OS X, Terminal) to verify that you can run the commands, and to determine which version is installed. If you have Java 6 installed, these commands will report a version number similar to 1.6.0. If you have Java 5 installed, the version number will be similar to 1.5.0.
java -version
 
javac -version

Using Eclipse and the Google Plugin for Eclipse

If you are using the Eclipse development environment, the easiest way to develop, test and upload App Engine apps is to use the Google Plugin for Eclipse. The plugin includes everything you need to build, test and deploy your app, entirely within Eclipse.
The plugin is available for Eclipse versions 3.3, 3.4, and 3.5. You can install the plugin using the Software Update feature of Eclipse. The installation locations are as follows:
  • The Google Plugin for Eclipse, for Eclipse 3.3 (Europa):
http://dl.google.com/eclipse/plugin/3.3
  • The Google Plugin for Eclipse, for Eclipse 3.4 (Ganymede):
http://dl.google.com/eclipse/plugin/3.4
  • The Google Plugin for Eclipse, for Eclipse 3.5 (Galileo):
http://dl.google.com/eclipse/plugin/3.5
For details on how to use Software Update to install the plugin, and how to create a new project, see Using the Google Eclipse Plugin.

 

Getting the SDK

If you are using Eclipse and the Google Plugin, you can install the App Engine SDK from Eclipse using Software Update. If you haven't already, install the "Google App Engine Java SDK" component using the locations above.
If you are not using Eclipse or the Google Plugin, you can download the App Engine Java SDK as a Zip archive.
Download the App Engine Java SDK. Unpack the archive in a convenient location on your hard drive.
Note: Unpacking the archive creates a directory whose name is something like appengine-java-sdk-X.X.X, where X.X.X is the SDK version number. Throughout this documentation, this directory will be referred to as appengine-java-sdk/. You may want to rename the directory after unpacking.

Trying a Demo Application

The App Engine Java SDK includes several demo applications in the demos/ directory. The final version of the guest book application you will create in this tutorial is included under the directory guestbook/. This demo has been precompiled for you so you can try it right away.
If you are using Eclipse, the SDK is located in your Eclipse installation directory, under plugins/com.google.appengine.eclipse.sdkbundle_VERSION/, where VERSION is a version identifier for the SDK. From the command line, change the current working directory to this directory to run the following command. If you're using Mac OS X or Linux, you may need to give the command files executable permissions before you can run them (such as with the command chmod u+x dev_appserver.sh).
If you are using Windows, start the guest book demo in the development server by running the following command at a command prompt:
appengine-java-sdk\bin\dev_appserver.cmd appengine-java-sdk\demos\guestbook\war
If you are using Mac OS X or Linux, run the following command:
./appengine-java-sdk/bin/dev_appserver.sh appengine-java-sdk/demos/guestbook/war
The development server starts, and listens for requests on port 8080. Visit the following URL in your browser:
Note: When you start the development server from within Eclipse using the Google Plugin for Eclipse (discussed later), the server uses the port 8888 by default: http://localhost:8888/
For more information about running the development web server from the command line, including how to change which port it uses, see the Dev Web Server reference.
To stop the server, make sure the command prompt window is active, then press Control-C.

Creating a Project

App Engine Java applications use the Java Servlet standard for interacting with the web server environment. An application's files, including compiled classes, JARs, static files and configuration files, are arranged in a directory structure using the WAR standard layout for Java web applications. You can use any development process you like to develop web servlets and produce a WAR directory. (WAR archive files are not yet supported by the SDK.)

The Project Directory

For this tutorial, we will use a single directory named Guestbook/ for all project files. A subdirectory named src/ contains the Java source code, and a subdirectory named war/ contains the complete application arranged in the WAR format. Our build process compiles the Java source files and puts the compiled classes in the appropriate location in war/.
The complete project directory looks like this:
Guestbook/
  src/
    ...Java source code...
    META-INF/
      ...other configuration...
  war/
    ...JSPs, images, data files...
    WEB-INF/
      ...app configuration...
      lib/
        ...JARs for libraries...
      classes/
        ...compiled classes...
If you are using Eclipse, create a new project by clicking the New Web Application Project button in the toolbar: The New Web Application Project button.Give the project a "Project name" of Guestbook and a "Package" of guestbook. Uncheck "Use Google Web Toolkit," and ensure "Use Google App Engine" is checked. See Using the Google Plugin for Eclipse for more information. The wizard creates the directory structure, and the files described below.
If you are not using Eclipse, create the directory structure described above. As you read each of the files described in this section, create the files using the given locations and names.
You can also copy the new project template included with the SDK, in the appengine-java-sdk/demos/new_project_template/ directory.

The Servlet Class

App Engine Java applications use the Java Servlet API to interact with the web server. An HTTP servlet is an application class that can process and respond to web requests. This class extends either the javax.servlet.GenericServlet class or the javax.servlet.http.HttpServlet class.
Our guest book project begins with one servlet class, a simple servlet that displays a message.
If you are not using the Eclipse plugin, create the directories for the path src/guestbook/, then create the servlet class file described below.
In the directory src/guestbook/, a file named GuestbookServlet.java has the following contents:
package guestbook;



import java.io.IOException;

import javax.servlet.http.*;



public class GuestbookServlet extends HttpServlet {

    public void doGet(HttpServletRequest req, HttpServletResponse resp)

            throws IOException {

        resp.setContentType("text/plain");

        resp.getWriter().println("Hello, world");

    }

}

The web.xml File

When the web server receives a request, it determines which servlet class to call using a configuration file known as the "web application deployment descriptor." This file is named web.xml, and resides in the war/WEB-INF/ directory in the WAR. WEB-INF/ and web.xml are part of the servlet specification.
In the directory war/WEB-INF/, a file named web.xml has the following contents:
<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE web-app PUBLIC

 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

 "http://java.sun.com/dtd/web-app_2_3.dtd">



<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">

    <servlet>

        <servlet-name>guestbook</servlet-name>

        <servlet-class>guestbook.GuestbookServlet</servlet-class>

    </servlet>

    <servlet-mapping>

        <servlet-name>guestbook</servlet-name>

        <url-pattern>/guestbook</url-pattern>

    </servlet-mapping>

    <welcome-file-list>

        <welcome-file>index.html</welcome-file>

    </welcome-file-list>

</web-app>
This web.xml file declares a servlet named guestbook, and maps it to the URL path /guestbook. It also says that whenever the user fetches a URL path that is not already mapped to a servlet and represents a directory path inside the application's WAR, the server should check for a file named index.html in that directory and serve it if found.

The appengine-web.xml File

App Engine needs one additional configuration file to figure out how to deploy and run the application. This file is named appengine-web.xml, and resides in WEB-INF/ alongside web.xml. It includes the registered ID of your application (Eclipse creates this with an empty ID for you to fill in later), the version number of your application, and lists of files that ought to be treated as static files (such as images and CSS) and resource files (such as JSPs and other application data).
In the directory war/WEB-INF/, a file named appengine-web.xml has the following contents:
<?xml version="1.0" encoding="utf-8"?>

<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">

    <application></application>

    <version>1</version>

</appengine-web-app>
appengine-web.xml is specific to App Engine, and is not part of the servlet standard. You can find XML schema files describing the format of this file in the SDK, in the appengine-java-sdk/docs/ directory. See Configuring an App for more information about this file.

Running the Project

The App Engine SDK includes a web server application you can use to test your application. The server simulates the App Engine environment and services, including sandbox restrictions, the datastore, and the services.
If you are using Eclipse, you can start the development server within the Eclipse debugger. Make sure the project ("Guestbook") is selected, then in the Run menu, select Debug As > Web Application. See Using the Google Plugin for Eclipse for details on creating the debug configuration.
If you are not using Eclipse, see Using Apache Ant for a build script that can build the project and start the development server. To start the server with this build script, enter the following command: ant runserver To stop the server, hit Control-C.

Testing the Application

Start the server, then visit the server's URL in your browser. If you're using Eclipse and the Google Eclipse plugin, the server runs using port 8888 by default:
If you're using the dev_appserver command to start the server, the default port is 8080:
For the rest of this tutorial, we'll assume the server is using port 8888.
The server calls the servlet, and displays the message in the browser.

Using the Users Service

Google App Engine provides several useful services based on Google infrastructure, accessible by applications using libraries included with the SDK. One such service is the Users service, which lets your application integrate with Google user accounts. With the Users service, your users can use the Google accounts they already have to sign in to your application.
Let's use the Users service to personalize this application's greeting.

Using Users

Edit src/guestbook/GuestbookServlet.java as indicated to resemble the following:
package guestbook;



import java.io.IOException;

import javax.servlet.http.*;

import com.google.appengine.api.users.User;

import com.google.appengine.api.users.UserService;

import com.google.appengine.api.users.UserServiceFactory;



public class GuestbookServlet extends HttpServlet {

    public void doGet(HttpServletRequest req, HttpServletResponse resp)

              throws IOException {

        UserService userService = UserServiceFactory.getUserService();

        User user = userService.getCurrentUser();



        if (user != null) {

            resp.setContentType("text/plain");

            resp.getWriter().println("Hello, " + user.getNickname());

        } else {

            resp.sendRedirect(userService.createLoginURL(req.getRequestURI()));

        }

    }

}
If you are using Eclipse and your development server is running in the debugger, when you save your changes to this file, Eclipse compiles the new code automatically, then attempts to insert the new code into the already-running server. Changes to classes, JSPs, static files and appengine-web.xml are reflected immediately in the running server without needing to restart. If you change web.xml or other configuration files, you must stop and start the server to see the changes.
If you are using Ant, you must stop the server and rebuild the project to see changes made to source code. Changes to JSPs and static files do not require restarting the server.
Rebuild your project and restart the server, if necessary. Test the application by visiting the servlet URL in your browser:
Instead of displaying the message, the server prompts you for an email address. Enter any email address (such as alfred@example.com, then click "Log In." The app displays a message, this time containing the email address you entered.
The new code for the GuestbookServlet class uses the Users API to check if the user is signed in with a Google Account. If not, the user is redirected to the Google Accounts sign-in screen. userService.createLoginURL(...) returns the URL of the sign-in screen. The sign-in facility knows to redirect the user back to the app by the URL passed to createLoginURL(...), which in this case is the URL of the current page.
The development server knows how to simulate the Google Accounts sign-in facility. When run on your local machine, the redirect goes to the page where you can enter any email address to simulate an account sign-in. When run on App Engine, the redirect goes to the actual Google Accounts screen.
You are now signed in to your test application. If you reload the page, the message will display again.
To allow the user to sign out, provide a link to the sign-out screen, generated by the method createLogoutURL(). Note that a sign-out link will sign the user out of all Google services.

Using JSPs

While we could output the HTML for our user interface directly from the Java servlet code, this would be difficult to maintain as the HTML gets complicated. It's better to use a template system, with the user interface designed and implemented in separate files with placeholders and logic to insert data provided by the application. There are many template systems available for Java, any of which would work with App Engine.
For this tutorial, we'll use JavaServer Pages (JSPs) to implement the user interface for the guest book. JSPs are part of the servlet standard. App Engine compiles JSP files in the application's WAR automatically, and maps them to URL paths.

Hello, JSP!

Our guest book app writes strings to an output stream, but this could also be written as a JSP. Let's begin by porting the latest version of the example to a JSP.
In the directory war/, create a file named guestbook.jsp with the following contents:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.google.appengine.api.users.User" %>
<%@ page import="com.google.appengine.api.users.UserService" %>
<%@ page import="com.google.appengine.api.users.UserServiceFactory" %>
 
<html>
  <body>
 
<%
    UserService userService = UserServiceFactory.getUserService();
    User user = userService.getCurrentUser();
    if (user != null) {
%>
<p>Hello, <%= user.getNickname() %>! (You can
<a href="<%= userService.createLogoutURL(request.getRequestURI()) %>">sign out</a>.)</p>
<%
    } else {
%>
<p>Hello!
<a href="<%= userService.createLoginURL(request.getRequestURI()) %>">Sign in</a>
to include your name with greetings you post.</p>
<%
    }
%>
 
  </body>
</html>
By default, any file in war/ or a subdirectory (other than WEB-INF/) whose name ends in .jsp is automatically mapped to a URL path. The URL path is the path to the .jsp file, including the filename. This JSP will be mapped automatically to the URL /guestbook.jsp.
For the guest book app, we want this to be the application's home page, displayed when someone accesses the URL /. An easy way to do this is to declare in web.xml that guestbook.jsp is the "welcome" servlet for that path.
Edit war/WEB-INF/web.xml and replace the current <welcome-file> element in the <welcome-file-list>. Be sure to remove index.html from the list, as static files take precedence over JSP and servlets.
    <welcome-file-list>

        <welcome-file>guestbook.jsp</welcome-file>

    </welcome-file-list>
Tip: If you are using Eclipse, the editor may open this file in "Design" mode. To edit this file as XML, select the "Source" tab at the bottom of the frame.
Stop then start the development server. Visit the following URL:
The app displays the contents of guestbook.jsp, including the user nickname if the user is signed in.
When you load a JSP for the first time, the development server converts the JSP into Java source code, then compiles the Java source into Java bytecode. The Java source and the compiled class are saved to a temporary directory. The development server regenerates and compiles JSPs automatically if the original JSP files change.
When you upload your application to App Engine, the SDK compiles all JSPs to bytecode, and only uploads the bytecode. When your app is running on App Engine, it uses the compiled JSP classes.

The Guestbook Form

Our guest book application will need a web form so the user can post a new greeting, and a way to process that form. The HTML of the form will go into the JSP. The destination of the form will be a new URL, /sign, to be handled by a new servlet class, SignGuestbookServlet. SignGuestbookServlet will process the form, then redirect the user's browser back to /guestbook.jsp. For now, the new servlet will just write the posted message to the log.
Edit guestbook.jsp, and put the following lines just above the closing </body> tag:
  ...
 
  <form action="/sign" method="post">
    <div><textarea name="content" rows="3" cols="60"></textarea></div>
    <div><input type="submit" value="Post Greeting" /></div>
  </form>
 
  </body>
</html>
Create a new class named SignGuestbookServlet in the package guestbook. (Non-Eclipse users, create the file SignGuestbookServlet.java in the directory src/guestbook/.) Give the source file the following contents:
package guestbook;



import java.io.IOException;

import java.util.logging.Logger;

import javax.servlet.http.*;

import com.google.appengine.api.users.User;

import com.google.appengine.api.users.UserService;

import com.google.appengine.api.users.UserServiceFactory;



public class SignGuestbookServlet extends HttpServlet {

    private static final Logger log = Logger.getLogger(SignGuestbookServlet.class.getName());



    public void doPost(HttpServletRequest req, HttpServletResponse resp)

                throws IOException {

        UserService userService = UserServiceFactory.getUserService();

        User user = userService.getCurrentUser();



        String content = req.getParameter("content");

        if (content == null) {

            content = "(No greeting)";

        }

        if (user != null) {

            log.info("Greeting posted by user " + user.getNickname() + ": " + content);

        } else {

            log.info("Greeting posted anonymously: " + content);

        }

        resp.sendRedirect("/guestbook.jsp");

    }

}
Edit war/WEB-INF/web.xml and add the following lines to declare the SignGuestbookServlet servlet and map it to the the /sign URL:
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">

    ...



    <servlet>

        <servlet-name>sign</servlet-name>

        <servlet-class>guestbook.SignGuestbookServlet</servlet-class>

    </servlet>

    <servlet-mapping>

        <servlet-name>sign</servlet-name>

        <url-pattern>/sign</url-pattern>

    </servlet-mapping>



    ...

</web-app>
This new servlet uses the java.util.logging.Logger class to write messages to the log. You can control the behavior of this class using a logging.properties file, and a system property set in the app's appengine-web.xml file. If you are using Eclipse, your app was created with a default version of this file in your app's src/ and the appropriate system property.
If you are not using Eclipse, you must set up the Logger configuration file manually. Copy the example file from the SDK appengine-java-sdk/config/user/logging.properties to your app's war/WEB-INF/ directory. Then edit the app's war/WEB-INF/appengine-web.xml file as indicated:
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">

    ...



    <system-properties>

        <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>

    </system-properties>



</appengine-web-app>
The servlet logs messages using the INFO log level (using log.info()). The default log level is WARNING, which suppresses INFO messages from the output. To change the log level for all classes in the guestbook package, edit the logging.properties file and add an entry for guestbook.level, as follows:
.level = WARNING
guestbook.level = INFO
 
...
Tip: When your app logs messages using the java.util.logging.Logger API while running on App Engine, App Engine records the messages and makes them available for browsing in the Admin Console, and available for downloading using the AppCfg tool. The Admin Console lets you browse messages by log level.
Rebuild and restart, then test http://localhost:8888/. The form displays. Enter some text in the form, and submit. The browser sends the form to the app, then redirects back to the empty form. The greeting data you entered is logged to the console by the server.

Using the Datastore with JDO

Storing data in a scalable web application can be tricky. A user could be interacting with any of dozens of web servers at a given time, and the user's next request could go to a different web server than the one that handled the previous request. All web servers need to be interacting with data that is also spread out across dozens of machines, possibly in different locations around the world.
With Google App Engine, you don't have to worry about any of that. App Engine's infrastructure takes care of all of the distribution, replication and load balancing of data behind a simple API—and you get a powerful query engine and transactions as well.
The App Engine datastore is one of several services provided by App Engine with two APIs: a standard API, and a low-level API. By using the standard APIs, you make it easier to port your application to other hosting environments and other database technologies, if you ever need to. Standard APIs "decouple" your application from the App Engine services. App Engine services also provide low-level APIs that exposes the service capabilities directly. You can use the low-level APIs to implement new adapter interfaces, or just use the APIs directly in your app.
App Engine includes support for two different API standards for the datastore: Java Data Objects (JDO) and Java Persistence API (JPA). These interfaces are provided by DataNucleus Access Platform, an open source implementation of several Java persistence standards, with an adapter for the App Engine datastore.
For the guest book, we'll use the JDO interface to retrieve and post messages left by users.

Setting Up DataNucleus Access Platform

Access Platform needs a configuration file that tells it to use the App Engine datastore as the backend for the JDO implementation. In the final WAR, this file is named jdoconfig.xml and resides in the directory war/WEB-INF/classes/META-INF/.
If you are using Eclipse, this file has been created for you as src/META-INF/jdoconfig.xml. This file is automatically copied into war/WEB-INF/classes/META-INF/ when you build your project.
If you are not using Eclipse, you can create the directory war/WEB-INF/classes/META-INF/ directly, or have your build process create it and copy the configuration file from another location. The Ant build script described in Using Apache Ant copies this file from src/META-INF/.
The jdoconfig.xml file should have the following contents:
<?xml version="1.0" encoding="utf-8"?>

<jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig">



    <persistence-manager-factory name="transactions-optional">

        <property name="javax.jdo.PersistenceManagerFactoryClass"

            value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/>

        <property name="javax.jdo.option.ConnectionURL" value="appengine"/>

        <property name="javax.jdo.option.NontransactionalRead" value="true"/>

        <property name="javax.jdo.option.NontransactionalWrite" value="true"/>

        <property name="javax.jdo.option.RetainValues" value="true"/>

        <property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/>

    </persistence-manager-factory>

</jdoconfig>

JDO Class Enhancement

When you create your JDO classes, you use Java annotations to describe how instances should be stored in the datastore, and how they should be recreated when retrieved from the datastore. Access Platform connects your data classes to the implementation using a post-compilation processing step, which DataNucleus calls "enhancing" the classes.
If you are using Eclipse and the Google Plugin, the plugin performs the JDO class enhancement step automatically as part of the build process.
If you are using the Ant build script described in Using Apache Ant, the build script includes the necessary enhancement step.
For more information on JDO class enhancement, see Using JDO.

POJOs and JDO Annotations

JDO allows you to store Java objects (sometimes called Plain Old Java Objects, or POJOs) in any datastore with a JDO-compliant adapter, such as DataNucleus Access Platform. The App Engine SDK includes an Access Platform plugin for the App Engine datastore. This means you can store instances of classes you define in the App Engine datastore, and retrieve them as objects using the JDO API. You tell JDO how to store and reconstruct instances of your class using Java annotations.
Let's create a Greeting class to represent individual messages posted to the guest book.
Create a new class named Greeting in the package guestbook. (Non-Eclipse users, create the file Greeting.java in the directory src/guestbook/.) Give the source file the following contents:
package guestbook;



import com.google.appengine.api.datastore.Key;

import com.google.appengine.api.users.User;



import java.util.Date;

import javax.jdo.annotations.IdGeneratorStrategy;

import javax.jdo.annotations.PersistenceCapable;

import javax.jdo.annotations.Persistent;

import javax.jdo.annotations.PrimaryKey;



@PersistenceCapable

public class Greeting {

    @PrimaryKey

    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)

    private Key key;



    @Persistent

    private User author;



    @Persistent

    private String content;



    @Persistent

    private Date date;



    public Greeting(User author, String content, Date date) {

        this.author = author;

        this.content = content;

        this.date = date;

    }



    public Key getKey() {

        return key;

    }



    public User getAuthor() {

        return author;

    }



    public String getContent() {

        return content;

    }



    public Date getDate() {

        return date;

    }



    public void setAuthor(User author) {

        this.author = author;

    }



    public void setContent(String content) {

        this.content = content;

    }



    public void setDate(Date date) {

        this.date = date;

    }

}
This simple class defines 3 properties for a greeting: author, content and date. These three private fields are annotated with @Persistent to tell DataNucleus to store them as properties of objects in the App Engine datastore.
This class defines getters and setters for the properties, which are used only by the application. Using setters is the simplest way of ensuring that the JDO implementation recognizes your updates. Modifying the fields directly bypasses a feature of JDO that saves updated fields automatically, unless you make other changes to your code to enable this
The class also defines a field named key, a Key annotated as both @Persistent and @PrimaryKey. The App Engine datastore has a notion of entity keys, and can represent the key in several different ways on the object. The Key class represents all aspects of App Engine datastore keys, including a numeric ID that is set automatically to a unique value when the object is saved.
For more information on JDO annotations, see Defining Data Classes.

The PersistenceManagerFactory

Each request that uses the datastore creates a new instance of the PersistenceManager class. It does so using an instance of the PersistenceManagerFactory class.
A PersistenceManagerFactory instance takes time to initialize. Thankfully, you only need one instance for your application, and this instance can be stored in a static variable to be used by multiple requests and multiple classes. An easy way to do this is to create a singleton wrapper class for the static instance.
Create a new class named PMF in the package guestbook (a file named PMF.java In the directory src/guestbook/), and give it the following contents:
package guestbook;



import javax.jdo.JDOHelper;

import javax.jdo.PersistenceManagerFactory;



public final class PMF {

    private static final PersistenceManagerFactory pmfInstance =

        JDOHelper.getPersistenceManagerFactory("transactions-optional");



    private PMF() {}



    public static PersistenceManagerFactory get() {

        return pmfInstance;

    }

}

Creating and Saving Objects

With DataNucleus and the Greeting class in place, the form processing logic can now store new greetings in the datastore.
Edit src/guestbook/SignGuestbookServlet.java as indicated to resemble the following:
package guestbook;



import java.io.IOException;

import java.util.Date;

import java.util.logging.Logger;

import javax.jdo.PersistenceManager;

import javax.servlet.http.*;

import com.google.appengine.api.users.User;

import com.google.appengine.api.users.UserService;

import com.google.appengine.api.users.UserServiceFactory;



import guestbook.Greeting;

import guestbook.PMF;



public class SignGuestbookServlet extends HttpServlet {

    private static final Logger log = Logger.getLogger(SignGuestbookServlet.class.getName());



    public void doPost(HttpServletRequest req, HttpServletResponse resp)

                throws IOException {

        UserService userService = UserServiceFactory.getUserService();

        User user = userService.getCurrentUser();



        String content = req.getParameter("content");

        Date date = new Date();

        Greeting greeting = new Greeting(user, content, date);



        PersistenceManager pm = PMF.get().getPersistenceManager();

        try {

            pm.makePersistent(greeting);

        } finally {

            pm.close();

        }



        resp.sendRedirect("/guestbook.jsp");

    }

}
This code creates a new Greeting instance by calling the constructor. To save the instance to the datastore, it creates a PersistenceManager using a PersistenceManagerFactory, then passes the instance to the PersistenceManager's makePersistent() method. The annotations and bytecode enhancement take it from there. Once makePersistent() returns, the new object is stored in the datastore.

Queries With JDOQL

The JDO standard defines a mechanism for querying persistent objects called JDOQL. You can use JDOQL to perform queries of entities in the App Engine datastore, and retrieve results as JDO-enhanced objects.
For this example, we will keep things simple by writing the query code directly into guestbook.jsp. For a larger application, you may want to delegate the query logic to another class.
Edit war/guestbook.jsp and add the indicated lines so that it resembles the following:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%@ page import="java.util.List" %>

<%@ page import="javax.jdo.PersistenceManager" %>

<%@ page import="com.google.appengine.api.users.User" %>

<%@ page import="com.google.appengine.api.users.UserService" %>

<%@ page import="com.google.appengine.api.users.UserServiceFactory" %>

<%@ page import="guestbook.Greeting" %>

<%@ page import="guestbook.PMF" %>



<html>

  <body>



<%

    UserService userService = UserServiceFactory.getUserService();

    User user = userService.getCurrentUser();

    if (user != null) {

%>

<p>Hello, <%= user.getNickname() %>! (You can

<a href="<%= userService.createLogoutURL(request.getRequestURI()) %>">sign out</a>.)</p>

<%

    } else {

%>

<p>Hello!

<a href="<%= userService.createLoginURL(request.getRequestURI()) %>">Sign in</a>

to include your name with greetings you post.</p>

<%

    }

%>



<%

    PersistenceManager pm = PMF.get().getPersistenceManager();

    String query = "select from " + Greeting.class.getName();

    List<Greeting> greetings = (List<Greeting>) pm.newQuery(query).execute();

    if (greetings.isEmpty()) {

%>

<p>The guestbook has no messages.</p>

<%

    } else {

        for (Greeting g : greetings) {

            if (g.getAuthor() == null) {

%>

<p>An anonymous person wrote:</p>

<%

            } else {

%>

<p><b><%= g.getAuthor().getNickname() %></b> wrote:</p>

<%

            }

%>

<blockquote><%= g.getContent() %></blockquote>

<%

        }

    }

    pm.close();

%>



    <form action="/sign" method="post">

      <div><textarea name="content" rows="3" cols="60"></textarea></div>

      <div><input type="submit" value="Post Greeting" /></div>

    </form>



  </body>

</html>
To prepare a query, you call the newQuery() method of a PersistenceManager instance with the text of the query as a string. The method returns a query object. The query object's execute() method performs the query, then returns a List<> of result objects of the appropriate type. The query string must include the full name of the class to query, including the package name.
Rebuild the project and restart the server. Visit http://localhost:8888/. Enter a greeting and submit it. The greeting appears above the form. Enter another greeting and submit it. Both greetings are displayed. Try signing out and signing in using the links, and try submitting messages while signed in and while not signed in.
Tip: In a real world application, it's a good idea to escape HTML characters when displaying user-submitted content, like the greetings in this app. The JavaServer Pages Standard Tag Library (JSTL) includes routines for doing this. App Engine includes the JSTL (and other JSP-related runtime JARs), so you do not need to include them with your app. Look for the escapeXml function in the tag library http://java.sun.com/jsp/jstl/functions. See Sun's J2EE 1.4 Tutorial for more information.

Introducing JDOQL

Our guestbook currently displays all messages ever posted to the system. It also displays them in the order they were created. When our guestbook has many messages, it might be more useful to display only recent messages, and display the most recent message at the top. We can do this by adjusting the datastore query.
You perform a query with the JDO interface using JDOQL, a SQL-like query language for retrieving data objects. In our JSP page, the following line defines the JDOQL query string:
    String query = "select from " + Greeting.class.getName();
In other words, the JDOQL query string is the following:
select from guestbook.Greeting
This query asks the datastore for every instance of the Greeting class saved so far.
A query can specify the order in which the results ought to be returned in terms of property values. To retrieve all Greeting objects in the reverse of the order in which they were posted (newest to oldest), you would use the following query:
select from guestbook.Greeting order by date desc
A query can limit the results returned to a range of results. To retrieve just the 5 most recent greetings, you would use order by and range together, as follows:
select from guestbook.Greeting order by date desc range 0,5
Let's do this for the guest book application. In guestbook.jsp, replace the query definition with the following:
    String query = "select from " + Greeting.class.getName() + " order by date desc range 0,5";
Post greetings to the guest book until there are more than 5. Only the most recent 5 are displayed, in reverse chronological order.
For more information about queries and JDOQL, see Queries and Indexes.

Using Static Files

There are many cases where you want to serve static files directly to the web browser. Images, CSS stylesheets, JavaScript code, movies and Flash animations are all typically served directly to the browser. For efficiency, App Engine serves static files from separate servers than those that invoke servlets.
By default, App Engine makes all files in the WAR available as static files except JSPs and files in WEB-INF/. Any request for a URL whose path matches a static file serves the file directly to the browser—even if the path also matches a servlet or filter mapping. You can configure which files App Engine treats as static files using the appengine-web.xml file.
Let's spruce up our guest book's appearance with a CSS stylesheet. For this example, we will not change the configuration for static files. See App Configuration for more information on configuring static files and resource files.

A Simple Stylesheet

In the directory war/, create a directory named stylesheets/. In this directory, create a file named main.css with the following contents:
body {
    font-family: Verdana, Helvetica, sans-serif;
    background-color: #FFFFCC;
}
Edit war/guestbook.jsp and insert the following lines just after the <html> line at the top:
<html>
  <head>
    <link type="text/css" rel="stylesheet" href="/stylesheets/main.css" />
  </head>
 
  <body>
    ...
  </body>
</html>
Visit http://localhost:8888/. The new version uses the stylesheet.

Uploading Your Application

You create and manage applications in App Engine using the Administration Console. Once you have registered an application ID for your application, you upload it to App Engine using either the Eclipse plugin, or a command-line tool in the SDK.
Note: Once you register an application ID, you can delete it, but you can't re-register that same application ID after it has been deleted. You can skip these next steps if you don't want to register an ID at this time.

Registering the Application

You create and manage App Engine web applications from the App Engine Administration Console, at the following URL:
https://appengine.google.com/
Sign in to App Engine using your Google account. If you do not have a Google account, you can create a Google account with an email address and password.
To create a new application, click the "Create an Application" button. Follow the instructions to register an application ID, a name unique to this application. If you elect to use the free appspot.com domain name, the full URL for the application will be http://application-id.appspot.com/. You can also purchase a top-level domain name for your app, or use one that you have already registered.
Edit the appengine-web.xml file, then change the value of the <application> element to be your registered application ID.

Uploading the Application

You can upload your application using Eclipse, or using a command at the command prompt.

Uploading From Eclipse

You can upload your application code and files from within Eclipse using the Google Plugin.
To upload your application from Eclipse, click the App Engine deploy button on the toolbar: The App Engine deploy button.
Enter your Google account username (your email address) and password when prompted, then click the Upload button. Eclipse gets the application ID and version information from the appengine-web.xml file, and uploads the contents of the war/ directory.

Uploading Using the Command Prompt

You can upload your application code and files using a command included in the SDK named appcfg.cmd (Windows) or appcfg.sh (Mac OS X, Linux).
AppCfg is a multi-purpose tool for interacting with your app on App Engine. The command takes the name of an action, the path to your app's war/ directory, and other options. To upload the app code and files to App Engine, you use the update action.
To upload the app, using Windows:
..\appengine-java-sdk\bin\appcfg.cmd update war
To upload the app, using Mac OS X or Linux:
../appengine-java-sdk/bin/appcfg.sh update war
Enter your Google username and password at the prompts.

Accessing Your Application

You can now see your application running on App Engine. If you set up a free appspot.com domain name, the URL for your website begins with your application ID:
http://application-id.appspot.com/
This is all about Google App Engine. In next blog, we will try to explore Aptana Cloud and Stax Cloud.

Please click on any advertisement if you like this blog.

1 comment:

  1. http://www.techiesinfo.com/

    My website is running on Google app engine since 2009

    ReplyDelete

Please provide your precious comments and suggestion