Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Error when creating TreeNode with List<SerializableObject>

    Hi,
    I am using SmartClient Version: v8.3p_2013-05-14/PowerEdition Deployment (built 2013-05-14) with IE8 and SmartGWT Power Edition 3.1p.
    One year ago (while using another version of SmartGWT) we implemented a tree view, after a while we changed to 3.1p version and now we noticed that the tree view does not work anymore. The error message is:

    "Can not convert element 0 of the array to a JavaScriptObject. Instances of class '..client.datamodel.ActionLinks' can not automatically be converted. Please see the SmartClient documentation of RPCRequest.data for a table of Java types that can be converted automatically."

    The class to initialize is the following (a TreeNode class), see constructor:

    private class ActionsTreeNode extends TreeNode {
    public ActionsTreeNode(final String actionId, final String actionType,
    final String actionLogsLink, final String rootAction,
    final String mainLog, final List<ActionLinks> attachments, final boolean isOpen) {
    setAttribute("actionId", actionId);
    setAttribute("actionType", actionType);
    setAttribute("actionLogsLink", actionLogsLink);
    setAttribute("rootAction", rootAction);
    setAttribute("mainLog", mainLog);
    setAttribute("attachments", attachments);
    setAttribute("isOpen", isOpen);
    }
    }

    Class ActionLinks (see "List<ActionLinks>") is serializable.
    The initialization is done as follows:

    try {
    actionsData.add(new ActionsTreeNode
    (action.getActionId(), action.getActionType(),
    link, action.getRootAction(),
    action.getMainLog(), action.getAttachments(), true));
    } catch (Exception e) {
    SC.say(e.getMessage());
    }

    Please could you shed some light on this, as it used to work fine before we moved to the above mentioned version of SmartGWT ?

    Many thanks in advance

    PS: please move this to Technical Q&A, if possible
    Many thanks
    Last edited by trainot; 18 Jul 2013, 04:07.

    #2
    Sounds like possibly a long-since fixed issue. Please try a more recent patched build instead.

    Comment


      #3
      Hi,

      We have installed the libraries located in :
      http://www.smartclient.com/builds/SmartGWT/3.1p/PowerEdition/2013-07-17/smartgwtpower-3.1p.zip

      http://www.smartclient.com/builds/SmartClient/8.3p/PowerEdition/2013-07-18/SmartClient_v83p_2013-07-18_PowerEdition.zip

      which contain the last patch for SmartGWT 3.1 and SmartClient 8.3.
      We have replaced the older libraries with the newer ones and recompiled the classes with the new libraries. Unfortunately we encounter the same problem (the same error message).
      We checked our CVS to see if the code has changed since last year, but there were no changes.
      Please could you investigate this with priority ?
      Should you need more information on the code, please let me know.

      Many thanks in advance

      Comment


        #4
        Quite possibly you simply missed a step in installation - please follow the complete documented installation steps and not just the .jar replacement approach you took. You can also use the instructions in the FAQ to verify that you are really running the new version.

        If you do this and you're still seeing an issue, what we need is a ready-to-run, minimal test case showing how this issue can be reproduced.

        Comment


          #5
          Originally posted by trainot View Post
          Hi,
          I am using SmartClient Version: v8.3p_2013-05-14/PowerEdition Deployment (built 2013-05-14) with IE8 and SmartGWT Power Edition 3.1p.
          One year ago (while using another version of SmartGWT) we implemented a tree view, after a while we changed to 3.1p version and now we noticed that the tree view does not work anymore. The error message is:

          "Can not convert element 0 of the array to a JavaScriptObject. Instances of class '..client.datamodel.ActionLinks' can not automatically be converted. Please see the SmartClient documentation of RPCRequest.data for a table of Java types that can be converted automatically."

          The class to initialize is the following (a TreeNode class), see constructor:

          private class ActionsTreeNode extends TreeNode {
          public ActionsTreeNode(final String actionId, final String actionType,
          final String actionLogsLink, final String rootAction,
          final String mainLog, final List<ActionLinks> attachments, final boolean isOpen) {
          setAttribute("actionId", actionId);
          setAttribute("actionType", actionType);
          setAttribute("actionLogsLink", actionLogsLink);
          setAttribute("rootAction", rootAction);
          setAttribute("mainLog", mainLog);
          setAttribute("attachments", attachments);
          setAttribute("isOpen", isOpen);
          }
          }

          Class ActionLinks (see "List<ActionLinks>") is serializable.
          The initialization is done as follows:

          try {
          actionsData.add(new ActionsTreeNode
          (action.getActionId(), action.getActionType(),
          link, action.getRootAction(),
          action.getMainLog(), action.getAttachments(), true));
          } catch (Exception e) {
          SC.say(e.getMessage());
          }

          Please could you shed some [color=black]led light[/color] on this, as it used to work fine before we moved to the above mentioned version of SmartGWT ?

          Many thanks in advance

          PS: please move this to Technical Q&A, if possible
          Many thanks
          Were you able to sort out the problem? I am facing the issue for a while but not able to find the answer.. hope you can help me out..
          Last edited by IrvingBowman; 21 Jul 2013, 22:18.

          Comment


            #6
            Hi again,

            Thanks for your answer, we have checked the installation very carefully. This problem does not seem related to the installation. Just as background information, the SmartGWT jar files are imported in our project like normal jar files and work very well as such, apart from the above mentioned problem. But anyway we have tested the version and the result is we use SmartGWT 3.1p, build date Wed Jul 17 09:45:00 GMT+200 2013, as expected.

            We have taken the time to create a small example for you to test, which does not work in our version and returns the error message mentioned before.

            Thank you for looking into this.

            Code:
            /**
             * @author trainot
             * 
             * Main class for Admin Actions (Entry Point)
             * 
             * 
             */
            package gwtree.client;
            
            import gwtree.client.datamodel.ActionLinks;
            
            import java.util.ArrayList;
            import java.util.List;
            
            import com.google.gwt.core.client.EntryPoint;
            import com.smartgwt.client.Version;
            import com.smartgwt.client.core.KeyIdentifier;
            import com.smartgwt.client.types.TreeModelType;
            import com.smartgwt.client.util.KeyCallback;
            import com.smartgwt.client.util.Page;
            import com.smartgwt.client.util.SC;
            import com.smartgwt.client.widgets.grid.CellFormatter;
            import com.smartgwt.client.widgets.grid.ListGridRecord;
            import com.smartgwt.client.widgets.tree.Tree;
            import com.smartgwt.client.widgets.tree.TreeGrid;
            import com.smartgwt.client.widgets.tree.TreeGridField;
            import com.smartgwt.client.widgets.tree.TreeNode;
            
            
            public class TreeGWT implements EntryPoint {
            
                /******************************* PRIVATE MEMBERS **********************************/
            
                /* data obtained via JSNI call */
                /* data coming from the backend */
                private List<TreeNode> actionsData = new ArrayList<TreeNode>();
            
                /* Remote Procedure Call interface */
                private DesignElements designElementsInstance;
            
                
                /******************************* GETTERS **********************************/
            
                /******************************** CONSTRUCTOR ********************************/
                public TreeGWT() {
                   
                } // end public class constructor
            
                /******************************* ENTRY POINT **********************************/
                public final void onModuleLoad() {
                    /* set CTRL-D as shortcut key for Developer Console */
                    setShortcutForDeveloperConsole();
                    //SC.say(Version.getBuildDate().toString());
                    designElementsInstance = new DesignElements();
                    fillTreeWithData();
                    
            
                } // end function onModuleLoad
            
                /******************************* RPC HANDLERS *********************************/
            
                /************************** PRIVATE MEMBER FUNCTIONS ***************************/
            
                private void setShortcutForDeveloperConsole() {
                    KeyIdentifier debugKey = new KeyIdentifier();
                    debugKey.setCtrlKey(true);
                    debugKey.setKeyName("Q");
            
                    Page.registerKey(debugKey, new KeyCallback() {
                        public final void execute(final String keyName) {
                            SC.showConsole();
                        }
                    });
                } // end function setShortcutForDeveloperConsole
            
            
                public void fillTreeWithData() {
                    List<ActionLinks> attachments = new ArrayList<ActionLinks>();
                    ActionLinks obj1 = new ActionLinks("link1", "linkName1", "11111");
                    ActionLinks obj2 = new ActionLinks("link2", "linkName2", "22222");
                    attachments.add(obj1);
                    attachments.add(obj2);
                    try {
                        actionsData.add(new ActionsTreeNode("1", "2", "Test", "3", "Log",
                                attachments, true));
                    } catch (Exception e) {
                        SC.say(e.getMessage());
                    }
            
                    designElementsInstance.getActionsTree().setData(
                            actionsData.toArray(new TreeNode[]{}));
                    designElementsInstance.getActionsTreeGrid().setData(
                            designElementsInstance.getActionsTree());
                    designElementsInstance.getActionsTreeGrid().redraw();
            
                }
            
                /************************** INNER CLASSES ***************************/
                /**
                 * Class containing the tree data Definition depends on the business object
                 * defined in datamodel.ActionsInfoBO
                 * 
                 * @author trainot
                 * 
                 */
                private class ActionsTreeNode extends TreeNode {
                    public ActionsTreeNode(final String actionId, final String actionType,
                            final String actionLogsLink, final String rootAction,
                            final String mainLog, final List<ActionLinks> attachments,
                            final boolean isOpen) {
                        setAttribute("actionId", actionId);
                        setAttribute("actionType", actionType);
                        setAttribute("actionLogsLink", actionLogsLink);
                        setAttribute("rootAction", rootAction);
                        setAttribute("mainLog", mainLog);
                        setAttribute("attachments", attachments);
                        setAttribute("isOpen", isOpen);
                    }
                }
            
                private class DesignElements {
            
             
                    private Tree actionsTree;
                    private TreeGrid actionsTreeGrid;
            
                    public Tree getActionsTree() {
                        return actionsTree;
                    }
            
                    public TreeGrid getActionsTreeGrid() {
                        return actionsTreeGrid;
                    }
                    /**
                     * Inner class definition for the design. The coupling between the
                     * parent class and the inner class (DesignElements) is relative high
                     * 
                     */
                    public DesignElements() {
            
                        actionsTree = new Tree();
            
                        actionsTree.setNameProperty("actionType");
                        actionsTree.setIdField("actionId");
                        actionsTree.setParentIdField("rootAction");
                        actionsTree.setOpenProperty("isOpen");
            
                        actionsTree.setModelType(TreeModelType.PARENT);
            
                        TreeGridField typeField = new TreeGridField("actionType");
                        typeField.setTitle("Action");
            
                        TreeGridField attachmentsField = new TreeGridField("attachments");
                        attachmentsField.setTitle("Attachments");
            
                        TreeGridField mainLogField = new TreeGridField("mainLog");
                        mainLogField.setTitle("Main Log");
            
                        mainLogField.setCellFormatter(new CellFormatter() {
                            @Override
                            public String format(final Object value,
                                    final ListGridRecord record, final int rowNum,
                                    final int colNum) {
                                return
            
                                "<a href = " + "returnMainLog.do?mainLogFile="
                                        + value.toString()
                                        + "&htmlparse='yes' target='_blank'>" + "HTML"
                                        + "</a>" +
            
                                        "&nbsp;&nbsp;&nbsp;<a href = "
                                        + "returnMainLog.do?mainLogFile="
                                        + value.toString() + ">" + "Main" + "</a>";
            
                            }
                        });
            
                        typeField.setCellFormatter(new CellFormatter() {
                            @Override
                            public String format(final Object value,
                                    final ListGridRecord record, final int rowNum,
                                    final int colNum) {
            
                                return record.getAttribute("actionLogsLink");
                            }
                        });
            
                        attachmentsField.setCellFormatter(new CellFormatter() {
                            @Override
                            public String format(final Object value,
                                    final ListGridRecord record, final int rowNum,
                                    final int colNum) {
            
                                @SuppressWarnings("unchecked")
                                List<ActionLinks> attachments = (List<ActionLinks>) record
                                        .getAttributeAsObject("attachments");
                                StringBuffer returnValue = new StringBuffer("");
                                for (ActionLinks attBO : attachments) {
                                    if (attBO.getHasHtmlLink()) {
                                        returnValue.append("<a href = "
                                                + "returnLog.do?processInfoId="
                                                + attBO.getProcessInfoId()
                                                + "&htmlparse='yes'" + "  target='_blank'>"
                                                + "HTML" + "</a>");
                                    }
            
                                    returnValue
                                            .append("&nbsp;&nbsp;&nbsp;<a href = returnLog.do?processInfoId="
                                                    + attBO.getProcessInfoId()
                                                    + ">"
                                                    + attBO.getLinkName() + "</a>");
            
                                    returnValue.append("<br>");
                                }
                                return returnValue.toString();
                            }
                        });
            
                        actionsTreeGrid = new TreeGrid() {
                            protected String getCellCSSText(final ListGridRecord record,
                                    final int rowNum, final int colNum) {
                                return "vertical-align:top;";
                            }
                        };
            
                        actionsTreeGrid
                                .setFields(typeField, mainLogField, attachmentsField);
                        actionsTreeGrid.setWidth100();
                        actionsTreeGrid.setHeight100();
                        actionsTreeGrid.show();
                    }
                } // end sub-class DesignElements
            }
            
            <?xml version="1.0" encoding="UTF-8"?>
            <module rename-to='treegwt'>
            
            	<!-- Inherit the core Web Toolkit stuff.                        -->
            	<inherits name='com.google.gwt.user.User' />
            
            	<!-- Other module inherits                                      -->
            	<inherits name="com.smartgwt.SmartGwtNoScript" />
            	<inherits name="com.smartgwt.SmartGwtNoTheme" />
            <!--
              <inherits name="com.smartclient.theme.graphite.Graphite"/> 
              <inherits name="com.smartclient.theme.graphite.GraphiteResources"/>
             
              <inherits name="com.smartclient.theme.simplicity.Simplicity"/> 
              <inherits name="com.smartclient.theme.simplicity.SimplicityResources"/>
              
              <inherits name="com.smartclient.theme.enterprisegray.EnterpriseGray" />
              <inherits name="com.smartclient.theme.enterprisegray.EnterpriseGrayResources" />
            -->
               <inherits name="com.smartclient.theme.enterprise.Enterprise" />
              <inherits name="com.smartclient.theme.enterprise.EnterpriseResources" />
                
                
            	<!-- for debugging with CTRL-D -->
            	<inherits name="com.smartgwt.tools.SmartGwtTools"></inherits>
            
               
            	<!-- Specify the app entry point class.                         -->
            	<entry-point class='gwtree.client.TreeGWT' />
            
            	<!-- Specify the paths for translatable code                    -->
            	<source path='client' />
            	<source path='shared' />
            	
            	<!--
            		servlet context - path is arbritray, but must match up with the rpc
            		init inside java class
            	
            	   <set-property name="user.agent" value="gecko1_8"/>  
            	
            		Tomcat will listen for this from the server and waits for rpc request
            		in this context
            	-->
            	<extend-configuration-property name="rpc.blacklist"
                    value="com.google.gwt.user.client.ui.*Collection" />
            </module>
            
            package gwtree.client.datamodel;
            
            import java.io.Serializable;
            
            public class ActionLinks implements Serializable {
                /**
                 * 
                 */
                private static final long serialVersionUID = 6929885226260327974L;
                private String value;
                private String linkName;
                private Boolean hasHtmlLink;
                private String processInfoId;
             
                
                public ActionLinks(final String value, final String linkName, final String processInfoId) {
                   
                    this.value = value;
                    this.linkName = linkName;
                    this.processInfoId = processInfoId;
                    
                    this.hasHtmlLink = this.value.endsWith(".html") ||
                    this.value.endsWith(".htm") ||
                        this.value.endsWith(".log")
                            || this.value.endsWith(".txt")
                            || this.value.endsWith(".ges")
                            || ((this.value.endsWith(".gz")) && (this.linkName
                                    .endsWith("GESMES")));
                }
            
                public ActionLinks() {
                    
                }
               
                public final String getValue() {
                    return value;
                }
            
                public final String getLinkName() {
                    return linkName;
                }
            
                public final void setValue(final String value) {
                    this.value = value;
                }
            
                public final void setLinkName(final String linkName) {
                    this.linkName = linkName;
                }
            
                public final Boolean getHasHtmlLink() {
                    return hasHtmlLink;
                }
            
                public final String getProcessInfoId() {
                    return processInfoId;
                }
            
                public final void setProcessInfoId(final String processInfoId) {
                    this.processInfoId = processInfoId;
                }
                
            }
            Last edited by trainot; 22 Jul 2013, 04:50.

            Comment


              #7
              Just a quick follow up to say this is currently under investigation. We will follow up with a proper response when we have more information.

              Comment


                #8
                many thanks indeed for having a look at this, much appreciated !

                Comment


                  #9
                  We've done some analysis here and what you've hit is essentially an expansion of an existing feature which happened to break a behavior your code relied upon.
                  Generally, the intended usage for setAttribute() is to populate a data object with values that would ultimately be valid values for a DataBoundComponent. In other words you're setting up record values that will potentially be read or displayed by SmartGWT components.
                  As such we automatically perform some conversions from Java data types to JavaScript data types.
                  This includes simple transformations (converting numeric Java data types to JavaScript Numbers, Java Date to JavaScript Date, etc), as well as more complex stuff (recursively converting Maps to JavaScript objects, and Java Arrays to JavaScript arrays).
                  Since the 8.3 release, this support has been expanded somewhat to handle converting Java Collections to JavaScript Arrays as well.

                  In this specific instance, you're calling "setAttribute" and passing in a Java List of POJOs.
                  The 8.3 release behavior would not have attempted to convert these to JavaScript at all -- the new behavior does (and ultimately fails with the warning you're seeing).

                  Your code was of course relying on the old behavior, as your intention was to store out the Java object unmodified and access it directly from your java code.

                  We recognize this is a valid use case, so we are making a change to add support for this via a new explicit API (most likely named "setAttributeAsJavaObject()").

                  We will also be modifying the "setAttribute()" method to behave more gracefully when passed something it is unable to convert.

                  We'll let you know when these changes are available

                  Regards
                  Isomorphic Software

                  Comment


                    #10
                    Many thanks Isomorphic for this detailed explanation, which makes a lot of sense. We will wait for you to let us know when the API will be available.

                    Best regards

                    Comment


                      #11
                      We've now added this API (DataClass.setAttributeAsJavaObject()) to the 4.0p, 3.1p and 4.1d branches.
                      We've also added some JavaDoc (in the 4.x branches) to clarify how setAttribute() behaves and pre-empt this kind of confusion in the future.

                      Please try the next nightly build to pick up these changes

                      Regards
                      Isomorphic Software

                      Comment


                        #12
                        Dear Isomorphic, I have installed today the latest build from 30.07. I could not find the new function in DataClass. Please could you double check if this fix has been deployed in branch 3.1p ?

                        Many thanks in advance

                        Comment


                          #13
                          This does appear to be present in the latest 3.1p build (Dated August 1).
                          http://www.smartclient.com/builds/SmartGWT/3.1p/
                          If you're still not seeing it there, you may be looking at stale jar's or javadoc somehow? Try refreshing the Eclipse project after updating your jars, and possibly clearing cache / running a gwt compile step?

                          Regards
                          Isomorphic Software

                          Comment


                            #14
                            Thank you Isomorphic.
                            I took the last nightly build. The new API is there and working as expected, very much appreciated indeed.

                            Best Regards

                            Comment

                            Working...
                            X