Десериализация JSON в KryoNet

Пытаюсь написать сервер для онлайн-игры. На данном этапе сервер принимает от клиента координаты игрока и рассылает эти координаты остальным игрокам. В тестовом формате использовал сериализацию Kryo и всё работало отлично, но мне необходимо, чтобы информация в моих пакетах находилась в JSON, поскольку клиентская часть написана на C#. С этим возникают проблемы, а именно сервер выкидывает ошибки

09:24 ERROR: [kryonet] Error reading TCP from connection: Connection 1
com.esotericsoftware.kryonet.KryoNetException: Error during deserialization.
    at com.esotericsoftware.kryonet.TcpConnection.readObject(TcpConnection.java:141)
    at com.esotericsoftware.kryonet.Server.update(Server.java:205)
    at com.esotericsoftware.kryonet.Server.run(Server.java:372)
    at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: com.esotericsoftware.jsonbeans.JsonException: 
    at com.esotericsoftware.jsonbeans.Json.readValue(Json.java:800)
    at com.esotericsoftware.jsonbeans.Json.fromJson(Json.java:620)
    at com.esotericsoftware.kryonet.JsonSerialization.read(JsonSerialization.java:68)
    at com.esotericsoftware.kryonet.TcpConnection.readObject(TcpConnection.java:139)
    ... 3 more
Caused by: java.lang.ClassNotFoundException: Position
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:333)
    at com.esotericsoftware.jsonbeans.Json.readValue(Json.java:797)
    ... 6 more
09:24  INFO: [kryonet] Connection 1 disconnected.

после получения со стороны клиента JSON вида

{
class: Position,
x: 315,
y: 330,
z: 0
}

Класс Position как со стороны клиента, так и со стороны сервера одинаковый(поля публичные, поскольку было подозрение, что десериализация в приватные поля может приводить к ошибкам):

@Data
public class Position {
    public int x, y, z;
    public Position(){}
}

Код сервера:

import DTOs.Position;
import DTOs.UnitPosition;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.JsonSerialization;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.kryonet.Server;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class Servers extends Listener {

    private final Map<Integer, Position> messages = new HashMap<>();
    private static Server server;

    public static void main(String[] args) throws IOException {
        int port = 27960;
        server = new Server(port, port, new JsonSerialization());
        server.bind(port);

        server.start();

        server.addListener(new Servers());
    }

    @Override
    public void connected(Connection c) {
        messages.forEach((id, data) -> server.sendToTCP(c.getID(), new UnitPosition(c.getID(), data)));
    }

    @Override
    public void received(Connection c, Object object) {
        if (object instanceof Position) {
            Position message = ((Position) object);
            messages.put(c.getID(), message);
            server.sendToAllExceptTCP(c.getID(), new UnitPosition(c.getID(), message));
        }
    }

    @Override
    public void disconnected(Connection c) {
        messages.remove(c.getID());
        server.sendToAllExceptTCP(c.getID(), c.getID());
    }

}

Код клиента:

import com.esotericsoftware.kryonet.Client;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.JsonSerialization;
import com.esotericsoftware.kryonet.Listener;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class MyClient extends Listener {
    private final static int tcpPort = 27960;
    private final static Client client = new Client(tcpPort, tcpPort, new JsonSerialization());
    private final static String ip = "localhost";
    private final Map<Integer, UnitPosition> positionMap = new HashMap<>();
    private final Random random = new Random();
    private Position my;
    private static MyFrame frame;

    public static void main(String[] args) throws IOException {
        client.start();
        client.connect(10000, ip, tcpPort);

        MyClient myClient = new MyClient();
        client.addListener(myClient);
        frame = new MyFrame(myClient);
        myClient.my = new Position(Math.abs(myClient.random.nextInt() % 400),
                Math.abs(myClient.random.nextInt() % 400));
        client.sendTCP(myClient.my);
    }

    @Override
    public void received(Connection connection, Object object) {
        if (object instanceof UnitPosition) {
            UnitPosition now = (UnitPosition) object;
            if(now.getId() != connection.getID()) {
                positionMap.put(now.getId(), now);
                try {
                    frame.repaint();
                } catch (NullPointerException exception) {
                    System.out.println("Repaint throw nullPointer!");
                }
            }
        } else if(object instanceof Integer){
            positionMap.remove(object);
            try {
                frame.repaint();
            } catch (NullPointerException exception) {
                System.out.println("Repaint throw nullPointer!");
            }
        }
    }

    public Position getMy() {
        return my;
    }

    public Map<Integer, UnitPosition> getPositionMap() {
        return positionMap;
    }

    public void send() {
        client.sendTCP(my);
    }
}

Ответы (1 шт):

Автор решения: Алексей Кожемякин

Проблема состояла в том, что класс Position находился в разных пакетах на клиенте и на сервере. При передаче json пакета в переменную class заносится полное имя класса с учётом пакета, поэтому местонахождение передаваемых классов на клиенте и на сервере должно совпадать.

→ Ссылка