0

I have a game in java called "Scotland Yard". In backend it is coded with java and frontend is coded with angular. From the beginning the game contained enums as transportation types but then our assignment were to have dynamically transport types. So we removed the enums and replaced it witha class called Ttype were we can add new transport types as instances of the class Ttype. we did that with the help of an arraylist. So in the code (which contains many classes) we replaced everything in the code from enum type to my new class Ttype. It works just fine but I get an error when I try to start the game. The error is very long and says:

2020-10-29 15:25:41.901[0;39m [31mERROR[0;39m [35m2596[0;39m [2m---[0;39m [2m[nio-7001-exec-2][0;39m [36mo.a.c.c.C.[.[.[/].[dispatcherServlet] [0;39m [2m:[0;39m Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.client.RestClientException: Error while extracting response for type [class se.kau.cs.sy.board.Board] and content type [application/json]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of se.kau.cs.sy.board.Ttype (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of se.kau.cs.sy.board.Ttype (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator) at [Source: (PushbackInputStream); line: 1, column: 139] (through reference chain: se.kau.cs.sy.board.Board["nodes"]->java.util.ArrayList[0]->se.kau.cs.sy.board.Node["links"]->java.util.HashSet[0]->se.kau.cs.sy.board.Link["type"])] with root cause

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of se.kau.cs.sy.board.Ttype (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator) at [Source: (PushbackInputStream); line: 1, column: 139] (through reference chain: se.kau.cs.sy.board.Board["nodes"]->java.util.ArrayList[0]->se.kau.cs.sy.board.Node["links"]->java.util.HashSet[0]->se.kau.cs.sy.board.Link["type"])

I don't understand what to do, What I think the error is that now when I do not have enums anymore the Ttype is causing problems. Here is the classes I think has something to do with the error. Can comeone please help me. I know it is alot to see but I dont really know what to do. Sorry for my bad english. I hope you understand

My Link class:

package se.kau.cs.sy.board;

import java.io.Serializable;

public class Link implements Serializable {

    private static final long serialVersionUID = 1L;
    private int[] nodes = new int[2];
    private Ttype type;
    
    //Only for json deserialization
    public Link() {
    }
    
    public Link(int nodea, int nodeb, Ttype t) {
        nodes[0] = nodea;
        nodes[1] = nodeb;
        type = t;
    }

    public int[] getNodes() {
        return nodes;
    }

    public Ttype getType() {
        return type;
    }

    //Only for json deserialization
    public void setNodes(int[] nodes) {
        this.nodes = nodes;
    }

    //Only for json deserialization
    public void setType(Ttype type) {
        this.type = type;
    }
    
    
}

My Ttype class:

package se.kau.cs.sy.board;

import java.util.ArrayList;
import java.util.Objects;

public class Ttype{
    
    public String Transport = "";

    public Ttype(String type) {
        
        this.Transport = type;
    }

    public String getTransport() {
        return Transport;
    }

    public void setTransport(String type) {
        this.Transport = type;
    }
}

My board class:

package se.kau.cs.sy.board;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.UUID;
import java.util.Random;
import java.util.Scanner;
import java.io.IOException;

import se.kau.cs.sy.match.Readconfig;
import se.kau.cs.sy.util.FileHandler;

public class Board implements Serializable {

    private static final long serialVersionUID = 1L;

    private static Board londonBoard;

    private final UUID id;
    private String name = "";
    private List<Node> nodes = new ArrayList<>();
    static Readconfig read = new Readconfig();
    
    static {
         londonBoard = loadMap();
         londonBoard.setName(read.array1[0]);
    }
    
    private Board(String name) {
        id = UUID.randomUUID();
        this.name = name;
    }

    //Only for json deserialization
    public Board() {
        this("");
    }

    
    public static Board create() {
        return londonBoard;
    }
    
    public UUID getId() {
        return id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public List<Node> getNodes() {
        return new ArrayList<>(nodes);
    }
    
    public Set<Link> getLinks(int node) {
        return getLinks(node, null);
    }
    
    public Set<Link> getLinks(int node, Ttype type) {
        Set<Link> links = nodes.get(node).getLinks();
        if (type != null) {
            links.removeIf(l -> l.getType() != type);
        }
        return links; 
    }
    
    public Location getLocation(int node) {
        return nodes.get(node).getLocation();
    }
    
    public Set<Integer> getNeighbourNodes(int node) {
            return getNeighbourNodes(node, null); //unknown
    }
    
    public Set<Integer> getNeighbourNodes(int node, Ttype type) {
        Set<Integer> result = new HashSet<>();
        Set<Link> links = this.getLinks(node, type);
        for (Link l : links) {
            result.add(l.getNodes()[0]);
            result.add(l.getNodes()[1]);
        }
        result.remove(node);
        return result;
    }
    
    public boolean connected(int nodeA, int nodeB, Ttype type) {
        return getNeighbourNodes(nodeA, type).contains(nodeB);
    }
    
    public boolean connected(int nodeA, int nodeB) {
        return getNeighbourNodes(nodeA, null ).contains(nodeB);
    }
    
    public int lastNodeIndex() {
        return nodes.get(nodes.size() - 1).getId();
    }
    
    public boolean nodeExists(int number) {
        return number > 0 && number <= lastNodeIndex();
    }
    
    private static Board loadMap() {
        Board map = new Board();
        try {
            FileHandler mapHandler = new FileHandler("se/kau/cs/sy/" +read.array1[1]+".txt");
            // RandomAccessFile map=new RandomAccessFile(f,"r");  //kanske bra och använda
            String buffer=mapHandler.readLine();
            StringTokenizer token;
            token=new StringTokenizer(buffer);
            int nrNodes=Integer.parseInt(token.nextToken());
            Location locs[] = readMapPositions();
            for (int i = 0; i < nrNodes; i++ ) {
                Node newNode = new Node(i);
                newNode.setLocation(locs[i]);
                map.nodes.add(newNode);
            }
            
            
            buffer=mapHandler.readLine();
            while(buffer!=null && buffer.trim().length()>0) {
                token=new StringTokenizer(buffer);
                int node1=Integer.parseInt(token.nextToken());
                int node2=Integer.parseInt(token.nextToken());
                String strType=token.nextToken();
                Ttype type =null; //unknown

                for(int i = 0; i < read.typearray.size(); i++) {
                
                    if(read.typearray.get(i).Transport.equals(strType)) {
                    
                        type=read.typearray.get(i); break;//ny
                        }
                }
            
                Link newLink = new Link(node1, node2, type);
                map.nodes.get(node1).addLink(newLink);
                map.nodes.get(node2).addLink(newLink);
                buffer=mapHandler.readLine();
            }
            mapHandler.close();
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    return map;
    }
 
    
    private static Location[] readMapPositions() {
    
        Location result[] = null;
        try {
            FileHandler map = new FileHandler("se/kau/cs/sy/" +read.array1[2]+ ".txt");
                
            String buffer = map.readLine();
            StringTokenizer token;
            token = new StringTokenizer(buffer);
            int numPos = Integer.parseInt(token.nextToken());
            result = new Location[numPos];
            for(int i = 0; i < numPos; i++)
            {
                buffer = map.readLine();
                token = new StringTokenizer(buffer);
                
                int pos = Integer.parseInt(token.nextToken());
                int posX = Integer.parseInt(token.nextToken());
                int posY = Integer.parseInt(token.nextToken());
                
                result[pos] = new Location(posX, posY);
            }
        }
        catch(Exception e) {
            System.exit(1);
        }
        return result;
    }
    

    //Only for json deserialization
    public void setNodes(List<Node> nodes) {
        this.nodes = nodes;
    }
    
}

Here is an error. My code crashes just after " MatchConfigurationImpl.Builder builder = new MatchConfigurationImpl.Builder();"

@PostMapping("/matches")
    public UUID createMatch(@RequestBody MatchConfigurationDTO conf) {
        MatchConfigurationImpl.Builder builder = new MatchConfigurationImpl.Builder();
        Board board = restTemplate.getForObject(integration.getBoardDetailsServiceUrl(), Board.class); //my code crashes here 
        if (board != null) {
            builder.board(board)
                .detectives(conf.getNrOfDetectives())
                .startPositions(conf.getStartingPositions())
                .surfacingTurns(conf.getSurfacingTurns())
                .turns(conf.getNrOfTurns())
                .ticketsForDetectives(conf.getTicketsdetectives())  //ny
                .ticketsForMrX(conf.getTicketsMrx())
                .ticketNames(conf.getTicketNames());   //ny
            Match newMatch = new Match(builder.build());
            //TODO: add Mr. X properly
            newMatch.registerMrX(new RandomPlayer(PlayerRole.MR_X));
            storage.add(newMatch, "New match");
            return newMatch.getId();
        }
        else
            return null;
    }

What can the problem be? any idea? Sorry if these classes don't help I will try to add other classes if needed.

Mohammed
  • 195
  • 1
  • 3
  • 12

1 Answers1

0

The error is saying Cannot construct instance of se.kau.cs.sy.board.Ttype (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator) at

It seems that you should add to your Ttype class a Jackson creator so when deserialising from Json it will know how to create an instance of Ttype.

Also, take a look at this thread No Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator

Rweinz
  • 195
  • 2
  • 7
  • This jackson creator should be in my Ttype class? Will it convert my java code to Json code or what does it do exactly? please explain with an example if possible. I am really bad at this kind of programming so if you can just explain briefly for me how and what this does I would appreciate it. Thanks – Mohammed Oct 29 '20 at 16:49
  • @Mohammed Try adding '@JsonCreator' annotation to your tType constructor. As seen here: http://www.cowtowncoder.com/blog/archives/2011/07/entry_457.html – Rweinz Oct 29 '20 at 16:59