2013-02-27 72 views
1

我使用Kryonet和Slick2d來製作java遊戲。Slick2D KryoNet Applet

作爲小我碰到下面的錯誤運行時,但是作爲一個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文件中運行的JAR和客戶端小程序在本地運行本地運行,它運行xampp作爲Web服務器。

我試過不同的序列化程序,緩衝區大小和發送只是單個字符串/布爾等,它似乎並不喜歡任何東西。 客戶端連接到服務器很好,但是當發送任何數據包時,無論發送什麼數據包,我都會收到上述錯誤。

任何幫助/建議將非常感激 - 我一直在這一難以置信! 謝謝

回答

0

我相信我有同樣的問題或至少類似的問題。我正在使用Kryonet作爲服務器和客戶端。客戶端是一個小程序,當我通過Eclipse的Applet Viewer運行它時,它工作正常。當我運行它通過Web服務器時,我得到類似的錯誤。客戶端和服務器連接,服務器接收客戶端的數據包,但客戶端在嘗試任何反序列化時都會給出錯誤。我發現applet的權限是責任。如果您更改Applet查看器的權限(如果您使用的是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"; 
}; 

有了這個改變我對Applet查看相同的行爲與嵌入的小程序。這不是一個完整的解決方案,但可以幫助找出問題的原因。

更新: 我發現我的情況是什麼問題。問題出在FieldSerializer和其他使用它的序列化程序中。當一個類被註冊時,FieldSerializer會遍歷它的字段並設置它們全部是可訪問的。該操作對於小程序是不允許的。結果是錯誤的註冊和序列化/反序列化。我找到了2個解決方法:

1)使用另一個序列化程序。默認的是一個FieldSerializer並且可以使用

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

另一個選擇是設置串行器登記每個類時被改變。不要使用基於FieldSerializer的序列化程序。

2)嘗試修復FieldSerializer。我所做的並不完全正確,但是對我來說很有用。如果設置可訪問性導致異常,我們將使FieldSerializer繼續註冊。我們需要做的另一件事是將我們註冊的類的所有字段設置爲公開。要更改FieldSerializer,您需要Kryo源。轉到FieldSerializer.java,編譯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

我有類似的問題,在gradle構建。可能你只需要增加內存(堆或PermSize)爲小程序JVM