生成的枚举类和建造者投掷NPE,因为枚举值为null

发布于 2025-02-04 13:29:14 字数 4710 浏览 4 评论 0原文

我很困惑。我得到了NPE,并将其追溯到一个建筑商类,似乎认为枚举价值是无效的。

return draftsClient
    .getCreativeDrafts(
        GetCreativeDraftsRequest.newBuilder()
            .setCreativeDraftId("18b3c829-ec3f-4e25-9d74-8b311d4d0cff")
            .setLimit(3)
            .setOffset(0)
            .setSortType(SortType.newBuilder().setType(Type.UPDATED))
            .setSortDirection(
                SortDirection.newBuilder().setType(SortDirection.Type.DESC).build())
            .build()).toCompletableFuture().join();

建筑商是由Protobuf生成的;这是相关的作品 -

    public GetCreativeDraftsRequest.Builder setSortDirection(SortDirection value) {
      if (this.sortDirectionBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }

        this.sortDirection_ = value;
        this.onChanged();
      } else {
        this.sortDirectionBuilder_.setMessage(value);
      }

      return this;
    }

正在查看sortDirection.type.desc在调试器中的值

我 。

​-

  public static enum Type implements ProtocolMessageEnum {
    UNSET(0),
    DESC(1),
    ASC(2),
    UNRECOGNIZED(-1);

    public static final int UNSET_VALUE = 0;
    public static final int DESC_VALUE = 1;
    public static final int ASC_VALUE = 2;
    private static final EnumLiteMap<SortDirection.Type> internalValueMap = new EnumLiteMap<SortDirection.Type>() {
      public SortDirection.Type findValueByNumber(int number) {
        return SortDirection.Type.forNumber(number);
      }
    };
    private static final SortDirection.Type[] VALUES = values();
    private final int value;

    public final int getNumber() {
      if (this == UNRECOGNIZED) {
        throw new IllegalArgumentException("Can't get the number of an unknown enum value.");
      } else {
        return this.value;
      }
    }

    /** @deprecated */
    @Deprecated
    public static SortDirection.Type valueOf(int value) {
      return forNumber(value);
    }

    public static SortDirection.Type forNumber(int value) {
      switch(value) {
      case 0:
        return UNSET;
      case 1:
        return DESC;
      case 2:
        return ASC;
      default:
        return null;
      }
    }

    public static EnumLiteMap<SortDirection.Type> internalGetValueMap() {
      return internalValueMap;
    }

    public final EnumValueDescriptor getValueDescriptor() {
      return (EnumValueDescriptor)getDescriptor().getValues().get(this.ordinal());
    }

    public final EnumDescriptor getDescriptorForType() {
      return getDescriptor();
    }

    public static final EnumDescriptor getDescriptor() {
      return (EnumDescriptor)SortDirection.getDescriptor().getEnumTypes().get(0);
    }

    public static SortDirection.Type valueOf(EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new IllegalArgumentException("EnumValueDescriptor is not for this type.");
      } else {
        return desc.getIndex() == -1 ? UNRECOGNIZED : VALUES[desc.getIndex()];
      }
    }

    private Type(int value) {
      this.value = value;
    }
  }

奇怪的是,如果这样做,它可以工作 -

SortDirection.newBuilder().setTypeValue(1).build()

我已经使用Protobufs已有几年了,并且从未遇到这个问题。这里可能会发生什么?


编辑

以下是枚举的原始:

syntax = "proto3";

package com.mycompany.ads.adstudiodrafts;

import "google/protobuf/timestamp.proto";

option java_outer_classname = "ModelProto";
option java_multiple_files = true;
option java_package = "com.mycompany.ads.adstudiodrafts.proto";

message Paging {
  int32 limit = 1;
  int32 total = 2;
  int32 offset = 3;
  SortDirection sortDirection = 4;
  SortType sortType = 5;
}

message SortDirection {
  enum Type {
    UNSET = 0;
    DESC = 1;
    ASC = 2;
  }
  Type type = 1;
}

message SortType {
  enum Type {
    UNSET = 0;
    CREATED = 1;
    UPDATED = 2;
  }
  Type type = 1;
}

这是端点的原始片段:

message GetCreativeDraftsRequest {
  string iamDomain = 1;
  int32 limit = 2;
  int32 offset = 3;
  SortDirection sortDirection = 4;
  SortType sortType = 5;
  DraftStatus status = 6;
  string searchWord = 7;
  oneof searchCriteria {
    string hierarchyDraftId = 8;
    string csCampaignId = 9;
    string csFlightId = 10;
    string campaignDraftId = 11;
    string flightDraftId = 12;
    string creativeDraftId = 13;
    IdFilter campaignIdsFilter = 14;
    IdFilter flightIdsFilter = 15;
    IdFilter hierarchyDraftIdsFilter = 16;
  }
  HierarchyDraft.CreateFlowType createFlowType = 17;
}

