2013-10-15 6 views
27

Ich stoße auf ein Problem, bei dem mein implementierbares Jar eine Ausnahme trifft, die nicht auftritt, wenn ich dies lokal in IntelliJ ausführe.Instanz von java.lang.String aus START_OBJECT-Token kann nicht deserialisiert werden

Ausnahme:

Receiving an event {id=2, socket=0c317829-69bf-43d6-b598-7c0c550635bb, type=getDashboard, data={workstationUuid=ddec1caa-a97f-4922-833f-632da07ffc11}, reply=true} 
Firing getDashboard event to Socket#0c317829-69bf-43d6-b598-7c0c550635bb 
Failed invoking AtmosphereFramework.doCometSupport() 
java.lang.IllegalArgumentException: Can not deserialize instance of java.lang.String out of START_OBJECT token 
at [Source: N/A; line: -1, column: -1] 
     at org.codehaus.jackson.map.ObjectMapper._convert(ObjectMapper.java:2502) 
     at org.codehaus.jackson.map.ObjectMapper.convertValue(ObjectMapper.java:2468) 
     at com.github.flowersinthesand.portal.support.DefaultDispatcher$DefaultHandler$DataParam.resolve(DefaultDispatcher.java:270) 
     at com.github.flowersinthesand.portal.support.DefaultDispatcher$DefaultHandler.handle(DefaultDispatcher.java:204) 
     at com.github.flowersinthesand.portal.support.DefaultDispatcher.fire(DefaultDispatcher.java:107) 
     at com.github.flowersinthesand.portal.support.AbstractSocketFactory.fire(AbstractSocketFactory.java:73) 
     at com.github.flowersinthesand.portal.atmosphere.AtmosphereSocketFactory.onRequest(AtmosphereSocketFactory.java:75) 
     at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:256) 
     at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:166) 
     at org.atmosphere.container.Grizzly2WebSocketSupport.service(Grizzly2WebSocketSupport.java:75) 
     at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:1342) 
     at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:219) 
     at org.atmosphere.websocket.DefaultWebSocketProcessor$2.run(DefaultWebSocketProcessor.java:183) 
     at org.atmosphere.util.VoidExecutorService.execute(VoidExecutorService.java:101) 
     at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:178) 
     at org.atmosphere.websocket.DefaultWebSocketProcessor.invokeWebSocketProtocol(DefaultWebSocketProcessor.java:167) 
     at org.atmosphere.container.Grizzly2WebSocketSupport$Grizzly2WebSocketApplication.onMessage(Grizzly2WebSocketSupport.java:171) 
     at org.glassfish.grizzly.websockets.DefaultWebSocket.onMessage(DefaultWebSocket.java:164) 
     at org.glassfish.grizzly.websockets.frametypes.TextFrameType.respond(TextFrameType.java:70) 
     at org.glassfish.grizzly.websockets.DataFrame.respond(DataFrame.java:104) 
     at org.glassfish.grizzly.websockets.WebSocketFilter.handleRead(WebSocketFilter.java:221) 
     at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) 
     at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:265) 
     at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200) 
     at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:134) 
     at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112) 
     at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:78) 
     at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:770) 
     at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112) 
     at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115) 
     at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55) 
     at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135) 
     at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:551) 
     at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:531) 
     at java.lang.Thread.run(Thread.java:781) 
Caused by: org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token 
at [Source: N/A; line: -1, column: -1] 
     at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163) 
     at org.codehaus.jackson.map.deser.StdDeserializationContext.mappingException(StdDeserializationContext.java:219) 
     at org.codehaus.jackson.map.deser.std.StringDeserializer.deserialize(StringDeserializer.java:44) 
     at org.codehaus.jackson.map.deser.std.StringDeserializer.deserialize(StringDeserializer.java:13) 
     at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:2704) 
     at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1315) 
     at org.codehaus.jackson.map.ObjectMapper._convert(ObjectMapper.java:2498) 
     ... 34 more 
java.lang.IllegalArgumentException: Can not deserialize instance of java.lang.String out of START_OBJECT token 
at [Source: N/A; line: -1, column: -1] Status 500 Message Server Error 

Sockel Handler

Ich glaube, die Ausnahme auftritt, wenn die JSON in ein WorkstationRequest Objekt analysiert wird aufgrund der unter Punkt. Dies ist die Buchse handler:

@On 
@Reply 
@JsonView({Views.WorkstationView.class}) 
public WorkstationDashboard getDashboard(@Data WorkstationRequest request) { 
    return new WorkstationDashboard(request.getWorkstation()); 
} 

Die Aufgabe der Socket-Handler zuordnet:

{"id":2,"socket":"0c317829-69bf-43d6-b598-7c0c550635bb","type":"getDashboard","data":{"workstationUuid":"ddec1caa-a97f-4922-833f-632da07ffc11"},"reply":true} 

WorkstationDashboard.java

public class WorkstationDashboard { 
    private HashMap<String, Object> queue = new HashMap<String, Object>(); 

    private LinkedBlockingDeque<JobSetEntity> currentWork; 

    public WorkstationDashboard() { 
     queue.put("size", 0); 
    } 

    public WorkstationDashboard(Workstation workstation) { 
     fromWorkstation(workstation); 
    } 

    /* Populate dashboard data from a workstation */ 
    public void fromWorkstation(Workstation workstation) { 
     WorkflowProcess workflowProcess = WorkflowProcessService.getWorkflowProcess(workstation); 

     setCurrentWork(workstation.getCurrentWork()); 
     setQueueSize(workflowProcess.getQueue().size()); 
    } 

    public void setQueueSize(Integer queueSize) { 
     queue.put("size", queueSize); 
    } 

