Google App Engine (GAE) is a platform-as-a-service (PaaS) offering from Google, which supports cloud deployment of applications written in Java and other languages, as well as SQL or JPA access to highly scalable storage (both Google CloudSQL and BigTable-based solutions).SmartClient applications, including those based on the SmartClient Server Framework, can be deployed to GAE and can integrate with Google CloudSQL either via SQLDataSource or via JPA, and can also use Google's BigTable-based storage via JPAGoogle App Engine (GAE) is a platform-as-a-service (PaaS) offering from Google, which supports cloud deployment of applications written in Java and other languages, as well as SQL or JPA access to highly scalable storage (both Google CloudSQL and BigTable-based solutions).
SmartClient applications, including those based on the SmartClient Server Framework, can be deployed to GAE and can integrate with Google CloudSQL either via SQLDataSource or via JPA, and can also use Google's BigTable-based storage via JPA.
SmartGWT 4.1d and later now includes sample projects for GAE that already take care of most of the concerns covered in the rest of this article. All the necessary steps to get the sample projects running are described in the readme file for each sample.
Setting up Smart GWT application for GAE
Under the /WEB-INF
directory you have to create a file named appengine-web.xml
which will hold Google's specific settings. At least, you must set threadsafe flag to "true".
We must take into account that, in GAE “...by default, all files in the WAR are treated as both static files and resource files, except for JSP files, which are compiled into servlet classes and mapped to URL paths, and files in the WEB-INF/ directory, which are never served as static files and always available to the app as resource files.” On the other hand, “App Engine serves static files from dedicated servers and caches that are separate from the application servers.”. This means that all our files, except JSP files and files under WEB-INF, are DUPLICATED both in app server and in dedicated servers. As a typical Smart GWT application consists of many resources, when those resources are duplicated we could exceed the “Code and Static File Storage” quota (currently 1Gb) or go beyond the limit of static files (10.000 per application). To avoid this, we can split our files between static and dynamic resources in appengine-web.xml. This is an example configuration:
appengine-web.xml |
<?xml version="1.0" encoding="UTF-8"?> <threadsafe>true</threadsafe> <static-files> |
PATH_TO_DATA_SOURCE_FILES: is the path to the folder that contains the DataSource definition files, as defined in “project.datasources”, either in server.properties file or in admin console.
MODULE_NAME: The GWT module name, as defined in your GWT module descriptor file.
With this change, we have reduced the size of the GAEDS example application from 140Mb to 100Mb.
Setting up DataSources
...
Using CloudSQL as a SQL DataSource
Using CloudSQL as a JPA DataSource
- Using DataStore as a limited JPA DataSource (severely limited and not recommended)
As a summary, these are the main differences among the three approaches. Anchor sample_code sample_code
CloudSQL Datasource | JPA2 Datasource | Datastore Datasource | |
Example code | gae-cloudSQL | gae-JPA-cloudSQL | gae-JPA-noSQL |
serverType (in server.properties) | sql | no need to specify | no need to specify |
records | SQL rows | java beans | java beans |
record definition (in *.ds.xml) | tableName | schemaBean or beanClassName | schemaBean or beanClassName |
DB Connector | com.isomorphic.sql.SQLDataSource | com.isomorphic.jpa.JPA2DataSource | com.isomorphic.jpa.GAEJPADatasource |
Conector Driver | com.google.appengine.api.rdbms.AppEngineDriver | com.google.appengine.api.rdbms.AppEngineDriver | no need to specify |
Connection config | server.properties* | persistence.xml** | persistence.xml*** |
Connector Library | isomorphic_sql.jar | isomorphic_jpa.jar | no need to specifyisomorphic_jpa.jar |
Other required libraries | commons-codec-1.3.jar commons-collections-3.2.1.jar commons-dbcp-1.2.2.jar commons-fileupload-1.2.1.jar commons-jxpath-1.3.jar commons-lang-2.4.jar commons-pool-1.4.jar isc-jakarta-oro-2.0.6.jar isomorphic_core_rpc.jar isomorphic_sql.jar smartgwt-skins.jar smartgwt.jar smartgwtee.jar velocity-1.7.jar When using tools: commons-cli-1.1.jar commons-lang-2.4.jar hibernate3.jar isomorphic_hibernate.jar isomorphic_tools.jar | commons-codec-1.3.jar commons-collections-3.2.1.jar velocitycommons-fileupload-1.2.71.jar When using tools: commons-clijxpath-1.13.jar commons-langpool-21.4.jar hibernate3eclipselink.jar isc-jakarta-oro-2.0.6.jar isomorphic_hibernatecore_rpc.jar isomorphic_toolsjavax.persistence_2.0.4.v201112161009.jar commons-codec-1.3smartgwt-skins.jar smartgwt.jar smartgwtee.jar commons-collectionslog4j-31.2.115.jar commonsvelocity-fileupload-1.27.1.jar When using tools: commons-jxpathcli-1.31.jar commons-poollang-12.4.jar eclipselinkhibernate3.jar isc-jakarta-oro-2.0.6.isomorphic_hibernate.jar isomorphic_core_rpcsql.jar javax.persistenceisomorphic_2.0.4.v201112161009tools.jar | commons-codec-1.3.jarsmartgwt commons-collections-skins3.jar smartgwt.jar smartgwtee2.1.jar log4jcommons-fileupload-1.2.151.jar velocitycommons-jxpath-1.73.jar When using tools: commons-clipool-1.14.jarcommons isc-jakarta-langoro-2.40.jarhibernate36.jar isomorphic_hibernate.jarisomorphic_sqlcore_rpc.jar isomorphic_tools.jar isomorphic_jpa.jar isomorphic_js_parser.jar smartgwt-skins.jar smartgwt.jar smartgwtee.jar log4j-1.2.15.jar velocity-1.7.jar When using tools: commons-cli-1.1.jar commons-lang-2.4.jar hibernate3.jar isomorphic_hibernate.jar isomorphic_sql.jar isomorphic_tools.jar |
Comments | You start your project as a GWT + GAE project in eclipse. Then add the required libraries, modify web.xml, create the datasource descriptors, create tables and finally configure “server.properties”. | Setup your eclipse project as specified in this doc. Add the extra libraries, modify web.xml, create the datasource descriptors, configure “persistence.xml”, create the persistent objects, create the tables (maybe automatically). | You start your project as a GWT + GAE project in eclipse. Then add the required libraries, modify web.xml, create the datasource descriptors and create the persistent objects. |
*server.properties: see example below
**persistence.xml: see example below
***persistence.xml is automatically generated when using Datastore.
Terms:
DataSource: “is data-provider-independent description of a set of objects that will be loaded, edited and saved within the user interface of your application”
Record: each datasource access to one kind of record. A record is a set of Fields.
Field: the components of Records. May have types, validators, etc.
DB Connector: each DataSource retrieves Records of one type, accessing a DB via DBConnector
DataBinding: “is the process by which Data Binding-capable UI components can automatically configure themselves for viewing, editing and saving data described by DataSources.”
DataIntegration: “is the process by which a DataSource can be connected to server systems such as SQL DataBases, Java Object models, WSDL web services and other data providers.” It can be server-side or client-side.
...
To define a Google CloudSQL database as your default database in server.properties
you you will have to define some properties, as shown below. Take into account that you will have to use the "url" format for the connection (you cannot configure it field by field).
server.properties |
|
|
|
|
|
|
|
|
|
|
|
|
where instance_name is the instance Name field, as it appears in the Google APIs Console, and db_name is the name of the SQL database that you created for this project with "CREATE DATABASE db_name".
If you are using the admin console, you will find pre-configured settings as "GoogleCloudSQL".
Using CloudSQL as a JPA2 DataSource
Object Relational Mapping (ORM) frameworks are very popular in the Java community for accessing relational databases. The Eclipse Web Tools Platform offers a robust set of tools to configure and use JPA with an implementation of your choice. With the new Google Plugin for Eclipse 2.6, you can now take advantage of these tools with Cloud SQL and Google App Engine. In any Google Plugin for Eclipse project, JPA can now be enabled and configured as a project facet.
You can find detailed information on how to configure your project to work with JPA2 and CloudSQL in the Google's document "Using Java Persistence API (JPA) with Cloud SQL". The list of required libraries is in the table above (under Data Integration strategies). Finally, using the eclipse "Persistence XML Editor" you will be able to configure properly the connection data, the driver to use, defining the persistent classes, etc in persistence.xml.
...
persistence.xml.
persistence.xml |
|
...
|
...
|
...
|
...
<persistence |
...
xmlns="http://java.sun.com/xml/ns/persistence" |
...
|
...
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence |
...
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" |
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
value="user_name"/> |
...
|
...
value="password"/> |
...
|
...
|
...
|
where instance_name is the instance Name field, as it appears in the Google APIs Console, db_name is the name of the SQL database that you created for this project with "CREATE DATABASE db_name", user_name is the name of a database user with access to the tables, and password is the password of the database user.
Using DataStore as a (limited) JPA2 DataSource
Notice that Google's JPA implementation is really wrapping a "NoSQL" type of engine, with severe limitations. We recommend CloudSQL as the first choice.
...