Page 1 of 3 123 LastLast
Results 1 to 10 of 25

Thread: BeanModel cannot be serializable? What gives?

  1. #1

    Question BeanModel cannot be serializable? What gives?

    Hi,

    I've been looking with close attention to the GWT + GXT framework/tool kit/whatever you call it. It looks powerful, so our company decided to adopt it. So we are looking at how some things are done.

    I have been able to implement some examples, specifically I have been able to build a Grid, based on the Stock.java in GridExample. It works, so the gxt.jar and the inherits part is done correctly. The ext-all.css is also there, since it displays the grid nicely.

    I'm telling you all this because some other thing isn't working, and it can't be due to classpaths and the like, since the Grid works, why shouldn't other things from the gxt.jar work as well?

    So, after this long intro, here is FINALLY my problem: i'm trying to use the Bean Model implementation to, as this post states (http://extjs.com/blog/2008/07/14/preview-java-bean-support-with-ext-gwt/), send a Java Bean over the wire.

    I've tried with implementation #1 (the @BEAN thing plus the interface that extends BeanModelMarker) and with method #2 (implements BeanModelTag), with no luck.

    The original idea was to import a domain class, so I was going to extend from that domain class (which was in a jar), and that inherited class would implement the Serializable and BeanModelTag interfaces, making it possible for GXT to transform it into a BeanModel and send it over the wire.

    The error is this:

    Code:
    Computing all possible rebind results for 'my.package.client.TesteBeanModel'
          Rebinding my.package.client.TesteBeanModel
             Invoking <generate-with class='com.google.gwt.user.rebind.rpc.ServiceInterfaceProxyGenerator'/>
                Generating client proxy for remote service interface 'my.package.client.TesteBeanModel'
                   Analyzing 'my.package.client.TesteBeanModel' for serializable types
                      Analyzing methods:
                         public abstract com.extjs.gxt.ui.client.store.ListStore<com.extjs.gxt.ui.client.data.BeanModel> getAllInvoices()
                            Return type: com.extjs.gxt.ui.client.store.ListStore<com.extjs.gxt.ui.client.data.BeanModel>
                               com.extjs.gxt.ui.client.store.ListStore<com.extjs.gxt.ui.client.data.BeanModel>
                                  [ERROR] Type 'com.extjs.gxt.ui.client.store.ListStore<com.extjs.gxt.ui.client.data.BeanModel>' was not serializable and has no concrete serializable subtypes
    [ERROR] Errors in 'file:/C:/NetBeansProjects/teste-gwt/src/java/my/package/client/TesteEntryPoint.java'
       [ERROR] Line 46:  Failed to resolve 'my.package.client.TesteBeanModel' via deferred binding
    [ERROR] Cannot proceed due to previous errors
    [ERROR] Build failed
    I will post some code now:

    Invoice4GWT.java:

    Code:
    package my.package.server;
    
    import com.extjs.gxt.ui.client.data.BeanModelTag;
    import java.io.Serializable;
    
    public class Invoice4GWT implements BeanModelTag, Serializable{
    
        private int number;
    
        public Invoice4GWT(){
            
        }
        
        public int getNumber() {
            return number;
        }
    
        public void setNumber(int number) {
            this.number = number;
        }
    }
    TesteBeanModelImpl.java:

    Code:
    public class TesteBeanModelImpl extends RemoteServiceServlet implements TesteBeanModel {
        
        public ListStore<BeanModel> getAllInvoices() {
              BeanModelFactory factory = BeanModelLookup.get().getFactory(Invoice4GWT.class);
           
            Invoice4GWT i = new Invoice4GWT();
    
            i.setNumber(34);            
            BeanModel model = factory.createModel(i);
                
            ListStore<BeanModel> ls = new ListStore<BeanModel>();
            ls.add(model);
            return ls;                
        }
    }
    Before I start posting here code and more code, answer me this: why can't the compiler serialize BeanModel?

    Correct me if i'm wrong, but the whole idea behind this is to have a common object that both the client and server know, and that is the object that "travels" over the wire. That common object is a BeanModel, and it's known because it's on the GXT module, which gets compiled to JavaScript.

    On the other hand, we can just simply import a jar with our domain classes and business logic, and "just" extend a class from our domain class, on the SERVER side (therefore not compiling OUR business code to JavaScript), implement two interfaces (BeanModelTag and Serializable) and voil

  2. #2
    Ext GWT Premium Member gslender's Avatar
    Join Date
    Mar 2008
    Location
    Brisbane, Australia
    Posts
    1,572

    Default

    1) it does work - I've got an app working fine, so I'm guessing it must be environmental as your code looks ok

    2) provide the exact details (java version, gwt, gxt etc)

    3) do any of the sample apps work for you (ie the grid bean example) ?

    cheers,
    grant

  3. #3

    Default

    Thanks for the fast reply!

    My java version is 1.6.0_10 (as stated by the java -version command).

    The GWT version is 1.5.3

    The GXT version is 1.1.1

    My partner tried to compile the GridExample and he gets the same error, but this time it's on BeanModelLookup and not on BeanModel. Somehow the project doesn't recognize it, although the gxt.jar is in the project.

    We are using NetBeans 6.0 (he is using 6.1). We have the GWT4NB plugin, so we create a new Web Project, using GWT Framework, and it does almost all the work for us.

    We can also create a new GWT RPC Service, and it automatically creates the Service.java and ServiceAsync.java and ServiceImpl.java, places a button and an input box and it can send a string to the server and send another string from the server to the client, so rpc is working fine. I even sent an id, used that id to fetch a record from my DB using hibernate, and sent over the name field of the record with that id. It's working fine.

    The next step is instead of sending id's back and forth, one at a time, and getting rows one at a time, i want to get a ListStore of them, so i can populate a Grid.

    About my environment: i have created a library entry in NEtbeans called GXT and added the gxt.jar to it. Then added the GXT library to the project. Since in that same project I am able to instanciate a Grid and populate it (locally, with several add() method calls), and the grid shows nicely and filled in, i believe gxt is being well imported.

    I have also the GWT_HOME system variable defined, and added to my PATH.
    This is also in the project definition of NEtBeans, since he asks for it. It's compiling via the build, so he knows where GWT is.

    Do I need to place a GXT_HOME as well?

    We are at our wits end here...

  4. #4
    Ext GWT Premium Member gslender's Avatar
    Join Date
    Mar 2008
    Location
    Brisbane, Australia
    Posts
    1,572

    Default

    just noticed that Invoice4GWT is in the my.package.server package - is it being imported by GWT in your module file?

    it needs to be in the GWT source path, so either under .client or add this to your gwt.xml module file...
    Code:
      	<source path="server"/>
      	<source path="client"/>

  5. #5

    Default

    What tha...?

    Invoice has to be in .client? Or in the source path?

    But if that is so, then it will compile my Invoice4GWT to javascript!

    I thougth that the client didn't have to know about my domain classes! Therefore the BeanModel approach, where i could type beanmodel.get("myfield") !!

    What is the use of making Invoice4GWT inv = (Invoice4GWT)model.getBean(); ?

    If so, if the client KNOWS about my Invoice4GWT, why should I transform it into a BeanModel for? And the first objective of this is that I have my domain classes ONLY in the server, with my business logic wrapped in a .jar, where other partners do that programming part and provide me with just a jar so that I can do the view part. I only needed to make a new class called Invoice4GWT, that would EXTENDS myBusinessLogic.Invoice and implements BeanModelTag, Serializable.

    But I will try your approach and tell in a minute what just happend.

    Be back shortly.

  6. #6

    Default

    Ok, just added the

    <source path="server"/>
    <source path="client"/>

    to the gwt.xml file.

    Same error persists, but now we have MORE!!!

    Code:
    [ERROR] Line 21: No source code is available for type com.google.gwt.user.server.rpc.RemoteServiceServlet; did you forget to inherit a required module?
                   [ERROR] Line 25: No source code is available for type simple.Invoice; did you forget to inherit a required module?
                   [ERROR] Line 29: No source code is available for type my.package.framework.persistance.PersistanceException; did you forget to inherit a required module?
    The first error i dont get, because my gwt.xml looks like this:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <module>
        <inherits name="com.google.gwt.user.User"/>
            <inherits name="com.extjs.gxt.ui.GXT"/> 
            <source path="server"/>
            <source path="client"/>        
        <entry-point class="my.package.client.TesteEntryPoint"/>
        <!-- Do not define servlets here, use web.xml -->
    </module>
    So he should know what com.google.gwt.user.server.rpc.RemoteServiceServlet is. How come he suddenly doesnt know what RemoteServiceServlet is?

    The other errors are obvious: This is because in that same project, remember I told you i was using RPC fine, sending a string to the server, using that string to instantiate an Invoice (which was only known in the server, because of my imported jar), and that Invoice used Hibernate (therefore the PersistanceException, which is thrown by a proxy we developed so that we dont use Hibernate directly but our own framework).

    Now GWT wants to know what the hell Invoice and PersistanceException are! Because i told him to also compile my server side.

    He doesnt need to know what these classes are. We only needs to know what BeanModel is, because a Grid component on the client side is capable of being instantiated with a new Grid(myListStore<BeanModel>, myColumnModel) and it populates the grid, provided my columns have the same ids my beanmodel has.

    Or DOES he need to know?

    So maybe before trying this or that to make the code compile, i would like to know how exactly the BeanModel thing works. So correct my if i'm wrong:

    You take a class on the server side which you DONT WANT to compile to javascript, transform it into a BeanModel and send it over the wire.

    On the client side, you get a BeanModel (or a List of BeanModels...).

    Since BeanModel is in the gxt.jar, which is a GWT-complient module and inherited in the gwt.xml, the GWT compiler knows what a BeanModel is and can compile it.

    So I can access that BeanModel in the client part and perform get's and set's, providing the attribute names [model.set("name", "xpto");].

    Then i can send back the beanmodel over the wire again, and the server side then casts it back to MY CLASS (with the (MyClass)model.getBean() method) and perform the operations i need.

    I dont want to perform server side operations on the client side. The client side, in my opinion, is for view only. All the business logic should happen on the server side. Therefore why should I make my Invoice class (or Invoice4GWT class) known to the client side for?

  7. #7
    Ext GWT Premium Member gslender's Avatar
    Join Date
    Mar 2008
    Location
    Brisbane, Australia
    Posts
    1,572

    Default

    3rd para in http://extjs.com/blog/2008/07/14/pre...-with-ext-gwt/ says...
    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.
    Whatever you send must be understood fully by GWT and that means including the source package, otherwise your server has to build objects within .client and send them.

    There is no way at all for GWT to deserialize an object is doesn't know about - just not possible. This is not a ExtGWT issue, but a solution to a GWT problem.

  8. #8
    Ext GWT Premium Member gslender's Avatar
    Join Date
    Mar 2008
    Location
    Brisbane, Australia
    Posts
    1,572

    Default

    Quote Originally Posted by Branco View Post
    So correct my if i'm wrong:

    You take a class on the server side which you DONT WANT to compile to javascript, transform it into a BeanModel and send it over the wire.

    On the client side, you get a BeanModel (or a List of BeanModels...).

    Since BeanModel is in the gxt.jar, which is a GWT-complient module and inherited in the gwt.xml, the GWT compiler knows what a BeanModel is and can compile it.

    So I can access that BeanModel in the client part and perform get's and set's, providing the attribute names [model.set("name", "xpto");].

    Then i can send back the beanmodel over the wire again, and the server side then casts it back to MY CLASS (with the (MyClass)model.getBean() method) and perform the operations i need.
    btw - you're wrong. before beanmodel you had to transfer via RPC an object that extended BaseModelData and this was yukky - lots of transferring between beans/pojos and a DTO that extended BaseModelData.

    with beanmodel, you now can simply mark a bean and the send it - easier/simpler

    cheers,
    grant

  9. #9
    Ext GWT Premium Member gslender's Avatar
    Join Date
    Mar 2008
    Location
    Brisbane, Australia
    Posts
    1,572

    Default

    bbtw...

    I'm not sure if
    Code:
    <source path="server"/>
    <source path="client"/>
    is the right solution for you - who knows what other classes exist in .server

    so create a new package, .model and drop in your classes you want to pass between client and server

    Code:
    <source path="model"/>
    <source path="client"/>

  10. #10

    Default

    Ok, i was wrong.

    But!

    Imagine I place my source code in the client like you said. That way the GWT client side knows how to compile it.

    But if my class uses, for example, Hibernate, that is, wants to make a new sessionFactory() and the like, then GWT will want to know what that sessionFactory is, that means sessionFactory must implement also the BeanModelTag interface? Must I provide also the source code in the Hibernate.jar so that GWT can compile it?

    And for that matter, all those other jars: log4j, commons-utils, etc... must have their source codes available for GWT to compile, since each and every time my classes instantiate such an object, GWT will complain that he cant serialize it or that the source code is missing!

    How will I be able to use 3rd party jars with GWT? My applications work fine with those jars. I just want to use GWT for the VIEW part. To create the forms and grids and such. Must I rewrite all my code, so that all my classes are now implementing BeanModelTag and Serializable?

    I could do that, but how on earth will I be able to do it to the 3rd party jar's provided by lots of companies?

Page 1 of 3 123 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •