Não é possível desserializar a instância de java.lang.String de START_OBJECT token

Eu estou correndo em um problema onde meu jar implantável atinge uma exceção que não acontece quando eu executo isso localmente no IntelliJ.

Exceção:

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 

Manipulador de soquete

Eu acredito que a exceção está ocorrendo quando o JSON é analisado em um object WorkstationRequest por causa do item abaixo. Este é o manipulador de soquete:

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

O object que o manipulador de soquete mapeia para:

 public class WorkstationRequest { /* Class to instantiate if this workstation does not already exist */ private Class 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 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; } } 

O JSON sendo mapeado:

 {"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 queue = new HashMap(); private LinkedBlockingDeque 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 getQueue() { return queue; } public LinkedBlockingDeque getCurrentWork() { return currentWork; } public void setCurrentWork(LinkedBlockingDeque currentWork) { this.currentWork = currentWork; } } 

Estou com muita perda de como começar a depurar isso. O rastreamento de pilha nunca toca meu aplicativo. Estou usando o Maven -> Package para implantar meu .jar e executá-lo com java -jar /path-to-jar.jar

Atualização: Para evitar que essa questão seja incrivelmente longa, incluí meu pom.xml aqui: http://pastebin.com/1ZUtKCfE . Eu acredito que este é um problema de dependência, pois o erro só ocorre no meu jar implantar e não no meu PC local.

Você está mapeando este JSON

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

que contém um elemento chamado data que tem um object JSON como seu valor. Você está tentando desserializar o elemento chamado workstationUuid desse object JSON para este setter.

 @JsonProperty("workstationUuid") public void setWorkstation(String workstationUUID) { 

Isso não funcionará diretamente porque Jackson vê um JSON_OBJECT, não um String.

Tente criar uma class de Data

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

a mudar o seu método

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

O conteúdo de dados é tão variável, acho que a melhor forma é defini-lo como “ObjectNode” e depois criar sua própria class para analisar:

Finalmente:

dados privados do ObjectNode;

Se você não deseja definir uma class separada para json nested, a definição de object json nested como JsonNode deve funcionar, por exemplo:

 {"id":2,"socket":"0c317829-69bf-43d6-b598-7c0c550635bb","type":"getDashboard","data":{"workstationUuid":"ddec1caa-a97f-4922-833f-632da07ffc11"},"reply":true} @JsonProperty("data") private JsonNode data; 
Intereting Posts