Announcement

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

    js exception when calling valuesHaveChanged()

    I'm getting the following exception when calling valuesHaveChanged() on a DynamicForm. Not sure what else to look for. Any advice would be appreciated.
    Code:
    com.google.gwt.core.client.JavaScriptException: (null): null
    	at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:248)
    	at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)
    	at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:561)
    	at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:269)
    	at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
    	at com.smartgwt.client.widgets.form.DynamicForm.valuesHaveChanged(DynamicForm.java)
    	at com.islandpacific.gui.client.purchasing.productionorder.ProductionOrderEditor$9.onTabDeselected(ProductionOrderEditor.java:259)
    	at com.smartgwt.client.widgets.tab.events.TabDeselectedEvent.dispatch(TabDeselectedEvent.java:97)
    	at com.smartgwt.client.widgets.tab.events.TabDeselectedEvent.dispatch(TabDeselectedEvent.java:1)
    	at com.google.gwt.event.shared.GwtEvent.dispatch(GwtEvent.java:1)
    	at com.google.web.bindery.event.shared.EventBus.dispatchEvent(EventBus.java:40)
    	at com.google.web.bindery.event.shared.SimpleEventBus.doFire(SimpleEventBus.java:193)
    	at com.google.web.bindery.event.shared.SimpleEventBus.fireEvent(SimpleEventBus.java:88)
    	at com.google.gwt.event.shared.HandlerManager.fireEvent(HandlerManager.java:127)
    	at com.smartgwt.client.core.DataClass.fireEvent(DataClass.java:248)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
    	at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
    	at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
    	at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:337)
    	at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:218)
    	at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)
    	at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:561)
    	at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:269)
    	at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
    	at com.google.gwt.core.client.impl.Impl.apply(Impl.java)
    	at com.google.gwt.core.client.impl.Impl.entry0(Impl.java:213)
    	at sun.reflect.GeneratedMethodAccessor154.invoke(Unknown Source)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
    	at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
    	at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
    	at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:292)
    	at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:546)
    	at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363)
    	at java.lang.Thread.run(Thread.java:680)
    The form is in a stack with other forms. I'm iterating over the Canvases in the stack and casting them back to DynamicForm to do the check. Here is the code that is getting the error.
    Code:
    // If there are changes to any of the pricing forms, save them.
    Canvas[] pricingFormStackMembers = itemTab.getPricingFormStack().getMembers();
    for (Canvas pricingFormStackMember : pricingFormStackMembers) {
    	final DynamicForm pricingForm = (DynamicForm) pricingFormStackMember;
    	if (pricingForm.valuesHaveChanged()) {
    		aSaveWasRequested = true;
    		pricingForm.saveData(new DSCallback() {
    			
    			@Override
    			public void execute(DSResponse response, Object rawData, DSRequest request) {
    				if (response.getStatus()==DSResponse.STATUS_SUCCESS)
    					pricingForm.editRecord(response.getData()[0]);
    			}
    		});
    	}
    }
    Last edited by jay.l.fisher; 29 May 2012, 18:50.

    #2
    Nevermind. I was calling form.editRecord(record) when I should have been calling form.editNewRecord(record.toMap()).

    Comment


      #3
      I'm getting the same error but I'm using fetchData instead of editRecord (or editNewRecord). I'm not really sure what to look for either. We're using SmartGWT 2.5p on Firefox.

      Another thing I noticed though is on our test/production environment, instead of the null JS exception, we get another one about too much recursion...

      ISC_Forms.js:796
      (Internal Error): too much recursion
      stack: isc_Array_findNextIndex(0, "name", "path/to/attribute/__ref/l/__ref/l/__ref/l/__ref/l/__ref/l/__ref/l/__ref/l/__ref/l/__ref/l/__ref/l/__ref/l/__ref/l/__ref/l/__ref/l/__ref/l/__ref/l/__ref/l/__ref/l <...goes more...>")

      Any ideas? (Sorry, I can't bring the code out)

      Thanks in advance!

      Comment


        #4
        __ref is a property that gets hung onto the SmartGWT JavaScript objects, and refers to the equivalent Java data structures (which of course are themselves automatically generated JavaScript objects with some custom behavior in compiled mode).

        This kind of error would result in cases where JavaScript code naively attempts to drill into the __ref property on some Java-backed JavaScript object and hits a circular reference (or possibly a massive object such as the entire DOM or the entire GWT and SmartGWT framework, etc).

        In general the SmartGWT framework javascript code is careful about not doing this, but you could possibly hit this through custom JavaScript or JSNI within your app, or through some edge case usage of an API that we hadn't anticipated perhaps.

        To get to the bottom of how you're hitting this we would need to figure out what code path is actually leading to the error.
        At risk of sounding like a broken record - test code is always the best way to proceed on this kind of thing. If we have a test case we can run we know for sure we're seeing what you're seeing, and the process of creating the test case often pinpoints the cause of the problem before we even see it.

        However one thing we can suggest before you start putting together a test case is to look at the top of the reported stack trace. Presumably the "too much recursion" indicates you'll see the same few functions iterated over and over and over at the stack, but if you scroll all the way down there should be an indication of what codepath actually led to this state, which may clear things up.
        Also a clear description of what you're doing along with some relevant code snippets may allow us to theorize as to what could be going wrong.

        Thanks
        Isomorphic Software

        Comment


          #5
          Thanks for your help. Here is some more info if it helps: I'm calling ValuesManager.valuesHaveChanged(). The ValuesManager gets its values from a fetchData and is backed by a custom DMI that calls a webservice. The data source has nested objects, which are all defined by ds.xml files.

          As mentioned, this only happens in the test environment but during develpment, I instead get a "JavaScriptException: (null): null" when calling valuesHaveChanged.

          I'll look at the stack trace and report back if I see anything.

          Thanks again!

          Comment


            #6
            Here is the stack trace for the too much recursion in our test env (please excuse any typos because I had to handwrite it then type it here)...

            Code:
            (Internal Error): too much recursion
            stack:isc_Arra_findNextIndex(0, "name", "path/to/attr/__ref/l/<cont'd>")@ISC_Forms.js:583
            isc_Arra_findIndex("name", "path/to/attr/__ref/l/<cont'd>")@ISC_Core.js:582
            isc_Array_find("name", "path/to/attr/__ref/l/<cont'd>")@ISC_Core.js:590
            isc_c_Class_getArrayItem("path/to/attr/__ref/l/<cont'd>")@ISC_Core:349
            isc_DynamicForm_getItem("path/to/attr/__ref/l/<cont'd>")@ISC_Forms:393
            isc_DynamicForm_getField("path/to/attr/__ref/l/<cont'd>")@ISC_Forms:395
            isc_ValuesManager__findMemberByField("path/to/attr/__ref/l/<cont'd>")@ISC_Forms:3032
            isc_ValuesManager_getItem("path/to/attr/__ref/l/<cont'd>")@ISC_Forms:3023
            
            isc_c_DynamicForm_valuesHaveChanged([object Object], (void 0), [object Object], [object Object], "path/to/attr/__ref/l/<cont'd>")@ISC_Forms.js:796
            <^78 times>
            
            isc_c_DynamicForm_valuesHaveChanged([object Object], (void 0), [object Object], [object Object])@ISC_Core.js:583

            Comment


              #7
              Hi again
              This gives us a good indication of where things are going wrong but doesn't really explain how. There is code in place in the method in question (valuesHaveChanged) that should explicitly skip __ref's and prevent this bug from occurring.

              Firstly - you mentioned you're seeing this issue against SmartGWT 2.5. We have done some significant work around nested data objects in the 3.0p and 3.1d streams since 2.5 (adding new features but also some clean up of existing issues etc). It is possible that this is something that no longer applies in the latest codebase.
              While upgrading your app for deployment may not be an option for you at this time we'd be interested to know if you you can reproduce the problem using the 3.0p or 3.1d libraries in testing so we can have an idea of whether we're looking at something specific to that build.

              Secondly - if this is still an issue with the latest build - while you may not be able to build us a standalone test case at this time, it might help to have a clearer picture of the objects involved.

              Could you show us some code (or pseudo-code) that gives an indication of
              - What the valuesManager definition looks like
              - What the member forms within the values manager looks like
              - what the relevant dataSources (client side code only) look like
              - how the data objects are structured.
              And the code that actually calls "valuesHaveChanged()".

              With a bit of luck this might give us the insight we need to see why our guard against this happening isn't helping in your usage.

              Thanks
              Isomorphic Software

              Comment


                #8
                Thanks for the advice. I'll look into those areas.

                In the meantime, do you have insight into how to debug the "JavaScriptException: (null): null" when calling valuesHaveChanged in dev mode?

                I don't have a clue how to debug it as there's not much info in the stack trace other than showing our code calling valuesHaveChanged. Is it safe to say that it's the same issue we're seeing on the test environment? It occurs at the same spot in our test case.

                Thanks!

                Comment


                  #9
                  This is almost certainly the same issue, yes. I don't think there's any need to separately debug this.

                  Comment


                    #10
                    rahulptiple, I think you hijacked my thread :P

                    Isomorphic, I think I was able to track down the problem by printing up the contents of ValuesManager.getValues() after every operation I did. It's kind of complicated...

                    In the values manager fetch callback, I retrieved the parent Record of the attribute in question. Then I manually merge (by recursively copying values) it with another Record. I'm not sure how, but a __ref to a Record gets added to one of the nested objects when I do this.

                    Code:
                    Record parent = dsResponse.getData()[0].getAttributeAsRecord("parent");
                    merge(parent, anotherRecord); // merge(dst, src)
                    valuesManager.setValue("parent", parent);
                    Afterward, when I call valuesHaveChanged, it gives an exception.

                    I fixed it by making a copy of the parent Record...
                    Code:
                    Record parent = new Record(dsResponse.getData()[0].getAttributeAsRecord("parent").toMap());
                    merge(parent, anotherRecord); // merge(dst, src)
                    valuesManager.setValue("parent", parent);

                    Comment


                      #11
                      Glad you found a way around this. It's not clear from your description whether there was a particular way to avoid this in the framework as it seems the merge function essentially created an object with a format our framework code wasn't expecting.
                      We'll leave this one be for now - if the problem resurfaces, we'll probably need to see a reproducible case to pursue it further.

                      Thanks
                      Isomorphic Software

                      PS Rahuptiple - we're moving your post to a new thread.

                      Comment

                      Working...
                      X