Announcement Announcement Module
Collapse
No announcement yet.
"flexjson.JSONException: Error trying to deepSerialize" confussion Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • "flexjson.JSONException: Error trying to deepSerialize" confussion

    I am trying to use the toJsonArray on a list of domain objects and getting this:
    Code:
    2012-02-16 10:06:57,770 [taskScheduler-2] ERROR org.springframework.scheduling.support.MethodInvokingRunnable - Invocation of method 'processPendingMessages' on target class [class com.xyz.art.messaging.MessagingCoordinator] failed
    flexjson.JSONException: Error trying to deepSerialize
    	at flexjson.transformer.ObjectTransformer.transform(ObjectTransformer.java:61)
    	at flexjson.transformer.TransformerWrapper.transform(TransformerWrapper.java:22)
    	at flexjson.transformer.ObjectTransformer.transform(ObjectTransformer.java:49)
    	at flexjson.transformer.TransformerWrapper.transform(TransformerWrapper.java:22)
    	at flexjson.transformer.ObjectTransformer.transform(ObjectTransformer.java:49)
    	at flexjson.transformer.TransformerWrapper.transform(TransformerWrapper.java:22)
    	at flexjson.transformer.ObjectTransformer.transform(ObjectTransformer.java:49)
    	at flexjson.transformer.TransformerWrapper.transform(TransformerWrapper.java:22)
    	at flexjson.JSONContext.transform(JSONContext.java:73)
    	at flexjson.transformer.IterableTransformer.transform(IterableTransformer.java:29)
    	at flexjson.transformer.TransformerWrapper.transform(TransformerWrapper.java:22)
    	at flexjson.JSONContext.transform(JSONContext.java:73)
    	at flexjson.JSONSerializer.serialize(JSONSerializer.java:377)
    	at flexjson.JSONSerializer.serialize(JSONSerializer.java:235)
    	at com.xyz.art.domain.Message_Roo_Json.toJsonArray_aroundBody2(Message_Roo_Json.aj:24)
    	at com.xyz.art.domain.Message_Roo_Json.ajc$interMethod$com_xyz_art_domain_Message_Roo_Json$com_xyz_art_domain_Message$toJsonArray(Message_Roo_Json.aj:1)
    	at com.xyz.art.domain.Message.toJsonArray(Message.java:1)
    	at com.xyz.art.domain.Message_Roo_Json.ajc$interMethodDispatch1$com_xyz_art_domain_Message_Roo_Json$com_xyz_art_domain_Message$toJsonArray(Message_Roo_Json.aj)
    	at com.xyz.art.messaging.MessagingCoordinator.processPendingMessages(MessagingCoordinator.java:113)
    	at sun.reflect.GeneratedMethodAccessor87.invoke(Unknown Source)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:273)
    	at org.springframework.scheduling.support.MethodInvokingRunnable.run(MethodInvokingRunnable.java:65)
    	at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:51)
    	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    	at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
    	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
    	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
    	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:180)
    	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:204)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    	at java.lang.Thread.run(Thread.java:680)
    Caused by: java.lang.IllegalAccessException: Class flexjson.BeanProperty can not access a member of class sun.util.calendar.CalendarDate with modifiers "private"
    	at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
    	at java.lang.reflect.Field.doSecurityCheck(Field.java:960)
    	at java.lang.reflect.Field.getFieldAccessor(Field.java:896)
    	at java.lang.reflect.Field.get(Field.java:358)
    	at flexjson.BeanProperty.getValue(BeanProperty.java:104)
    	at flexjson.transformer.ObjectTransformer.transform(ObjectTransformer.java:37)
    	... 33 more
    My class looks like this:
    Code:
    package com.xyz.art.domain;
    
    import java.util.Calendar;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    
    import javax.persistence.EntityManager;
    import javax.persistence.Enumerated;
    import javax.persistence.ManyToMany;
    import javax.persistence.OneToMany;
    import javax.persistence.Temporal;
    import javax.persistence.TemporalType;
    import javax.persistence.TypedQuery;
    import javax.validation.constraints.NotNull;
    import org.springframework.format.annotation.DateTimeFormat;
    import org.springframework.roo.addon.javabean.RooJavaBean;
    import org.springframework.roo.addon.jpa.activerecord.RooJpaActiveRecord;
    import org.springframework.roo.addon.json.RooJson;
    import org.springframework.roo.addon.tostring.RooToString;
    
    @RooJavaBean
    @RooToString
    @RooJpaActiveRecord
    @RooJson
    public class Message {
        @NotNull
        @Enumerated
        private MessageDisplayType displayType;
    
        @NotNull
        private String title;
    
        @NotNull
        private String message;
        
        @ManyToMany
        private Set<SiteAuthority> destinationAuthorities = new HashSet<SiteAuthority>();
        
        /**
         * If ackRequired == true, the message will continue to be sent until it is acknowledged.
         * If ackRequired == false, the message is auto-ack'ed when it is sent, as we don't care 
         * about guaranteed delivery.
         */
        private boolean ackRequired = false;
        
        @NotNull
        @Temporal(TemporalType.TIMESTAMP)
        @DateTimeFormat(style = "MM")
        private Calendar createdOn = Calendar.getInstance();
        
        @Temporal(TemporalType.TIMESTAMP)
        @DateTimeFormat(style = "MM")
        private Calendar sentOn;
        
        @Temporal(TemporalType.TIMESTAMP)
        @DateTimeFormat(style = "MM")
        private Calendar start;
        
        @Temporal(TemporalType.TIMESTAMP)
        @DateTimeFormat(style = "MM")
        private Calendar expiration;
    }
    Nothing overly crazy. What I am confused about is why it's complaining about serializing the Calendar objects? Aren't all the values marked "private"? I have use the Object.toJsonArray many times, and never had a problem with other class members that were marked as "private".

    Anyone know why it might be complaining now?

  • #2
    I have the exact same problem as mbabauer.
    Googling hasn't helped so far.
    Any hint?

    Comment


    • #3
      Yeah, I haven't figured it out yet, either. Its sort of blocking my development at the moment.

      For additional information, what I have is a class that has a method setup with a simple Scheduler. When kicked off, it uses a find to get a bunch of these Message objects out of the DB, which is returned as a TypedQuery. It then uses getResultList() to get it as a list, does some processing to convert that to a HashMap, then iterates the keys of the HashMap, creating a third list of Messages that need acting on. This list is what is being serialized via the Message.toJsonArray(). I have broke at the spot where the serialization occurs, and the list looks fine. I can see the Message objects, can click the various parts, etc.

      From the error message, though, I am lead to believe this might not be in the Message class at all, though, given the phrase "deepSerialize". So, it may be one of the linked objects. My next step will be to start looking at those more closely to see if I can figure out why this is happening.

      Comment


      • #4
        I'm trying to debug the FlexJson JSONSerializer().serialize() (difficult task for me).
        The first weird thing is that maybe it has problems with the Calendar type we are using; it has a map of transformers, and the Calendar type isn't in it! It has a GregorianCalendar and a JulianCalendar one, and a java.util.Date one, but not the abstract Calendar...

        I have to dig into it more.
        I'll keep you posted.

        Comment


        • #5
          If I use a java.util.Date field the serializer works without exceptions...but it outputs a Long instead of a date, and there are other problems with the scaffolded MVC controller, the jspx has problems in formatting such Long.
          I guess Roo is built to use a Calendar and not a Date.
          ----------------------
          I tryed using a GregorianCalendar: it gives the same exception as before, but now it is thrown on my own class containing the date field, and not on the Calendar anymore.

          The ObjectTransformer is looking for a Calendar field named "modifyDate", but it can't find one!
          The one that is in there is a GregorianCalendar indeed.

          ObjectTransformer:
          Code:
          BeanAnalyzer analyzer = BeanAnalyzer.analyze( resolveClass(object) );
          TypeContext typeContext = context.writeOpenObject();
          for( BeanProperty prop : analyzer.getProperties() ) {
          	String name = prop.getName();
          	path.enqueue(name);
          	if( context.isIncluded(prop) ) {
          		Object value = prop.getValue( object ); // <<<<< exception here!
          		if (!context.getVisits().contains(value)) {
          
          			TransformerWrapper transformer = (TransformerWrapper)context.getTransformer(value);
          
          			if(!transformer.isInline()) {
          				if (!typeContext.isFirst()) context.writeComma();



          BeanProperty:
          Code:
          public Object getValue(Object instance) throws InvocationTargetException, IllegalAccessException {
          	Method rm = getReadMethod();
          	if (rm != null ) {
          		return rm.invoke(instance, (Object[]) null);
          	} else if (property != null) {
          		return property.get(instance);  // <<<<< exception here!
          	} else {
          		return null;
          	}
          }
          Maybe I should ask such questions on the FlexJason list.

          Comment


          • #6
            I think my former guesses were wrong: there's no problem in finding a transformer for a GregorianCalendar.
            The field that cannot be read from Calendar (GregorianCalendar in my case) is "locale", which has no getter as per its API. Let's go ahead tomorrow...

            Comment


            • #7
              Great work!

              I have played with using the Date in leu of Calendar, but I too have had many problems with it.

              It does sound like this is a problem with the Flex JSON parser. I might try to change the version in the pom.xml. I haven't checked yet, but maybe there is a newer version out that might correct the problem. Its worth a shot, at least.

              Comment


              • #8
                Originally posted by mbabauer View Post
                It does sound like this is a problem with the Flex JSON parser. I might try to change the version in the pom.xml. I haven't checked yet, but maybe there is a newer version out that might correct the problem. Its worth a shot, at least.
                I tryed changing the execution environment:
                * from JDK 1.6.30 64bit back to JDK 1.6.24 32bit (under Windows 7);
                * from flexJSON 2.1 back to 2.0 (there's no newer released version AFAIK)

                but the problem seems always the same :-(

                Comment


                • #9
                  I managed to obtain something useful, even if maybe it's still not perfect.
                  The flexJSON home page [1] explains how to use the DateTransformer to serialize dates...I need to learn its API still better :-)

                  Now my serializer looks like so:
                  Code:
                  public static String toJsonArray(Collection<RoomType> collection) {
                  	return new JSONSerializer()
                  			.include("name", "code")
                  			.include("modifyDate.time")
                  			.exclude("*")
                  			.transform(new DateTransformer("MM/dd/yyyy"), "modifyDate.time")
                  			.serialize(collection);
                  }
                  I include my fields explicitly: the entity plain fields and the Calendar time.
                  Than I exclude everything else.
                  Finally I state that the field "modify.time" shall be transformed using a DateTransformer with a pattern "MM/dd/yyyy". That needed to be done anyway, otherwise it would have serialized every damn field out of the Calendar...

                  Now the outputted JSON looks quite good:
                  Code:
                  [
                        {
                        "code": "RGV",
                        "modifyDate": {"time": "02/08/2012"},
                        "name": "Royal garden Villa"
                     },
                        {
                        "code": "MSUI",
                        "modifyDate": {"time": "02/15/2012"},
                        "name": "Master suite vista montagne"
                     }
                  ]
                  Hope this helps.
                  Cheers,
                  Vito Meuli

                  [1] http://flexjson.sourceforge.net/

                  Comment


                  • #10
                    So, I wanted to update this posting with the latest...

                    I found several discussions on the inter-tubes about this particular error, but no solid answers. The best I found was to use Vito's suggestion, modified for my own situation, which uses a Transformer.

                    In essence, what I did was pushed my toJasonArray() into my domain object, then modified the call to add an exclude for all of the Calendar members, and a transform to all the Calendars .time members. The code looks something like this:
                    Code:
                        public static java.lang.String toJsonArray(Collection<Message> collection) {
                            return new JSONSerializer().exclude("createdOn","sentOn","start","expiration")
                                .exclude("*.class").transform(new DateTransformer("MM/dd/yyyy HH:mm:ss z"),
                                "createdOn.time","sentOn.time","start.time","expiration.time").serialize(collection);
                        }
                    So, basically you are black-listing the Calendars, which seem to cause FlexJSON problems, and telling it to only pay attention to transforming the "time" for each. Once implemented, my code works flawlessly.

                    Comment


                    • #11
                      Tried

                      I know this is an old thread but I have a similar issue. I have tried all of the above which only partially resolves the problem, for some unknown reason it will only output 1 field in Json format - the others are completely disregarded - any thoughts?

                      code:

                      public static String Vpatients.toJsonArray(Collection<Vpatients> collection) {
                      return new JSONSerializer()
                      .include("modifiedOn.time")
                      .include("DOB.time")
                      .include("DOD.time")
                      .include("Title.String")
                      .transform(new DateTransformer("dd/MM/yyyy"), "modifiedOn.time", "DOB.time", "DOD.time")
                      .transform(new StringTransformer(), "Title.String")
                      .exclude("*")
                      .serialize(collection);
                      }

                      Comment

                      Working...
                      X