Java-Gaming.org Hi !
Featured games (90)
games approved by the League of Dukes
Games in Showcase (707)
Games in Android Showcase (206)
games submitted by our members
Games in WIP (781)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Java getting serializer error with kryonet and slick2d?  (Read 3210 times)
0 Members and 1 Guest are viewing this topic.
Offline rokyslash

Junior Newbie





« Posted 2016-12-02 03:01:13 »

I am trying to execute this server code.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
package server;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import org.apache.logging.log4j.message.Message;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryonet.Server;
import com.esotericsoftware.minlog.Log;

import Client.PlayerChar;
import NetworkClasses.LoginRequest;
import NetworkClasses.LoginResponse;

public class MainServer {

    private int tcpPort;
    private int udpPort;
    public static Server server;
    private Kryo kryo;

    static JFrame jFrame;
    static JTextArea jTextArea;
    static MainServerListener listener = new MainServerListener();

    public MainServer(int tcpPort, int udpPort) {
        this.tcpPort = tcpPort;
        this.udpPort = udpPort;
        server = new Server();

        kryo = server.getKryo();
        registerKryoClasses();
    }

    public void startServer() {
        Log.info("Starting Server");
        jTextArea.append("Starting Server...");
        jTextArea.append("\n");
        server.start();
        try {
            server.bind(tcpPort, udpPort);
            server.addListener(listener);
            jTextArea.append("Server online! \n");
            jTextArea.append("----------------------------");
            jTextArea.append("\n");
            update();
        } catch (IOException e) {
            Log.info("Port already used");
            jTextArea.append("Port already in use");
            jTextArea.append("\n");
            e.printStackTrace();
        }
    }

    // Try changing this to non staic and see where this effects our game
    public static void stopServer() {
        Log.info("Server stopped");
        jTextArea.append("Server stopped.");
        jTextArea.append("\n");
        server.stop();
    }

    public void update() {
        while (true) {

        }
    }

    private void registerKryoClasses() {
        kryo.register(LoginRequest.class);
        kryo.register(LoginResponse.class);
        kryo.register(Message.class);
        kryo.register(PlayerChar.class);
        kryo.register(org.newdawn.slick.geom.Rectangle.class);
        kryo.register(float[].class);
        kryo.register(NetworkClasses.PacketUpdateX.class);
        kryo.register(NetworkClasses.PacketUpdateY.class);
        kryo.register(NetworkClasses.PacketAddPlayer.class);
        kryo.register(NetworkClasses.PacketRemovePlayer.class);

    }

    public static void createServerInterface() {
        jFrame = new JFrame("GameServerInterface");
        jTextArea = new JTextArea();
        jTextArea.append("\n");
        jTextArea.setLineWrap(true);
        jTextArea.setEditable(false);

        jFrame.add(jTextArea);
        jFrame.setSize(400, 600);
        jFrame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                int i = JOptionPane.showConfirmDialog(null, "You want to shut down the server?");
                if(i == 0) {
                    stopServer();
                    System.exit(0); // successful exit
                }
            }
        });

        JScrollPane scrollPane = new JScrollPane(jTextArea);
        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        jFrame.add(scrollPane);
    }

    public static void main(String args[]) {
        Log.set(Log.LEVEL_INFO);

        MainServer main = new MainServer(55555, 55556);
        createServerInterface();
        main.startServer();
    }

} // end total class


Full source code is at https://github.com/schepan1/ms/tree/master/src/main/java. However when I try to run this server, I keep getting this error/exception and there are no solutions online at all. How can I solve this?

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
Exception in thread "main" java.lang.IllegalArgumentException: Unable to create serializer "com.esotericsoftware.kryo.serializers.FieldSerializer" for class: com.esotericsoftware.kryonet.FrameworkMessage$RegisterTCP
    at com.esotericsoftware.kryo.Kryo.newSerializer(Kryo.java:337)
    at com.esotericsoftware.kryo.Kryo.newDefaultSerializer(Kryo.java:316)
    at com.esotericsoftware.kryo.Kryo.getDefaultSerializer(Kryo.java:309)
    at com.esotericsoftware.kryo.Kryo.register(Kryo.java:353)
    at com.esotericsoftware.kryonet.KryoSerialization.<init>(KryoSerialization.java:33)
    at com.esotericsoftware.kryonet.KryoSerialization.<init>(KryoSerialization.java:25)
    at com.esotericsoftware.kryonet.Server.<init>(Server.java:91)
    at com.esotericsoftware.kryonet.Server.<init>(Server.java:73)
    at server.MainServer.<init>(MainServer.java:36)
    at server.MainServer.main(MainServer.java:118)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at com.esotericsoftware.kryo.Kryo.newSerializer(Kryo.java:324)
    ... 9 more