    public HashMap<String, Object> getQueue() { 
     return queue; 
    } 

    public LinkedBlockingDeque<JobSetEntity> getCurrentWork() { 
     return currentWork; 
    } 

    public void setCurrentWork(LinkedBlockingDeque<JobSetEntity> currentWork) { 
     this.currentWork = currentWork; 
    } 
} 
:

public class WorkstationRequest { 

    /* Class to instantiate if this workstation does not already exist */ 
    private Class<? extends Workstation> workstationClass; 

    private WorkflowProcess workflowProcess; 

    private PhysicalWorkstation workstation; 

    WorkstationService workstationService; 

    /** 
    * @param workstationClass Required so when jackson maps the UUID we can auto fetch the class 
    */ 
    public WorkstationRequest(Class<? extends Workstation> workstationClass) { 
     this.workstationClass = workstationClass; 
     workstationService = (WorkstationService) ApplicationContextProvider.getApplicationContext().getBean("workstationService"); 
    } 

    /* Set the workstation based on UUID. Will register the workstation if it's new */ 
    @JsonProperty("workstationUuid") 
    public void setWorkstation(String workstationUUID) { 
     workstation = (PhysicalWorkstation)WorkstationService.getWorkstation(workstationUUID); 

     //setup new workstation 
     if (workstation == null) { 
      WorkstationEntity workstationEntity = workstationService.findByUUID(workstationUUID); 
      workstation = (PhysicalWorkstation)Workstation.factory(workstationEntity, workstationClass); 

      //register with queue 
      WorkflowProcessService.getWorkflowProcess(workstation).registerWorkstation(workstation); 
     } 
    } 

    public PhysicalWorkstation getWorkstation() { 
     return workstation; 
    } 
} 

Die JSON abgebildet wird

Ich bin ziemlich ratlos, wie ich mit der Fehlersuche beginnen soll. Der Stack-Trace berührt nie meine Anwendung. Ich verwende Maven -> Package meine .jar einzusetzen und es mit java -jar /path-to-jar.jar

aktualisiert Ausführung: Um diese Frage zu verhindern, unglaublich lang zu sein, ich habe mein pom.xml hier enthalten: http://pastebin.com/1ZUtKCfE. Ich glaube, das ist ein Abhängigkeitsproblem, da der Fehler nur bei meinem deploybaren jar und nicht bei meinem lokalen PC auftritt.

Antwort

36

Sie Kartierung dieses JSON

{ 
    "id": 2, 
    "socket": "0c317829-69bf-43d6-b598-7c0c550635bb", 
    "type": "getDashboard", 
    "data": { 
     "workstationUuid": "ddec1caa-a97f-4922-833f-632da07ffc11" 
    }, 
    "reply": true 
} 

, die ein Element enthält namens data, die ein JSON-Objekt als Wert hat. Sie versuchen, das Element mit dem Namen workstationUuid von diesem JSON-Objekt in diesen Setter zu deserialisieren.

Dies wird nicht direkt funktionieren, weil Jackson ein JSON_OBJECT, kein String sieht.

Versuchen Sie, eine Klasse Data

public class Data { // the name doesn't matter 
    @JsonProperty("workstationUuid") 
    private String workstationUuid; 
    // getter and setter 
} 

der Schalter auf Ihre Methode

@JsonProperty("data") 
public void setWorkstation(Data data) { 
    // use getter to retrieve it 
+0

ich nicht dies im Detail zu beschreiben, aber die Socket-Bibliothek I‘ m verwendet das 'data' Feld in diesem Array zu meinem Objekt über' public WorkstationDashboard getDashboard (@Data WorkstationRequest Anfrage) {'. Es ruft 'getDashboard()' wegen des 'type' in diesem JSON auf und bildet dann' data' ab. Ich könnte falsch liegen, da ich nicht wirklich weiß, was los ist. Aber da dies alles lokal auf meinem PC funktioniert und bricht, wenn ich meine Anwendung über ein .jar ausliege, scheint es eine Art Abhängigkeitsproblem zu sein. Mein Pom ist hier: http://pastebin.com/1ZUtKCfE – Webnet

+1

@Webnet Ist '@ Data' eine benutzerdefinierte Anmerkung, die das' Daten'-Feld von der JSON bindet? Sie müssen zurückverfolgen, um zu sehen, wie das Argument 'WorkstationRequest' generiert wird. –

+0

@SotiriosDelimanolis, SOLID Antwort Mann. Sparte mir Stunden der Fehlersuche. – icfantv

4

Dateninhalt ist so variabel zu schaffen, ich denke, die beste Form es als „ObjectNode“ zu definieren ist und als nächstes erstellen seine eigene Klasse zu analysieren:

Endlich:

private ObjectNode-Daten;

+1

Sie haben meine lange Jagd nach diesem gespeichert. Mein 'Daten'-Feld kann JSON enthalten, daher kann ich es nicht mit einem POJO verknüpfen. Ich suchte nach einer Lösung, die nur JSON-Wert enthalten kann. Ich danke dir sehr. Nur um zu überprüfen, gibt es irgendwelche Nebenwirkungen oder Nachteile der Verwendung? – theGamblerRises

2

Wenn Sie nicht über eine eigene Klasse für verschachtelte json definieren wollen, definieren verschachtelte JSON-Objekt als JsonNode funktionieren soll, zum Beispiel:

{"id":2,"socket":"0c317829-69bf-43d6-b598-7c0c550635bb","type":"getDashboard","data":{"workstationUuid":"ddec1caa-a97f-4922-833f-632da07ffc11"},"reply":true} 

@JsonProperty("data") 
    private JsonNode data;