Friday, February 24, 2012

Metawidget and AeroGear

Recently I've been working with the JBoss AeroGear team. AeroGear is a new JBoss initiative focussed on providing examples, tutorials, and techniques to help developers get going with all kinds of mobile development.

We've been creating a 'proof of concept' integration between JBoss Forge and Metawidget for scaffolding mobile apps. Like the Forge/Metawidget/JSF scaffold, it uses static generation and doesn't require Metawidget at runtime. Unlike the JSF scaffold, however, the AeroGear scaffold generates a POH5/JQuery app. It's heavily based on Jay Balunas' excellent AeroGear Maven archetype - thanks Jay!

The Story So Far

An update on our progress. The plugin is hosted at First download the latest version of JBoss Forge and run it. Then install the plugin:

$ forge git-plugin git://

Setup your project:

$ new-project --named test --topLevelPackage com.test --type war
$ persistence setup
? [provider=ARG (of type org.jboss.forge.spec.javaee.jpa.api.JPAProvider)]: HIBERNATE
? [container=ARG (of type org.jboss.forge.spec.javaee.jpa.api.JPAContainer)]: JBOSS_AS7
$ scaffold setup --scaffoldType aerogear
$ entity --named Company
$ field string --named name
$ field boolean --named publiclyListed
$ field custom --named color
? [type=The qualified Class to be used as this field's type (of type java.lang.String)]: java.awt.Color
$ entity --named Employee
$ field string --named firstName
$ field string --named lastName
$ field custom --named dateOfBirth
? [type=The qualified Class to be used as this field's type (of type java.lang.String)]: java.util.Date
$ field int --named salary
$ field manyToOne --named company --fieldType com.test.model.Company
$ scaffold from-entity com.test.model.* --scaffoldType aerogear

This will generate a complete app, ready to import into your favourite IDE and deploy. To save time, you can download the generated app here (click the link, then use File > Download to download the ZIP).

Kick The Tyres

Deploy the app (I tested on JBoss AS 7.0.2.Final, please try this exact version) and open it in an HTML5-compliant browser or mobile device (I tested on Chrome):

The opening screen displays a menu generated from the entities in your domain model. Here we're developing a little employee database. Click on Company:

This screen allows you to search for existing companies. But we need to create some first! Click on Create:

Fill out the fields as shown above. Things to note:
  • All the form fields and labels have been generated by Metawidget
  • This includes a custom PlaceholderWidgetProcessor for HTML5 placeholders such as 'Your Color'
  • It also includes correct HTML5 controls, such as checkbox and the new color input. Unfortunately Chrome doesn't seem to recognize this yet
Click Save to return to the search screen:

Things to note:
  • The company has been saved to the database and redisplayed in the search results, using JQuery, JSON and JPA
  • Metawidget has generated the 'name' field as an HTML5 search control
  • Metawidget has generated appropriate columns for the search results table
  • Search fields work as expected. If you click 'publicly listed' and hit Search, you'll only see companies where 'publicly listed' has been set to true. This uses JQuery, JSON, JPA and the Criteria API
Click on a row in the table to view and edit it:

Things to note:
  • Metawidget has generated a read-only view of the entity
  • This includes using HTML5 output controls
Next, click back to the Home screen, click on Employee and click Create:

Things to note:
  • Metawidget has generated HTML5 date and number controls where appropriate. Again, Chrome's support is limited
  • There is a many-to-one relation between an employee and their company. This is presented as a dropdown. Possible values are populated using JQuery, JSON and JPA
  • The values in the dropdown use the toString of the company object. This uses a custom ObjectMapperProvider
Click Save and create some more employees:

Searching on a many-to-one relation also works:

Things to note:
  • The 'Company' column in the table uses the toString of the company object
The Road Ahead

That's it so far! We hope this gives a compelling proof of concept for generating mobile applications using AeroGear, JBoss Forge and Metawidget. But there's lots more to do, so please join the community and start contributing!


Orfeo Morello said...

Not work with the Final 1.0.0 Version of Forge. This is the message i read when Forge 1.0.0 Final start:
Not loading plugin [org.jboss.forge.plugins.aerogear.plugin-scaffold-aerogear] b
ecause it references Forge API version [1.0.0.CR2] which may not be compatible w
ith my current version [1.0.0.Final]. To remove this plugin, type 'forge remove-
plugin org.jboss.forge.plugins.aerogear.plugin-scaffold-aerogear:1.0.0.CR2:1.0.0
Can you fix this?

Richard said...

Apologies. Please try again now?

Sander Mak said...

Installing the plugin fails for me with:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project plugin-scaffold-aerogear: Compilation f
ailure: Compilation failure:
[ERROR] \Users\SANDER~1.CRO\AppData\Local\Temp\forgetemp7303795455950580071\repo\src\main\java\org\jboss\forge\scaffold\aerogear\metawidget\config\ForgeConfigRe[67,3] method does not override or implement a method from a supertype
[ERROR] \Users\SANDER~1.CRO\AppData\Local\Temp\forgetemp7303795455950580071\repo\src\main\java\org\jboss\forge\scaffold\aerogear\metawidget\inspector\propertyst
yle\[512,59] type parameters of T cannot be determined; no unique maximal instance exists for type variable T with upper bounds T,jav

(using forge 1.0.0.Final to install, on Java 1.7_03)

Richard said...

First error should now be resolved. Apologies. Not sure about the second. Can you try on Java 1.6?

Sander Mak said...

Thanks, first issue is indeed gone, but second one still persists (also with Java 6)

Richard said...

I'm afraid I'm having difficulty reproducing this. Here's what I see...

...when running with Forge 1.0.0.Final and Java 1.6.0_25 on Windows x64.

Richard said...

Checked in a speculative fix. Can you please retry?

Orfeo Morello said...

I managed to make everything work, thanks for your support. My platform is windows7 64 bit and Java(TM) SE Runtime Environment (build 1.6.0_29-b11) Java HotSpot(TM) 64-Bit Server VM (build 20.4-b02, mixed mode)

Nisar said...

following statement give the below error on ubuntu with java6 $ scaffold from-entity com.aeromediremin.model.* --scaffoldType aerogear
***ERROR*** [scaffold from-entity] org.jboss.forge.scaffold.aerogear.AeroGearScaffold.generateFromEntity(Lorg/jboss/forge/resources/Resource;Lorg/jboss/forge/parser/java/JavaClass;Z)Ljava/util/List;

Richard said...

The latest version of the AeroGear plugin targets the new Forge API (1.0.1 and above). But this error appears to be because the old Forge API (1.0.0.Final) is trying to call the new AeroGear plugin.

Can you please post full details to the forge-dev mailing list?

Nisar said...

Hi Richard.. my apologies for not following the last comment... today(at last moment) I am in same situation please help...

[no project] myproj $ version
JBoss Forge, version [ 1.1.0.Final ] - JBoss, by Red Hat, Inc. [ ]

[myproj] myproj $ scaffold setup --scaffoldType aerogear
***ERROR*** Exception encountered: (type "set VERBOSE false" to disable stack traces)
java.lang.AbstractMethodError: org.jboss.forge.scaffold.aerogear.AeroGearScaffold.setup(Ljava/lang/String;Lorg/jboss/forge/resources/Resource;Z)Ljava/util/List;
at org.jboss.forge.scaffold.plugins.ScaffoldPlugin.setup(
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(

[myproj] myproj $ scaffold from-entity com.myproj.model.* --scaffoldType aerogear
***ERROR*** Exception encountered: (type "set VERBOSE false" to disable stack traces)
java.lang.AbstractMethodError: org.jboss.forge.scaffold.aerogear.AeroGearScaffold.generateFromEntity(Ljava/lang/String;Lorg/jboss/forge/resources/Resource;Lorg/jboss/forge/parser/java/JavaClass;Z)Ljava/util/List;
at org.jboss.forge.scaffold.plugins.ScaffoldPlugin.generateFromEntity(
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

Richard said...

This is likely due to Forge API changes. Can you please post this error to the forge-dev mailing list?

I believe José Donizetti was looking at updating the Aerogear plugin to work with the newer version of Forge.

Nisar said...

Hi Richard,
Thanks for the reply, The issue from last time I believe was there was a field type boolean iAgree was creating problem, as while submitting it was getting converted to upper case as IAgree after changing to agreeTerms it worked.

Another issue I am facing today is while submitting a form Textarea value is going null and radio button last option value is getting submitted, I believe there is a issue in forge-aerogear.js at serializeFromForm else { dest[] = this.value; }
can you please help to fix. Regards

Richard said...

Hi Nisar,

The issue regarding iAgree should have been fixed in the latest version of Metawidget (2.4). Could you please try upgrading the version inside the scaffold?

The issue to do with 'going null' sounds outside the scope of this proof-of-concept. It sounds like a small bug, for which I'm sure the AeroGear team would welcome a fix, rather than a show-stopper for proving the overall concept?

Contributions welcome!