1

記録されたデータベースから DDS データを再生しており、データをリッスンする Java プログラムを作成しました。ほとんどのメッセージを正常に受信できますが、次のような一貫した例外がいくつか発生します。

PRESCstReaderCollator_storeSampleData:!deserialize
java.lang.IllegalStateException: not enough available space in CDR buffer
    at com.rti.dds.cdr.CdrBuffer.checkSize(Unknown Source)
    at com.rti.dds.cdr.CdrInputStream.readShortFromBigEndian(Unknown Source)
    at com.rti.dds.cdr.CdrInputStream.deserializeAndSetCdrEncapsulation(Unknown Source)
    at <my type>.deserialize_key_sample(<my type>TypeSupport.java:456)
    at com.rti.dds.topic.TypeSupportImpl.deserialize_key(Unknown Source)
    at com.rti.dds.topic.TypeSupportImpl.deserialize_keyI(Unknown Source)

誰かがこれを見たことがありますか、またはこれを引き起こす原因を知っていますか?

編集: また、rtireplay を使用して、再生されたデータベースを介して現在 DDS データを受信して​​いることも追加する必要があります。使用するように与えられた新しいリプレイ構成をドロップした後、このエラーを受け取り始めました。おそらく問題は、どのリプレイ構成設定がこのようなことに影響を与える可能性があるかということです。リクエストに応じて、難読化された @key フィールドを IDL に投稿しています

struct MyType{
    Key1 key1; //@key
    Key2 key2; //@key
    ...
}

struct Key1 {
    long long m; //@key
    long long l; //@key
    ...
}

//key members only
struct Key2 {
    Key1 a; //@key
    ...
}
4

1 に答える 1

0

スタック トレースは若干異なりますが、次の出力で同様のケースを再現できました。

Exception in thread "Thread-5" java.lang.IllegalArgumentException: string length (200)
exceeds maximum (10)
    at com.rti.dds.cdr.CdrInputStream.readString(CdrInputStream.java:364)
    at stringStructTypeSupport.deserialize_key_sample(stringStructTypeSupport.java:411)
    at com.rti.dds.topic.TypeSupportImpl.deserialize_key(TypeSupportImpl.java:1027)
    at com.rti.dds.topic.TypeSupportImpl.deserialize_keyI(TypeSupportImpl.java:965)
PRESCstReaderCollator_storeSampleData:!deserialize

エラーメッセージがもう少し冗長な5.1.0を使用していることに注意してください。

これが発生した条件は次のとおりです。

  • DataReader は、異なるキー定義を持つ型、より正確には、DataWriter が生成していたものとは異なるサイズのキー定義を期待していました。私の場合、DataWriter は 200 文字の文字列キー属性を生成しましたが、DataReader は 10 文字以内の文字列を想定していました。
  • DataWriter の QoS 設定はprotocol.serialize_key_with_disposetrue に設定されていました。これは、この矛盾したキーが (キー ハッシュではなく) 実際に使用され、dispose()
  • 5.1.0 以降を使用している場合: パブリッシング パティシパントの QoS 設定は でresource_limits.type_code_max_serialized_lengthあり、resource_limits.type_object_max_serialized_length両方とも 0 に設定されています。これにより、タイプ情報の通信が回避されるため、定義の不一致が検出されなくなります。古いバージョンでは、resource_limits がゼロ以外に設定されていたとしても、そもそも型の一貫性をチェックしていませんでした。
  • インスタンスがdispose()dになった瞬間にエラーが発生しました

特に一般的に変更されることはなく、この関数がスタック トレースに表示されるprotocol.serialize_key_with_dispose唯一の理由のようです。deserialize_key構成を確認rtireplayして、この特定の設定が に設定されてtrueいることがわかった場合は、ここで説明されているシナリオが該当する可能性が非常に高くなります。

このserialize_key_with_dispose設定は、キー値に対して受信した最初のサンプルがたまたまdispose. これは、インスタンスがまだ認識されていないことを意味します。通常、実際のキー値は dispose では伝達されませんが、ハッシュされたキーのみが伝達されます。これは、破棄が意図されているインスタンスを特定するには不十分な場合があります。このポリシーを true に設定すると、dispose で完全なキー値が伝達されます。に関連していpropagate_dispose_of_unregistered_instancesます。詳細については、 Connext ユーザーズ マニュアルのセクション6.5.3.5 Disposed-Instance Notificationsを使用したシリアル化されたキーの伝達を参照してください。

于 2014-06-24T21:14:00.970 に答える