2017-05-14 10 views
-2

내 스파크 작업 중 하나에 오류가 아래 얻고 있었다 -스파크 - 작업하지 직렬화 : java.io.NotSerializableException : java.lang.reflect.Field의

작업하지 직렬화 : java.io.NotSerializableException : java.lang.reflect.Field의

은 내가 메모리에서 java.lang.reflect.Field의 배열을 유지하는 사용 된 폐쇄 중 하나의 클래스를 한 것을 깨달았다. java.lang.reflect.Field는 java.io.Serializable을 구현하지 않으므로 Spark에서 직렬화 할 수 없으므로 오류가 발생합니다. 이 오류를 어떻게 해결할 수 있습니까? Field를 사용할 수 없습니다.

  1. 각 실행 프로그램에서 클래스의 새 인스턴스를 작성하여 직렬화되지 않도록하십시오. 나는 https://www.nicolaferraro.me/2016/02/22/using-non-serializable-objects-in-apache-spark/을 사용했는데 하나의 객체 유형에서는 작동하지만 2에서는 작동하지 않는 것처럼 보였다.
  2. Field를 사용하는 클래스에 Kryo 시리얼 라이저를 사용하십시오. Kryo는 java.io.Serializable을 구현하지 않는 클래스에서 작동합니까?
  3. 방송 변수 사용 - 확실하지 않습니다. 브로드 캐스트 변수는 직렬화 가능해야합니까?

개체가 실제로 어떤 이유로 든 직렬화 될 수없는 경우이 NotSerializableException을 해결하는 다른 방법은 무엇입니까?

+0

코드를 제공 할 수 있습니까? –

+0

왜 처음부터 필드를 직렬화 하시겠습니까? 수신단에서 재구성 할 수 있습니다. – EJP

+0

@EJP 그게 문제를 해결하기위한 것이지만, 코드를 리팩터링하고 디자인을 변경하여 클래스에서 Field를 제거해야했습니다. 나는 진정으로 무언가가 직렬화되지 않고 코드에서 제거 될 수 없을 때 문제를 해결할 다른 방법이 있는지 알아 내고 싶었다. –

답변

0

필드를 사용할 수 없습니까?

코드를 이해하지 않고 해당 코드를 이해하지 못하면 답변을 드릴 수 없습니다. (분명히!)

하지만 그건 잘못된 질문 일 것입니다. 질문해야 할 것은 아마도 Field 개체를 직렬화하는 것을 피할 수 있는지 여부입니다. 그 대답은 '예'입니다.

  • 필드를 transient으로 표시 할 수 있습니다. 즉, 그들은 연재되지 않을 것입니다. Field 참조가 캐쉬 된 정보 일 경우, 캐쉬 된 정보를 찾아서 다시 캐싱하십시오 .... 필요한 경우 참조하십시오.

  • Field 필드가 속한 클래스에 사용자 지정 serialization 메서드를 추가합니다. 이것들은 필드 명/서명/무엇이든 문자열 데이터를 직렬화 할 수 있고, 데이터가 직렬화 될 때 Class API를 통해 다시 해결하려고 시도 할 수 있습니다. 결과적으로 비 직렬화 할 컨텍스트에서 해당하는Field 개체를 찾으려고합니다.


나는 의심이 Kryo 또는 방송 변수 (그들이 무엇이든). Field은 전송할 수없는 JVM 상태 (클래스 ID)에 의존하기 때문에 근본적으로 비 직렬화 가능합니다.

응용 프로그램에서 이러한 개체를 사용하는 방식에 따라 직렬화를 완전히 피할 수있는 구성표가 작동 할 수 있습니다.


나는 클래스가 진정으로 직렬화하지 못할 때 NotSerializableException 해결에 입력 찾고 있었다.

글쎄, 어떤 방법 으로든 개체를 직렬화 할 수 없다면 어떻게해야하는지 묻습니다. 예 : 사용자 지정 직렬화 메서드가 작동하지 않고 Kryo가 작동하지 않으며 다른 방법이 작동하지 않습니다. (사용자 지정 직렬화 또는 Kryo가 작동하지 않으면 아무 것도 작동하지 않습니다.)

개체 직렬화 옵션이 하나도 없으면 수행 할 수있는 작업이 하나뿐입니다. 그것을 직렬화하지 마십시오.

그리고 이것이 진정한 경우 인 몇 가지 클래스가 있습니다. 예 : thread 및 많은 Swing 및 AWT 클래스는 근본적으로 비 직렬화 가능합니다.

+0

클래스를 진정으로 직렬화 할 수 없을 때 java.lang.reflect.Field를 제거하여 내 프로그램에서 제거하여 코드를 붙여 넣지 않은 이유가 무엇인지에 대해 NotSerializableException을 해결할 수있는 인풋을 찾고있었습니다. 나는 Field를 사용하지 않고 String 대신 fieldName을 사용하기 시작했다. 나중에 Field는 object.getClass(). getDeclaredField (<>)를 사용하여 재구성되었습니다. 실제 작업이 실행될 때 필드를 더 빨리 캐시하기 위해 캐시했습니다. Field는 캐시 된 것일 수 있고 여러 번 사용할 수있는 정적 데이터입니다. –