Preview: Java Bean support with Ext GWT
July 14, 2008 by Darrell Meyer
The Ext GWT Store and Binder API work with ModelData instances. The primary goal of ModelData is to provide a type of “introspection” as GWT does not allow runtime inspection of Java objects. You can query ModelData for a list of properties it contains, and these properties can be retrieved and set using the parameter name with the get and set methods.
Although this approach works, it forces you to either implement the ModelData interface in your Java Beans or extend the Ext GWT base classes that implement the ModelData interface. What is missing is a way to use your Java Beans as is, without having to extend the Ext GWT base classes or implement an “invasive” interface.
With the 1.1 release of Ext GWT, it is possible to use any Java Beans in the Store and Binder API. This allows you to send your Java Beans from server to client using GWT RPC.
Java Bean support is provided by dynamically creating new BeanModel instances using any bean. The new type will “wrap” the bean, and all get and set calls on the model will be delegated to the underlying bean. Also, the original bean is available via the new bean model instance. The new model instances are created using a GWT Generator. Basically, the generator allows “new” types to be created at compile time using GWT.create(). The GXT generator will create a BeanModelFactory than can create new BeanModel instances from a Java Bean.
Identifying Java Beans
There are 2 ways of identifying Java Beans. The first method requires a new interface that extends BeanModelMarker and uses annotations. This method does not require the JavaBean to be modified. With the second method, your Java Bean implements the BeanModelTag interface.
BeanModellMarker Interface
The first step to enable Java Bean support is to identify the Class you would like to “adapt”. Rather than specifying the class directly, a new interface is created that extends BeanModelMarker. Then, a @BEAN annotation is added to the interface to identify the actual bean. This approach is beneficial, as it allows a single deferred binding rule to be used to identify your bean. Also, by using a marker interface, other configuration information can be specified by annotations.
public class Customer implements Serializable { private String name; private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } } @BEAN(Customer.class) public interface CustomerBeanModel extends BeanModelMarker { }
BeanModelTag Interface
With this method, a new interface is not required as you tag the Java Bean directly. This means your beans will have a reference to a GXT interface.
public class Customer implements BeanModelTag, Serializable { private String name; private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
BeanModelLookup
BeanModelLookup is used to obtain a BeanModelFactory instance for a given bean type. You will use the BeanModelLookup singleton to obtain a BeanModelFactory for your given bean. The BeanModelFactory can be used to create new bean model instances from your bean instances.
BeanModelFactory factory = BeanModelLookup.get().getFactory(Customer.class);
With the factory, you are able to create new BeanModel instances that wrap your bean.
Customer c = new Customer(); c.setName("Darrell"); BeanModel model = factory.createModel(c);
BeanModelReader
It is common to use the GXT data loading API to retrieve remote data and populate a Store. The BeanModelReader can be used to handle creating new model instances from the beans being returned from the data proxy. With this approach, you can return any Java Beans from the RPC call. BeanModelReader will lookup the factory given the type of the objects being returned from the data proxy.
Store
When using this approach, the type of objects in the store will be the dynamically created types that were created based on the bean. These objects will extend BeanModel. BeanModel provides access to the “wrapped” bean via the getBean method.
Customer customer = (Customer)model.getBean();
Grid Example
Here is a snippet of code from the Explorer demo. It demonstrates uses a BeanModelReader with a Grid.
// gwt service final ExplorerServiceAsync service = (ExplorerServiceAsync) Registry.get("service"); // proxy and reader RpcProxy proxy = new RpcProxy() { @Override public void load(Object loadConfig, AsyncCallback callback) { service.getCustomers(callback); } }; BeanModelReader reader = new BeanModelReader(); // loader and store ListLoader loader = new BaseListLoader(proxy, reader); ListStore<BeanModel> store = new ListStore<BeanModel>(loader); loader.load(); // column model List<ColumnConfig> columns = new ArrayList<ColumnConfig>(); columns.add(new ColumnConfig("name", "Name", 200)); columns.add(new ColumnConfig("email", "Email", 100)); columns.add(new ColumnConfig("age", "Age", 50)); ColumnModel cm = new ColumnModel(columns); Grid<BeanModel> grid = new Grid<BeanModel>(store, cm); grid.setAutoExpandColumn("name"); grid.setWidth(400); grid.setAutoHeight(true); grid.setBorders(true);
Summary
The new Java Bean support allows easy data integration of your existing Java Bean objects. Sending any Java Bean over the wire is possible, and Ext GWT can create bean model instances on the client.
These features will be available with the 1.1 release of Ext GWT. For those with access to SVN, the working code is in the trunk.


Posted on July 14th, 2008 at 11:33 pm
Nice work, just got it from svn and it works great!
Posted on July 15th, 2008 at 9:11 pm
OH~ it’s like great!
Posted on August 26th, 2008 at 1:42 am
[...] Java bean support [...]
Posted on September 3rd, 2008 at 10:51 am
Hi,
I’m trying to use GXT 1.1alpha3 and can’t get the table equivalent of “grid example” working.
Did anything change in the mean time?
I’m using it this order:
BeanModelReader reader = new BeanModelReader();
BasePagingLoader loader = new BasePagingLoader(proxy, reader);
loader.load(0, 20);
ListStore store = new ListStore(loader);
final PagingToolBar toolbar = new PagingToolBar(20);
toolbar.bind(loader);
new TableBinder(table, store);
Anything terrebly wrong?
Posted on September 5th, 2008 at 5:01 am
Any idea on how to wire Enteprise Java Beans over the wire?
First problem is that the EJB wont compile in gwt becouse they relate to annotatioons in javax.persistence.*;
I then made fake annotation files, that made the gwt js compile and run.
But then the gwt-servlet fails to serialize the beans for transmission
This error is shown in console:
Caused by: com.google.gwt.user.client.rpc.SerializationException: Type ‘oracle.toplink.essentials.internal.indirection.UnitOfWorkQueryValueHolder’ was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.
Posted on September 18th, 2008 at 1:39 am
[...] With the 1.1 release of Ext GWT, it is possible to use any Java Beans in the Store and Binder API. This allows you to send your Java Beans from server to client using GWT RPC. More information can be found in this blog post. [...]
Posted on October 4th, 2008 at 5:01 pm
I’m trying to get the Java Bean stuff working.
But when I follow your example using the factory the system won’t compile.
This is caused by the fact that the GWT compiler can’t find the BeanModelLookup implementation which is made at run-time, but I need it to create instance of my model.
At the following code to a project that is not build with the GXT.gwt.xml.
BeanModelFactory factory = BeanModelLookup.get().getFactory(MyJavaBean.class);
BeanModel model = factory.createModel(myJavaBean);
Posted on October 4th, 2008 at 5:06 pm
Hereby the build error,
Scanning for additional dependencies: jar:file:/G:/gwt/gxt-1.1/gxt.jar!/com/extjs/gxt/ui/client/data/BeanModelLookup.java
Computing all possible rebind results for ‘com.extjs.gxt.ui.client.data.BeanModelLookup’
Rebinding com.extjs.gxt.ui.client.data.BeanModelLookup
Invoking
[ERROR] Class com.extjs.gxt.ui.client.data.BeanModelLookup not found.
java.lang.NullPointerException
at com.extjs.gxt.ui.rebind.core.BeanModelGenerator.getMarkerBean(BeanModelGenerator.java:169)
at com.extjs.gxt.ui.rebind.core.BeanModelGenerator.generate(BeanModelGenerator.java:53)
at com.google.gwt.dev.cfg.RuleGenerateWith.realize(RuleGenerateWith.java:51)
at com.google.gwt.dev.shell.StandardRebindOracle$Rebinder.tryRebind(StandardRebindOracle.java:116)
at com.google.gwt.dev.shell.StandardRebindOracle$Rebinder.rebind(StandardRebindOracle.java:61)
at com.google.gwt.dev.shell.StandardRebindOracle.rebind(StandardRebindOracle.java:166)
at com.google.gwt.dev.GWTCompiler$DistillerRebindPermutationOracle.getAllPossibleRebindAnswers(GWTCompiler.java:195)
at com.google.gwt.dev.jdt.WebModeCompilerFrontEnd.doFindAdditionalTypesUsingRebinds(WebModeCompilerFrontEnd.java:128)
at com.google.gwt.dev.jdt.AbstractCompiler$CompilerImpl.process(AbstractCompiler.java:150)
at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:392)
at com.google.gwt.dev.jdt.AbstractCompiler$CompilerImpl.compile(AbstractCompiler.java:84)
at com.google.gwt.dev.jdt.AbstractCompiler$CompilerImpl.compile(AbstractCompiler.java:180)
at com.google.gwt.dev.jdt.AbstractCompiler$CompilerImpl.access$400(AbstractCompiler.java:70)
at com.google.gwt.dev.jdt.AbstractCompiler.compile(AbstractCompiler.java:493)
at com.google.gwt.dev.jdt.WebModeCompilerFrontEnd.getCompilationUnitDeclarations(WebModeCompilerFrontEnd.java:73)
at com.google.gwt.dev.jjs.JavaToJavaScriptCompiler.(JavaToJavaScriptCompiler.java:277)
at com.google.gwt.dev.GWTCompiler.distill(GWTCompiler.java:353)
at com.google.gwt.dev.GWTCompiler.run(GWTCompiler.java:564)
at com.google.gwt.dev.GWTCompiler.run(GWTCompiler.java:554)
at com.google.gwt.dev.GWTCompiler.main(GWTCompiler.java:214)
[ERROR] Errors in ‘jar:file:/G:/gwt/gxt-1.1/gxt.jar!/com/extjs/gxt/ui/client/data/BeanModelLookup.java’
[ERROR] Line 17: Failed to resolve ‘com.extjs.gxt.ui.client.data.BeanModelLookup’ via deferred binding
Posted on October 19th, 2008 at 4:55 pm
Any solution for the error during build process ?
[ERROR] Line 17: Failed to resolve ‘com.extjs.gxt.ui.client.data.BeanModelLookup’ via deferred binding
Posted on October 21st, 2008 at 5:48 pm
Any progress about this issue? Deferred binding for BeanModel works in hosted-mode browser, but it does not compile for deployment.
Posted on October 23rd, 2008 at 4:05 pm
Hi,
I got the exactly same problem, but just resolved it !
The problem for me was a wrong classpath for the GWT-compiler. You could try to include your compiled source classes for your domain classes to your classpath – that solved my problem.
My ant target look like this:
—————————————————————
GWT version=${toolsetup.gwt}
Classpath is : ${gwt.classpath.tmp}
————————————
the property “classes.main.dir” points to my compiled domain source classes.
Hope this can point you in the right direction…
Best regards Martin
Posted on October 23rd, 2008 at 4:08 pm
<![CDATA[
GWT version=${toolsetup.gwt}
Classpath is : ${gwt.classpath.tmp}
]]>
Posted on October 23rd, 2008 at 11:52 pm
What happens if I do the following?
Customer customer = (Customer)model.getBean();
customer.setName(”David”);
Is the model updated? Or is the model only updated if I call model.set(”name”, “David”) directly?
Thanks.
David
Posted on November 6th, 2008 at 1:30 pm
I am still getting that
[ERROR] Class com.extjs.gxt.ui.client.data.BeanModelLookup not found.
java.lang.NullPointerException
When I try to build through ANT. I am using gwt-1.5.0 and gxt-1.1.2 and don’t seem to be using any of the features that would require the BeanModelReader, etc, unless it is hidden (guessing it is).
Has anyone found a way to make this work? The solution of listing the temp directory doesn’t seem to work – unless I am doing it wrong. Can someone help me out with what specifically the post above really meant?
GWT version=${toolsetup.gwt}
Classpath is : ${gwt.classpath.tmp}
What directory is gwt.classpath.tmp? specifically? I was assuming it was /www/.gwt-tmp but that isn’t working.
Posted on November 28th, 2008 at 6:36 pm
Any progress about this issue? Deferred binding for BeanModel works in hosted-mode browser, but it does not compile for deployment.
Posted on January 5th, 2009 at 11:42 pm
I am using eclipse and cypal. What do I configure?
Posted on January 13th, 2009 at 5:55 am
i got the same problem with this Errors:
still have this problem, hope someboby resolve it ,pls tell us! 3X!
Computing all possible rebind results for ‘com.extjs.gxt.ui.client.data.BeanModelLookup’
Rebinding com.extjs.gxt.ui.client.data.BeanModelLookup
Invoking
[ERROR] Class com.extjs.gxt.ui.client.data.BeanModelLookup not found.
java.lang.NullPointerException
at com.extjs.gxt.ui.rebind.core.BeanModelGenerator.getMarkerBean(BeanModelGenerator.java:169)
at com.extjs.gxt.ui.rebind.core.BeanModelGenerator.generate(BeanModelGenerator.java:53)
at com.google.gwt.dev.cfg.RuleGenerateWith.realize(RuleGenerateWith.java:51)
at com.google.gwt.dev.shell.StandardRebindOracle$Rebinder.tryRebind(StandardRebindOracle.java:116)
at com.google.gwt.dev.shell.StandardRebindOracle$Rebinder.rebind(StandardRebindOracle.java:61)
at com.google.gwt.dev.shell.StandardRebindOracle.rebind(StandardRebindOracle.java:166)
at com.google.gwt.dev.GWTCompiler$DistillerRebindPermutationOracle.getAllPossibleRebindAnswers(GWTCompiler.java:195)
at com.google.gwt.dev.jdt.WebModeCompilerFrontEnd.doFindAdditionalTypesUsingRebinds(WebModeCompilerFrontEnd.java:128)
at com.google.gwt.dev.jdt.AbstractCompiler$CompilerImpl.process(AbstractCompiler.java:150)
at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:392)
at com.google.gwt.dev.jdt.AbstractCompiler$CompilerImpl.compile(AbstractCompiler.java:84)
at com.google.gwt.dev.jdt.AbstractCompiler$CompilerImpl.compile(AbstractCompiler.java:180)
at com.google.gwt.dev.jdt.AbstractCompiler$CompilerImpl.access$400(AbstractCompiler.java:70)
at com.google.gwt.dev.jdt.AbstractCompiler.compile(AbstractCompiler.java:493)
at com.google.gwt.dev.jdt.WebModeCompilerFrontEnd.getCompilationUnitDeclarations(WebModeCompilerFrontEnd.java:73)
at com.google.gwt.dev.jjs.JavaToJavaScriptCompiler.(JavaToJavaScriptCompiler.java:277)
at com.google.gwt.dev.GWTCompiler.distill(GWTCompiler.java:353)
at com.google.gwt.dev.GWTCompiler.run(GWTCompiler.java:564)
at com.google.gwt.dev.GWTCompiler.run(GWTCompiler.java:554)
at com.google.gwt.dev.GWTCompiler.main(GWTCompiler.java:214)
[ERROR] Errors in ‘file:/D:/iread_src/trunk/1.Manager/iReadManagerClient/src/com/extjs/gxt/ui/client/data/BeanModelLookup.java’
[ERROR] Line 17: Failed to resolve ‘com.extjs.gxt.ui.client.data.BeanModelLookup’ via deferred binding
Posted on January 24th, 2009 at 2:10 pm
If you want to develop GXT with Eclipse + Cypal, You can read this article
http://extjs-gwt.blogspot.com/
I think this can help you.
Posted on July 3rd, 2009 at 6:31 am
Any idea on how to wire Enteprise Java Beans over the wire?
First problem is that the EJB wont compile in gwt becouse they relate to annotatioons in javax.persistence.*; Medyum ;
I then made fake annotation files, that made the gwt js compile and run.
But then the gwt-servlet fails to serialize the beans for transmission
Posted on July 23rd, 2009 at 11:00 am
I am using eclipse and cypal. What do I configure?
Posted on July 23rd, 2009 at 1:05 pm
I think this can help you.
Posted on August 5th, 2009 at 12:30 pm
thanks a lot…
medyum oguz
Posted on August 12th, 2009 at 3:08 am
Unable to get Bean Model Data Grid working . Can anyone help me out on why my data grid is not working . I checked the callback object . Its comming up right from the server . Here is my code .
Just the data grid with collumn header comes up .
MY DTO : EmpCounty implements BeanModelTag, Serializable
VerticalPanel vp = new VerticalPanel();
// proxy and reader
final RpcProxy<List> proxyB = new RpcProxy<List>() {
@Override
public void load(Object loadConfig, AsyncCallback<List> callback) {
String key = “israel”;
myService.loadObject(key, callback);
loader.load();
}
};
BeanModelReader reader = new BeanModelReader();
// loader and store
ListLoader<ListLoadResult> loader = new BaseListLoader<ListLoadResult>(proxyB, reader);
ListStore store ;
store = new ListStore(loader);
loader.load()
// column model
List columns = new ArrayList();
columns.add(new ColumnConfig(”name”, “name”, 200));
columns.add(new ColumnConfig(”country”, “country”, 100));
ColumnModel cm = new ColumnModel(columns);
Grid grid = new Grid(store, cm);
grid.setAutoExpandColumn(”country”);
grid.setHeight(300);
vp.add(grid);
RootPanel.get().add(vp);
Posted on August 12th, 2009 at 3:50 am
Well Folks , I got the above stuff working , but now I am attaching a button to my vertical panel and on click of a button , i want to reload the grid from the server . I notice that inside of my button click if i do call loader.load it still gives me the old data , How do i refresh the grid .