message GetCreativeDraftsResponse {
  repeated CreativeDraft creativeDrafts = 1;
  Paging paging = 2;
}

I am so confused. I'm getting an NPE, and traced it down to a builder class that seems to think an enum value is null.

return draftsClient
    .getCreativeDrafts(
        GetCreativeDraftsRequest.newBuilder()
            .setCreativeDraftId("18b3c829-ec3f-4e25-9d74-8b311d4d0cff")
            .setLimit(3)
            .setOffset(0)
            .setSortType(SortType.newBuilder().setType(Type.UPDATED))
            .setSortDirection(
                SortDirection.newBuilder().setType(SortDirection.Type.DESC).build())
            .build()).toCompletableFuture().join();

The builder is generated from protobuf; here's the relevant piece—

    public GetCreativeDraftsRequest.Builder setSortDirection(SortDirection value) {
      if (this.sortDirectionBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }

        this.sortDirection_ = value;
        this.onChanged();
      } else {
        this.sortDirectionBuilder_.setMessage(value);
      }

      return this;
    }

I'm looking at the value of SortDirection.Type.DESC in the debugger and indeed, it's null—

enter image description here

Here's the enum, also generated from protobuf—

  public static enum Type implements ProtocolMessageEnum {
    UNSET(0),
    DESC(1),
    ASC(2),
    UNRECOGNIZED(-1);

    public static final int UNSET_VALUE = 0;
    public static final int DESC_VALUE = 1;
    public static final int ASC_VALUE = 2;
    private static final EnumLiteMap<SortDirection.Type> internalValueMap = new EnumLiteMap<SortDirection.Type>() {
      public SortDirection.Type findValueByNumber(int number) {
        return SortDirection.Type.forNumber(number);
      }
    };
    private static final SortDirection.Type[] VALUES = values();
    private final int value;

    public final int getNumber() {
      if (this == UNRECOGNIZED) {
        throw new IllegalArgumentException("Can't get the number of an unknown enum value.");
      } else {
        return this.value;
      }
    }

    /** @deprecated */
    @Deprecated
    public static SortDirection.Type valueOf(int value) {
      return forNumber(value);
    }

    public static SortDirection.Type forNumber(int value) {
      switch(value) {
      case 0:
        return UNSET;
      case 1:
        return DESC;
      case 2:
        return ASC;
      default:
        return null;
      }
    }

    public static EnumLiteMap<SortDirection.Type> internalGetValueMap() {
      return internalValueMap;
    }

    public final EnumValueDescriptor getValueDescriptor() {
      return (EnumValueDescriptor)getDescriptor().getValues().get(this.ordinal());
    }

    public final EnumDescriptor getDescriptorForType() {
      return getDescriptor();
    }

    public static final EnumDescriptor getDescriptor() {
      return (EnumDescriptor)SortDirection.getDescriptor().getEnumTypes().get(0);
    }

    public static SortDirection.Type valueOf(EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new IllegalArgumentException("EnumValueDescriptor is not for this type.");
      } else {
        return desc.getIndex() == -1 ? UNRECOGNIZED : VALUES[desc.getIndex()];
      }
    }

    private Type(int value) {
      this.value = value;
    }
  }

Oddly, it works if I do this—

SortDirection.newBuilder().setTypeValue(1).build()

I've been using protobufs for several years and never run into this problem. What could be happening here?


Edit

Here's the proto for the enums:

syntax = "proto3";

package com.mycompany.ads.adstudiodrafts;

import "google/protobuf/timestamp.proto";

option java_outer_classname = "ModelProto";
option java_multiple_files = true;
option java_package = "com.mycompany.ads.adstudiodrafts.proto";

message Paging {
  int32 limit = 1;
  int32 total = 2;
  int32 offset = 3;
  SortDirection sortDirection = 4;
  SortType sortType = 5;
}

message SortDirection {
  enum Type {
    UNSET = 0;
    DESC = 1;
    ASC = 2;
  }
  Type type = 1;
}

message SortType {
  enum Type {
    UNSET = 0;
    CREATED = 1;
    UPDATED = 2;
  }
  Type type = 1;
}

And here's a snippet of the proto for the endpoint:

message GetCreativeDraftsRequest {
  string iamDomain = 1;
  int32 limit = 2;
  int32 offset = 3;
  SortDirection sortDirection = 4;
  SortType sortType = 5;
  DraftStatus status = 6;
  string searchWord = 7;
  oneof searchCriteria {
    string hierarchyDraftId = 8;
    string csCampaignId = 9;
    string csFlightId = 10;
    string campaignDraftId = 11;
    string flightDraftId = 12;
    string creativeDraftId = 13;
    IdFilter campaignIdsFilter = 14;
    IdFilter flightIdsFilter = 15;
    IdFilter hierarchyDraftIdsFilter = 16;
  }
  HierarchyDraft.CreateFlowType createFlowType = 17;
}

message GetCreativeDraftsResponse {
  repeated CreativeDraft creativeDrafts = 1;
  Paging paging = 2;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文