2008-09-30 5 views
20

jdk 1.5와 1.6 (Java 6) 객체 직렬화 (biderctional communication)를 혼합하는 것이 안전한지 궁금합니다. 나는이 질문에 관하여 태양에서 명백한 계산서를 찾았지만 성공하지 못했다. 그래서 기술적 타당성 외에도 문제와 관련된 "공식적인"진술을 찾고 있습니다.Java 객체 직렬화가 1.5와 1.6 사이에서 호환 가능합니까

+0

나는 이것이 이전 질문이지만 미래 개발자를위한 것임을 알고 있습니다. 몇 년 동안 POJO를 사용하는 클라이언트, 서버가있는 제품을 위해 광범위하게 사용해온 것입니다. 버전 간 직렬화 된 객체는 문제없이 작동했습니다. 유일한 문제는 직렬화 규칙을 위반했을 때입니다. 예를 들어, 변수의 유형을 변경하지 마십시오. –

답변

2

Java 1.5 프로그램의 ObjectOutputStream을 사용하여 파일에 작성된 직렬화 된 객체로 테스트 한 후 Java 1.6 프로그램에서 ObjectInputStream을 사용하여 읽기를 실행하면 문제없이 작동한다고 말할 수 있습니다.

+0

아니야. 한 클래스에 대해 테스트했습니다. 1 개의 삼키기는 여름을 만들지 않습니다. – EJP

16

직렬화 메커니즘 자체는 변경되지 않았습니다. 개별 클래스의 경우 특정 클래스에 따라 다릅니다. 클래스에 serialVersionUID 필드가 있으면 직렬화 호환성을 나타냅니다. 같은

뭔가 :이 변경되지 않은 경우

private static final long serialVersionUID = 8683452581122892189L; 

는, 직렬화 된 버전이 호환됩니다. JDK 클래스의 경우 이것은 보장되지만 물론 변경을 수행 한 후에 serialVersionUID를 업데이트하는 것을 잊어 버릴 수도 있습니다.

JDK 클래스가 호환성을 보증하지 않는 경우는, 일반적으로 Javadoc로 언급되고 있습니다.

경고 :이 클래스의 직렬화 된 오브젝트는, 향후의 Swing 릴리스

2

나는 빨리이 클래스를 변경하지만 serialVersionUID의를 변경하는을 잊지하는 것이 가능하다는 것을 추가 할 수와 호환되지 않습니다. "클래스가 serialVersionUID를 정의하고 이것이 변경되지 않으면 클래스는 호환 가능함을 보장합니다." 대신, 동일한 serialVersionUID를 갖는 것은 API가 이전 버전과의 호환성을 약속하는 방식입니다.

+0

질문이 jdk 클래스에 관한 것으로 가정하고 serialVersionUID가 정확하다고 가정합니다 ... – Tom

+0

충분히 공정 : JDK 업그레이드가 Serializable을 엉망으로 만들면 큰 소년 JDK (예 : Sun, BEA, IBM 등)의 클라이언트가 엉망이됩니다.) 피 묻은 살인을 비명 지어야한다 (그리고 나는 가지고있다). 틀림없이 그것이 단지 JDK 클래스에 관한 것인지 아닌지는 의문의 여지가있다. – Alan

2

달리 언급하지 않는 한, 이것은 2 진 호환성의 일부 여야합니다. 스윙 클래스는 버전간에 명시 적으로 호환되지 않습니다. 다른 클래스에 문제가있는 경우 bugs.sun.com에 버그를 신고하십시오.

+0

이진 호환성은 공용 및 보호 된 인터페이스에 대한 것이며 직렬화 호환성은 일반적으로 개인 필드를 처리합니다. 그 중 하나가 다른 것을 의미한다고 확신합니까? – Tom

+0

기술적으로 JLS의 13 장에 정의 된대로 이진 호환성이 없습니다. 그러나 달리 명시하지 않는 한 Java 버전 간에는 직렬화에 대한 2 진 호환성이 필요합니다. 문제가 있으면 버그를보고하십시오. –

2

Java Object Serialization Specification을 읽으셨습니까? versioning에 대한 주제가 있습니다. 클래스 구현자를위한 기사도 있습니다 : Discover the secrets of the Java Serialization API. Java의 각 릴리스에는 compatibility notes이 수반됩니다. 직렬화에 자바 6 스펙에서

:


목표입니다에 :

    :에 의해 서로 다른 가상 머신에서 작동하는 클래스의 다른 버전 사이

    • 지원 양방향 통신
    • JavaTM 클래스가 동일한 클래스의 이전 버전에서 작성된 스트림을 읽을 수 있도록하는 메커니즘을 정의합니다.
    • JavaTM 클래스가 동일한 클래스의 이전 버전에서 읽을 스트림을 쓸 수있게하는 메커니즘을 정의합니다.
  • 지속성 및 RMI의 기본 직렬화를 제공하십시오.
  • RMI에서 직렬화를 사용할 수 있도록 간단한 수행으로 성능을 향상시키고 간단한 스트림을 생성합니다.
  • 스트림을 쓰는 데 사용 된 정확한 클래스와 일치하는 클래스를 식별하고로드 할 수 있어야합니다.
  • 비 버전 관리 클래스의 경우 오버 헤드를 낮게 유지하십시오.
  • 스트림에 저장된 오브젝트에 특정한 메소드를 호출 할 필요없이 스트림을 탐색 할 수있는 스트림 형식을 사용하십시오.

3

1.5 직렬화 메커니즘 1.6 호환된다. 따라서 1.5와 1.6 컨텍스트에서 컴파일/실행되는 동일한 코드가 직렬화 된 객체를 교환 할 수 있습니다. 2 개의 VM 인스턴스가 클래스의 동일/호환성 버젼 (serialVersionUID 필드로 가리킬 수있는 것)을 가지는지 어떤지는, JDK 버젼과 관련되지 않은 다른 질문입니다.

하나의 직렬화 가능 Foo.java가 있고 이것을 1.5 및 1.6 JDK/VM에서 사용하는 경우 하나의 V로 작성된 Foo의 직렬화 된 인스턴스. 다른쪽에 의해 deserialize 될 수 있습니다.

0

Java Beans 사양에는 강력한 하위 호환성을 허용하는 버전 독립적 인 직렬화 방법이 자세히 설명되어 있습니다. 또한 "직렬화 된"형식으로 읽을 수 있습니다. 사실 직렬화 된 객체는 메커니즘을 사용하여 매우 쉽게 생성 할 수 있습니다.

XMLEncoderXMLDecoder 클래스에 대한 설명서를 찾아보십시오.

필자는 와이어를 통해 객체를 전달할 때이 기능을 사용하지 않겠지 만 (고성능이 필요한 경우에도 직렬화를 사용하지 않지만) 영구 객체 저장에는 매우 중요합니다.

0

자바 1.5와 1.6을 섞어도 안전하지 않습니다. 예를 들어, 나는 자바 1.5 개체를 파일에 직렬화하고 자바 1.6에서 열어 보았지만 아래 오류가 발생했습니다.

java.io.InvalidClassException : javax.swing.JComponent; 로컬 클래스 호환 : 스트림에서의 serialVersionUID classdesc = 7백91경7천9백68조3천4백48억6천80만2백89, java.io.ObjectInputStream의에 java.io.ObjectInputStream.readNonProxyDesc (알 소스)에 java.io.ObjectStreamClass.initNonProxy (알 소스) 현지 클래스의 serialVersionUID = -1030230214076481435 . 자바 .io에서 java.io.ObjectInputStream.readNonProxyDesc (알 소스)에 java.io.ObjectInputStream.readClassDesc (알 소스)에 java.io.ObjectInputStream.readNonProxyDesc (알 소스)에 readClassDesc (알 소스) ObjectInputStream.readClassDesc (알 수없는 소스) at java.io.ObjectInputStream.readOrdinaryObject (알 수없는 소스) at java.io.ObjectInputStream.readObject0 (알 수없는 소스)(알 수없는 소스) at java.io.ObjectInputStream.readObject0 (알 수없는 소스) at java.io.ObjectInputStream.defaultReadFields (알 수없는 소스) at java.io.ObjectInputStream.readSerialData (알 수없는 소스) java.io.ObjectInputStream.readSerialData에서 java.io.ObjectInputStream.defaultReadFields (알 수없는 소스) 에서 java.io.ObjectInputStream.readObject0 (알 수없는 소스) 에서 java.io.ObjectInputStream.readOrdinaryObject (알 수없는 소스) 에서 소스) (알 수없는 소스) at java.io.ObjectInputStream.readOrdinaryObject (알 수없는 소스) at java.io.ObjectInputStream.readObject0 (알 수없는 소스) at java.io.ObjectInputStream.readArray (알 수없는 소스) at java.io.ObjectInputStream.readObject0 (알 수없는 소스) at java.io.ObjectInputStream.defaultReadFields (알 수없는 소스) at java.io.ObjectInputStream.readSerialData (알 수없는 소스) at java.io. ObjectInputStream.readOrdinaryObject (알 수없는 소스) at java.io.ObjectInputStream.readObject0 (알 수없는 소스) at java.io.ObjectInputStream.readObject (알 수없는 소스)

+0

그 자체의 Javadoc에 명시되어있는 것처럼, * 특정 클래스에 대해서는 * 안전하지 않습니다. 당신은 우주의 법칙을 우연히 발견하지 못했습니다. – EJP

관련 문제