2013-02-27 3 views
1

Я использую Kryonet с Slick2d, чтобы создать java-игру.Slick2D KryoNet апплет

Он отлично работает, когда работает как приложение Java, однако при работе в качестве апплета я получаю следующее сообщение об ошибке:

00:00 INFO: [kryonet] Server opened. 
00:04 DEBUG: [kryonet] Port 9991/TCP connected to: /(ip):55801 
00:04 DEBUG: [kryo] Write: RegisterTCP 
00:04 INFO: [kryonet] Connection 1 connected: /(ip) 
00:04 INFO: [SERVER] Someone has connected. 
00:04 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:192) 
    at com.esotericsoftware.kryonet.Server.run(Server.java:350) 
    at java.lang.Thread.run(Unknown Source) 
Caused by: com.esotericsoftware.kryo.KryoException: Buffer underflow. 
    at com.esotericsoftware.kryo.io.Input.require(Input.java:162) 
    at com.esotericsoftware.kryo.io.Input.readLong(Input.java:621) 
    at com.esotericsoftware.kryo.io.Input.readDouble(Input.java:745) 
    at com.esotericsoftware.kryo.serializers.DefaultSerializers$DoubleSerializer.read(DefaultSerializers.java:141) 
    at com.esotericsoftware.kryo.serializers.DefaultSerializers$DoubleSerializer.read(DefaultSerializers.java:131) 
    at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:735) 
    at com.esotericsoftware.kryonet.KryoSerialization.read(KryoSerialization.java:57) 
    at com.esotericsoftware.kryonet.TcpConnection.readObject(TcpConnection.java:139) 
    ... 3 more 
00:04 INFO: [SERVER] Someone has disconnected. 
00:04 INFO: [kryonet] Connection 1 disconnected. 

Сервер работает локально как работоспособная банка и апплет клиента в HTML-файле локально, а также работает xampp для работы в качестве веб-сервера.

Я пробовал разные сериализаторы, размеры буфера и отправка только одного String/Booleans и т. Д., Это просто не похоже на что-либо. Клиент прекрасно подключается к серверу, однако, когда дело доходит до отправки каких-либо пакетов, я получаю вышеуказанную ошибку, независимо от того, какой пакет отправлен.

Любая помощь/совет были бы оценены по достоинству - я был в тупике на некоторое время! Спасибо

ответ

0

Я считаю, что у меня такая же проблема или, по крайней мере, такая же. Я использую Kryonet для сервера и клиента. Клиент - это апплет, и когда я запускаю его через Eclipse's Applet Viewer, он отлично работает. Когда я запускаю его через веб-сервер, я получаю подобные ошибки. Клиент и сервер соединяются, сервер принимает пакеты клиента, но клиент дает ошибку, где бы он ни пытался десериализовать. Я обнаружил, что виноваты разрешения апплета. Если вы измените разрешения Applet Viewer (если вы используете Eclipse), чтобы они были такими же, как на веб-странице, вы получите те же ошибки. Преимущество состоит в том, что вы можете отладить проблему.

Чтобы изменить разрешения для Eclipse: Перейдите в папку проекта \ bin \ и откройте «java.policy.applet». Внутри вы должны иметь:

grant { 
    permission java.security.AllPermission; 
}; 

Изменить что:

grant { 
    permission java.io.FilePermission "<<ALL FILES>>", "read, write, execute, delete"; 
    permission java.net.SocketPermission "*", "accept, connect, listen, resolve"; 
    permission java.util.PropertyPermission "*", "read, write"; 
    permission java.lang.RuntimePermission "*"; 
    permission java.awt.AWTPermission "showWindowWithoutWarningBanner"; 
}; 

С этим изменением я имел такое же поведение для апплета просмотра, как с помощью встроенного апплета. Это не полное решение, но может помочь найти причину проблемы.

Обновление: Я нашел, в чем проблема в моем случае. Проблема заключается в использовании FieldSerializer и других сериализаторов. Когда класс зарегистрирован, FieldSerializer просматривает его поля и устанавливает, чтобы все они были доступны. Эта операция не разрешена для апплета. Результатом является неправильная регистрация и сериализация/десериализация. Я нашел 2 обходных пути:

1) Использование другого сериализатора. По умолчанию один является FieldSerializer и может быть изменено с помощью

public void setDefaultSerializer (Class<? extends Serializer> serializer) 

другой вариант установить сериалайзер при регистрации каждого класса. Не используйте сериализаторы на основе FieldSerializer.

2) Попытайтесь исправить полевой сериализатор. То, что я делаю, не совсем правильно, но оно работает в моем случае. Мы сделаем FieldSerializer продолжением регистрации, если установка доступности вызывает исключение. Еще одна вещь, которую нам нужно сделать, - установить все поля классов, которые мы регистрируем для публики. Чтобы изменить FieldSerializer, вам понадобятся источники Kryo. Перейдите в FieldSerializer.java, mething rebuildCachedFields().Вы можете найти следующий код там:

if (!field.isAccessible()) { 
     if (!setFieldsAsAccessible) continue; 
     try { 
      field.setAccessible(true); 
     } catch (AccessControlException ex) { 
      continue; 
     } 
    } 

Вам нужно изменить, что:

if (!field.isAccessible()) { 
     if (setFieldsAsAccessible) 
     try { 
      field.setAccessible(true); 
     } catch (AccessControlException ex) { 
     } 
    } 

Другое дело, что нужно изменить все из зарегистрированных классов имеют только открытые поля.

0

У меня есть аналогичная проблема в конструкции градации. Возможно, вам просто нужно увеличить память (кучу или PermSize) для апплета JVM

Смежные вопросы