แสดงบทความที่มีป้ายกำกับ Serializable แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ Serializable แสดงบทความทั้งหมด

Mismatched serialization UIDs

Caused by: org.omg.CORBA.MARSHAL: Unable to read value from underlying bridge :
Mismatched serialization UIDs :
Source (RepId RMI:com.model.HAHAResult:1335A78CB1E6EDB7:690F13781C0374C1) = 690F13781C0374C1 whereas
Target (RepId RMI:com.model.HAHAResult:359C570FBD100732:584576386E6E2CBD) = 584576386E6E2CBD vmcid: IBM minor code: 896 completed: No


ปัญหาเกิดจาก com.model.HAHAResult ไม่ได้ประกาศ serialVersionUID ทำให้เรียก Object ผ่าน RMI
มีปัญหาฟ้องว่า uid ต้นทางกับ ปลายทางไม่ตรงกัน ดูข้อมูลได้จาก entry เรื่องของ Serializable

วิธีแก้ที่คือ ถ้าสร้าง class แล้ว implements java.io.Serializable ต้องสร้าง serialVersionUID เสมอ
พอเพิ่มแล้ว compile class ใหม่ก็ใช้ได้แล้ว

แต่เนื่องจาก class ตัวนี้ เป็น ejb (แล้วยังไง compile ใหม่ก็เสร็จ) แล้วมีการนำ ejb client ไปใช้ที่ระบบอื่นด้วย
ทำให้ถ้า gen client ใหม่ ก็ต้องส่งให้ระบบอื่นด้วยจะทำยังไงแค่แก้ฝั่ง ejb โดยไม่กระทบ client

เลยคิดว่า งั้นก็ สร้าง serialVersionUID ที่มีค่า uid เหมือนกับ ตัวแปล ที่ client
แต่เราจะรู้ค่า uid ที่อยู่ใน jvm ได้ยังไง
จากที่หาข้อมูลมาที่ http://download.oracle.com/javase/6/docs/platform/serialization/spec/class.html (บอกวิธีคำนวน uid ด้วย)

ทำให้รู้จัก ObjectStreamClass จะมี method getSerialVersionUID


String name = "com.model.HAHAResult";
Class c = Class.forName(name);

ObjectStreamClass oc = ObjectStreamClass.lookup( c );
long uid = oc.getSerialVersionUID();


เราก็จะได้ ค่า uid ของ class ที่ต้องการแล้ว

แต่ทั้งนี้ทั้งนั้น Entry นี้จะไม่เกิด ถ้าสร้าง class แล้ว implements java.io.Serializable ต้องสร้าง serialVersionUID เสมอ

เรื่องของ Serializable

อ่านในกระทู้ ปัญหากับ method setAttribute(), non-serializable (Narisa.com) มีความรู้ดีๆหลายเรื่อง
1. คุณ Siros post:
เนื่อง จากว่า Servlet container อาจจะไม่ได้ handle object ใน session เป็น local object เสมอไป .. เป็นไปได้ว่า เรา deploy server เป็น cluster แล้วให้ server มันทำ session replication (จะได้ทำ fail-over ได้) ... ดังนั้น object จาก session ใน server หนึ่ง อาจจะต้องถูกส่งไป เพื่อ synchronize กับ session ใน server อื่นๆ ด้วย ... นี่เป็นเหตุผลว่าทำไม ถึงต้อง Serializable ครับ
2. คุณ nohc post:
สิ่งที่กำหนดว่า Object นั้นคือตัวเดียวกันในการ De/Serialize คือ attribute serialVersionUID ใน Class นั่นเองครับ ถ้าอย่างนั้น hashCode() กับ equals() ไว้ทำอะไร สองตัวนี้ใช้ในการเปรียบเทียบ Object กับการทำ hash code ครับ เช่น Object ที่ใส่ไว้ใน HashMap ควรจะต้อง implement สอง method นี้ ยังมีอีกตัวครับที่ออกจะคุ้นเคยกันอยู่คือ compareTo(), method นี้จะใช้ใน Comparator หรือการ Sorting เท่านั้นครับ
- serialVersionUID ใช้ใน Serializable
- hashCode(), equals() ใช้ใน Hash
- compareTo() ใช้ใน Comparator
เหตุผล ของการ Serializable ไม่ใช่แค่เรื่องของ Session Replication เท่านั้นน่ะครับ การแปลง Object จะรูปแบบหนึ่งไปยังอีกรูปแบบหนึ่ง หรือเมื่อไรก็ตามที่ JVM ทำการเรียก writeObject() และ readObject() ตัว Object นั้น ๆ ต้องทำการ Serializable เสมอ
เช่นการแปลง Object เป็น file, ส่งผ่าน Object ทาง Network, เก็บ Object ลง Session, เรียก Object ผ่าน RMI เป็นต้นครับ
- ทำไม่แทบไม่เห็นใครใส่ Attribute serialVersionUID ลงใน Class ของเขาเวลา implement Serialzable
เพราะ ว่ากระบวนการของ JVM เวลาเราทำการประกาศ Class โดยการ implement Serializable ตัว JVM เองจะทำการตรวจสอบดูก่อนว่าเรามีการประกาศ Attribute serialVersionUID หรือเปล่า ถ้าไม่มีการประกาศ JVM จะทำการ Generate serialVersionUID ให้เราเองครับ ดังนั้นจึงไม่จะเป็นที่ต้องใส่ serialVersionUID เองใน Class อย่างไรก็ดีทาง SUN ใน strongly recommended ให้ทำการ ใส่ serialVersionUID ลงใน Class ของเรา เนื่องจากว่าในโลกนี้ไม่ได้มีแค่ SUN JVM ไงครับ SUN JVM ทำการ generate serialVersionUID ให้แต่ BEA, IBM, GNU, Microsoft JVM อาจไม่ได้ทำให้เราก็ได้ไงครับ

- แล้ว hashCode() กับ equals() จำเป็นแค่ไหนในการ implement ตัว JVM เองสามารถ generate ให้เหมือน serialVersionUID หรือไม่
คำ ตอบคือจำเป็นครับ และตัว JVM ก็ generate ให้ด้วย ที่บอกว่าจำเป็นเพราะว่า default generator ของ JVM จะทำการ generate hash code โดยเอา memory address ของ Object นั้นมาทำการ generate และ method equals() จะทำการเปรียบเทียบ โดยใช้ address เป็นตัวเปรียบเทียบครับ หมายความว่าทุกครั้งที่เราทำการ allocate memory ให้ Object ตัวใหม่ ก็จะ้ได้ hashCode() คนละตัวกันถึงแม้ว่า Object ของเรานั้นจะมีค่าเดียวกันก็ตาม เพราะฉะนั้นเมื่อไรก็ตามที่เราต้องการ identify Object ของเราโดย value ไม่ใช่ address เราก็ตัอง implement hashCode() กับ equals() เสมอครับ
top