Announcement

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

    JSONEncoder

    Hi Folks,

    (SmartGWT - 2.5).

    I am trying out a piece of code which where i need to serialize a Hashmap content to JSON and send it across to a server.

    I tried using the following snippet,
    Code:
    JSONEncoder j = new JSONEncoder();
    String jsonData = j.encode(mapData);
    but it seems to fail with,

    java.lang.reflect.InvocationTargetException
    com.google.gwt.core.client.JavaScriptException: (String): 4.43846607925724E-304

    Any idea why this could be failing and is there any other way in SmartGWT to achieve this (object to JSON conversion). I have used 3rd party libraries for this in the past, but if its available within SmartGWT itself, that would be ideal.

    Thanks,
    Vikram

    #2
    There's something funny in the Map (possibly in a nested substructure). Are you able to re-create this problem with code we can run to see the problem?

    Comment


      #3
      Its a simple map which will largely have String keys and String/String[] values. But the API failed even with a simple String key/value pair, you can try the below code,

      Code:
      HashMap<String, Object> data = new HashMap<String, Object>();
      data.put("key1", "Value1");
      data.put("key2", "Value2");
      		
      JSONEncoder jsonEncoder = new JSONEncoder();
      String jsonData = jsonEncoder.encode(data);
      Here is the complete stack trace,

      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.util.JSONEncoder.encode(JSONEncoder.java)
      at com.smart.gwt.client.SampleSmartGWTApp.onModuleLoad(SampleSmartGWTApp.java:57)
      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.ModuleSpace.onLoad(ModuleSpace.java:396)
      at com.google.gwt.dev.shell.OophmSessionHandler.loadModule(OophmSessionHandler.java:200)
      at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:525)
      at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363)
      at java.lang.Thread.run(Thread.java:662)

      Comment


        #4
        Not reproducible (obviously). You probably have something wrong in your environment, such as mixed versions of files. Run a GWT compile, restart your browser and clear cache on a blank page. If that doesn't fix it, rebuild your project using the installation instructions.

        Comment


          #5
          Ok, let me create a fresh project and try this out again.

          Btw, i am using GWT 2.4 with SmartGWT2.5.

          Comment


            #6
            Hi,
            I'm facing exactly the same problem. I've prepared a minimal test case for you to reproduce the behaviour.

            I simply create different flat and nested object structures using pojos and records. In development mode, the encoder fails with every testcase, in production mode, the simple pojo test succeeds while the other object structures cause the encoder to fail again. Am I missing something?

            I've been using GWT 2.3 and SmartGWT EE2.5 Version SC_SNAPSHOT-2011-11-02/EVAL Deployment (2011-11-02), FF3.6.15 on a W2k8 Server. Actually nothing seems to be wrong with my environment, browser etc. pp. so I think this might be a bug...

            The entry point class....
            Code:
            package json.test.client;
            
            import java.util.ArrayList;
            import java.util.Date;
            
            import com.google.gwt.core.client.EntryPoint;
            import com.google.gwt.core.client.GWT;
            import com.google.gwt.core.client.GWT.UncaughtExceptionHandler;
            import com.smartgwt.client.data.Record;
            import com.smartgwt.client.util.JSONEncoder;
            import com.smartgwt.client.util.SC;
            import com.smartgwt.client.widgets.Button;
            import com.smartgwt.client.widgets.Canvas;
            import com.smartgwt.client.widgets.events.ClickEvent;
            import com.smartgwt.client.widgets.events.ClickHandler;
            
            /**
             * Entry point classes define <code>onModuleLoad()</code>.
             */
            public class JSONEncoderTest implements EntryPoint {
            	
            	class A {
            		ArrayList<B> bSet = new ArrayList<B>();
            		ArrayList<CRecord> cSet = new ArrayList<CRecord>();
            	}
            	
            	class B {
            		ArrayList<CRecord> cSet = new ArrayList<CRecord>();
            		CRecord cField = new CRecord();
            	}
            	
            	class CRecord extends Record {
            		String testStr = "foo";
            		Date testDate = new Date();
            		public CRecord() {
            			super();
            			this.testStr = testStr + Math.random();
            			this.setAttribute("testStr", testStr);
            			this.setAttribute("testDate", testDate);
            		}
            	}
            	
            	class CPojo {
            		String testStr = "foo";
            		Date testDate = new Date();
            		public CPojo() {
            			this.testStr = testStr + Math.random();
            		}
            	}
            	
            	
            	/**
            	 * This is the entry point method.
            	 */
            	public void onModuleLoad() {
            		
            		SC.showConsole();
            
            		final JSONEncoder encoder = new JSONEncoder();
            		
            		GWT.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
            			@Override
            			public void onUncaughtException(Throwable e) {
            				SC.say("Exception occurred :" + e.getMessage());
            			}
            		});
            		
            		Button b1 = new Button("Simple Pojo"); 
            		Button b2 = new Button("Simple Record");
            		Button b3 = new Button("Nested Record");
            		Canvas buttonLayout = new Canvas(); 
            		buttonLayout.addChild(b1);
            		buttonLayout.addChild(b2);
            		buttonLayout.addChild(b3);
            		b1.setRect(6, 6, 100, 22);
            		b2.setRect(116, 6, 100, 22);
            		b3.setRect(216, 6, 100, 22);
            		
            		buttonLayout.setRect(5, 5, 500, 30);
            		
            		b1.addClickHandler(new ClickHandler() {
            			@Override
            			public void onClick(ClickEvent event) {				
            				SC.say(encoder.encode(new CPojo()));
            			}
            		});
            		
            		b2.addClickHandler(new ClickHandler() {
            			@Override
            			public void onClick(ClickEvent event) {				
            				SC.say(encoder.encode(new CRecord()));
            			}
            		});
            		
            		b3.addClickHandler(new ClickHandler() {
            			@Override
            			public void onClick(ClickEvent event) {				
            				SC.say(encoder.encode(createNestedTestData()));
            			}
            		});
            		
            		buttonLayout.draw();
            	}
            	
            	private B createBTestData() {
            		B clazzB = new B();
            		for (int i = 0; i < 30; i++) {
            			clazzB.cSet.add(new CRecord());
            		}
            		return clazzB;
            	}
            	
            	private A createNestedTestData() {
            		A clazzA = new A();
            		
            		for (int i = 0; i < 30; i++)
            			clazzA.bSet.add(createBTestData());
            			
            		for (int i = 0; i < 30; i++)
            			clazzA.cSet.add(new CRecord());
            		
            		return clazzA;
            	}
            }
            The module.xml...
            Code:
            <?xml version="1.0" encoding="UTF-8"?>
            <module rename-to='jsonencodertest'>
              <!-- Inherit the core Web Toolkit stuff.                        -->
              <inherits name='com.google.gwt.user.User'/>
            
              <!-- Other module inherits                                      -->
              <inherits name="com.smartgwtee.SmartGwtEE"/>
              <inherits name="com.smartgwtee.tools.Tools"/>
                
              <!-- Specify the app entry point class.                         -->
              <entry-point class='json.test.client.JSONEncoderTest'/>
            
              <!-- Specify the paths for translatable code                    -->
              <source path='client'/>
              <source path='shared'/>
            
            </module>
            Here's the stack trace:
            Code:
            Caused by: com.google.gwt.core.client.JavaScriptException: (null): null
                at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:237)
                at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:132)
                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.util.JSONEncoder.encode(JSONEncoder.java)
                at json.test.client.JSONEncoderTest$2.onClick(JSONEncoderTest.java:87)
                at com.smartgwt.client.widgets.events.ClickEvent.dispatch(ClickEvent.java:99)
                at com.smartgwt.client.widgets.events.ClickEvent.dispatch(ClickEvent.java:1)
                at com.google.gwt.event.shared.GwtEvent.dispatch(GwtEvent.java:1)
                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.widgets.BaseWidget.fireEvent(BaseWidget.java:67)
                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:167)
                at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:326)
                at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:207)
                at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:132)
                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:214)
                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:167)
                at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:281)
                at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:531)
                at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:352)
                at java.lang.Thread.run(Thread.java:662)
            Greez, Holger

            Comment


              #7
              Just one more remark. I've slightly modified the record structure and tried to convert the nested record object to a map. The convert to map test case fails in devmode and production mode using the same environment as before providing the same stack trace. Here is the modified test case.

              Code:
              package json.test.client;
              
              import java.util.ArrayList;
              import java.util.Date;
              import java.util.Map;
              
              import com.google.gwt.core.client.EntryPoint;
              import com.google.gwt.core.client.GWT;
              import com.google.gwt.core.client.GWT.UncaughtExceptionHandler;
              import com.smartgwt.client.data.Record;
              import com.smartgwt.client.util.JSONEncoder;
              import com.smartgwt.client.util.SC;
              import com.smartgwt.client.widgets.Button;
              import com.smartgwt.client.widgets.Canvas;
              import com.smartgwt.client.widgets.events.ClickEvent;
              import com.smartgwt.client.widgets.events.ClickHandler;
              
              /**
               * Entry point classes define <code>onModuleLoad()</code>.
               */
              public class JSONEncoderTest implements EntryPoint {
              	
              	class A {
              		ArrayList<B> bSet = new ArrayList<B>();
              		ArrayList<CRecord> cSet = new ArrayList<CRecord>();
              	}
              	
              	class B {
              		ArrayList<CRecord> cSet = new ArrayList<CRecord>();
              		CRecord cField = new CRecord();
              	}
              	
              	class CRecord extends Record {
              		String testStr = "foo";
              		Date testDate = new Date();
              		public CRecord() {
              			super();
              			this.testStr = testStr + Math.random();
              			this.setAttribute("testStr", testStr);
              			this.setAttribute("testDate", testDate);
              		}
              	}
              	
              	class NestedRecord extends Record {
              		public NestedRecord() {
              			super();
              		}
              		
              		public void addRecord(Record r) {
              			this.setAttribute("record"+Math.random(), r);			
              		}
              	}
              	
              	
              	class CPojo {
              		String testStr = "foo";
              		Date testDate = new Date();
              		public CPojo() {
              			this.testStr = testStr + Math.random();
              		}
              	}
              	
              	
              	/**
              	 * This is the entry point method.
              	 */
              	public void onModuleLoad() {
              		
              		SC.showConsole();
              
              		final JSONEncoder encoder = new JSONEncoder();
              		
              		GWT.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
              			@Override
              			public void onUncaughtException(Throwable e) {				
              				SC.say("Exception occurred :" + e.getMessage());
              				GWT.log("Exception occurred :" + e.getMessage(), e);
              			}
              		});
              		
              		Button b1 = new Button("Encode Simple Pojo"); 
              		Button b2 = new Button("Encode Simple Record");
              		Button b3 = new Button("Encode Nested Record");
              		Button b4 = new Button("Convert Nested To Map & Encode");
              		Canvas buttonLayout = new Canvas(); 
              		buttonLayout.addChild(b1);
              		buttonLayout.addChild(b2);
              		buttonLayout.addChild(b3);
              		buttonLayout.addChild(b4);
              		b1.setRect(6, 6, 150, 22);
              		b2.setRect(156, 6, 150, 22);
              		b3.setRect(306, 6, 150, 22);
              		b4.setRect(456, 6, 200, 22);
              		
              		buttonLayout.setRect(5, 5, 800, 30);
              		
              		b1.addClickHandler(new ClickHandler() {
              			@Override
              			public void onClick(ClickEvent event) {				
              				SC.say(encoder.encode(new CPojo()));
              			}
              		});
              		
              		b2.addClickHandler(new ClickHandler() {
              			@Override
              			public void onClick(ClickEvent event) {
              				SC.say(encoder.encode(new CRecord()));
              			}
              		});
              		
              		b3.addClickHandler(new ClickHandler() {
              			@Override
              			public void onClick(ClickEvent event) {				
              				SC.say(encoder.encode(createNestedTestData()));
              			}
              		});
              
              		b4.addClickHandler(new ClickHandler() {
              			@Override
              			public void onClick(ClickEvent event) {
              				final Record nr = createNestedRecord();
              				final Map map = nr.toMap();
              				SC.say("conversion successful: " + map.values().toString());
              				SC.say("encoding successful: " + encoder.encode(createNestedTestData()));
              			}
              		});
              
              		
              		buttonLayout.draw();
              	}
              	
              	private B createBTestData() {
              		B clazzB = new B();
              		for (int i = 0; i < 30; i++) {
              			clazzB.cSet.add(new CRecord());
              		}
              		return clazzB;
              	}
              	
              	private A createNestedTestData() {
              		A clazzA = new A();
              		
              		for (int i = 0; i < 30; i++)
              			clazzA.bSet.add(createBTestData());
              			
              		for (int i = 0; i < 30; i++)
              			clazzA.cSet.add(new CRecord());
              		
              		return clazzA;
              	}
              	
              
              	private Record createNestedRecord() {
              		NestedRecord nr = new NestedRecord();
              		for (int i = 0; i < 30; i++) {
              			nr.addRecord(new CRecord());
              		}
              		return nr;
              	}
              }
              I hope, this is sufficient to clarify whether this is a bug or just wrong usage of the Encoder.

              Greez, Holger

              Comment


                #8
                JSON encoding doesn't support POJOs, that would require Java Reflection capabilities which GWT does not support. This code would not work in any environment.

                Comment

                Working...
                X