Caused by: java.lang.IncompatibleClassChangeError: Found interface org.objectweb.asm.MethodVisitor, but class was expected
    at com.esotericsoftware.reflectasm.FieldAccess.insertConstructor(FieldAccess.java:144)
    at com.esotericsoftware.reflectasm.FieldAccess.get(FieldAccess.java:109)
    at com.esotericsoftware.kryo.serializers.FieldSerializer.rebuildCachedFields(FieldSerializer.java:104)
    at com.esotericsoftware.kryo.serializers.FieldSerializer.<init>(FieldSerializer.java:50)
    ... 14 more
Offline Stranger

Senior Devvie


Medals: 15
Exp: 10 years


I STILL SO FAR HATE DOTA !


« Reply #1 - Posted 2016-12-02 05:54:02 »

Hi.

1  
Caused by: java.lang.IncompatibleClassChangeError: Found interface org.objectweb.asm.MethodVisitor, but class was expected


I guess it's happened due the fact that your code tries to create instance of interface MethodVisitor...

I think you have to create your own serializer for the class that's on the start of the last stack trace.

EDIT: Btw, as I see you use Kryonet 2.22-rc1, but AFAIK Kryonet 4 is released.


Sorry, I've mistaken Kryonet for Kryo.  Smiley

Anton
Offline KaiHH

JGO Kernel


Medals: 374



« Reply #2 - Posted 2016-12-02 08:13:15 »

In your case, the IncompatibleClassChangeError likely happens because the caller - in this case Kryo's reflectasm.FieldAccess class - expects the callee - in this case asm's MethodVisitor - to be something which it is not.
ASM changed the "kind" of all visitor classes between version 4 and 5 from interfaces to classes.
Therefore, everyone who wants to call a method on a class must use a different JVM bytecode opcode (INVOKEVIRTUAL) than when calling a method on an interface (INVOKEINTERFACE). So, in this case, Kryo expects the asm.MethodVisitor to be a class (because it calls INVOKEVIRTUAL) whereas in reality at runtime it is an interface, so the JVM expects and enforces the caller to use INVOKEINTERFACE instead. Which kryo did not do. And therefore: boom!

Another possible cause is that Kryo's reflectasm is declaring a class which extends (as in extend from a class) ASM's MethodVisitor, which it thought would be a class, but in reality it is an interface.

Yet another possible cause is what Stranger said, that Kryo's reflectasm code is trying to use the NEW keyword/opcode to instantiate the MethodVisitor type which it thinks is a class, but in reality it is an interface.

The root cause of this is that you are using an incompatible ASM library version (likely 5, which is using classes for the visitor classes, instead of interfaces) for your Kryo version.
Steps in order to fix it: Use compatible Kryo and ASM versions.
Pages: [1]
  ignore  |  Print  
 
 

 
Galdo (237 views)
2017-01-12 13:44:09

Archive (405 views)
2017-01-02 05:31:41

0AndrewShepherd0 (864 views)
2016-12-16 03:58:39

0AndrewShepherd0 (801 views)
2016-12-15 21:50:57

Lunch (938 views)
2016-12-06 16:01:40

ral0r2 (1168 views)
2016-11-23 16:08:26

ClaasJG (1270 views)
2016-11-10 17:36:32

CoffeeChemist (1305 views)
2016-11-05 00:46:53

jay4842 (1390 views)
2016-11-01 19:04:52

theagentd (1207 views)
2016-10-24 17:51:53
List of Learning Resources
by elect
2016-09-09 09:47:55

List of Learning Resources
by elect
2016-09-08 09:47:20

List of Learning Resources
by elect
2016-09-08 09:46:51

List of Learning Resources
by elect
2016-09-08 09:46:27

List of Learning Resources
by elect
2016-09-08 09:45:41

List of Learning Resources
by elect
2016-09-08 08:39:20

List of Learning Resources
by elect
2016-09-08 08:38:19

Rendering resources
by Roquen
2016-08-08 05:55:21
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!