Protobuf-java包名称和跨项目共享proto文件

Protobuf-java包名称和跨项目共享proto文件,java,protocol-buffers,proto,Java,Protocol Buffers,Proto,我有两个java项目,它们生成和使用来自Kafka的消息, 一个项目生成类型为Ticker的消息,另一个项目使用此消息 所以我创建了这个文件 syntax = "proto3"; message Ticker { string symbol = 1; float ask = 2; float bid = 3; } 我知道为了创建这种消息类型的Java对象,我使用了protoc 然而,我有两个问题 我需要一种在整个项目中共享proto文件的方法(我现在拥有的两个项目以及

我有两个java项目,它们生成和使用来自Kafka的消息, 一个项目生成类型为
Ticker
的消息,另一个项目使用此消息

所以我创建了这个文件

syntax = "proto3";

message Ticker {
    string symbol = 1;
    float ask = 2;
    float bid = 3;
}
我知道为了创建这种消息类型的Java对象,我使用了
protoc

然而,我有两个问题

  • 我需要一种在整个项目中共享
    proto
    文件的方法(我现在拥有的两个项目以及将来需要访问
    Ticker
    的任何项目)。最好的方法是什么?我听说过git子树或子模块,这是一种好的/可靠的方法吗

  • 我需要一种
    protoc
    方法来生成某个包下的Java对象,例如,我有两个项目,一个是
    com.myorg.TickerProducer
    另一个是
    com.myorg.TickerConsumer
    我需要
    protoc
    分别在包/名称空间
    com.myorg.TickerProducer.entitiges
    com.myorg.TickerConsumer.enties
    中生成Java对象。我知道我可以在
    proto
    文件中使用
    option java_package
    ,但我有不同的项目使用相同的文件,每个项目都希望在其名称空间下生成java对象。有办法吗


  • 谢谢。

    单个.proto文件将始终在同一个包/命名空间中生成代码,因此,如果您希望在两个项目中有两个不同的布局,则需要两个.proto文件。坦率地说,尽管如此,我认为将它放在两者的同一个包/名称空间中是正确的:它最终还是一样的东西


    注意,只要不使用“any”特性,protobuf在运行时就不太关心类型名/包/命名空间;因此
    X.Y.Z
    可以与
    A.B.C
    互换,只要它们实际上是相同的基本形状。只要不使用json,就连字段名都是不相关的。

    解决这一问题的最明智的方法可能是为这些实体提供一个单独的包,消费者和生产者都使用它。只要你不希望消费者依赖生产者,反之亦然

    如果您使用的是Gradle,那么有一个将protobufs的构建集成到消费者项目代码中的方法


    一般来说,protobuf的使用方式之间存在轻微的阻抗不匹配,这是因为谷歌有一个单一的存储库,其中每个构建单元/包在技术上都可以依赖于其他构建单元/包,而在世界其他地方,项目有许多存储库,它们是如何使用的,而这些作为构建单元和包之间的可见性和依赖性的硬边界


    如果您可以将它们添加到包含其他常见定义等的包中,这将是最好的,但如果缺少这些定义,一个单独的包,尽管它很难看,可能是您最安全的选择。

    那么您建议对所有Java项目使用相同的名称空间com.myorg.Entities?那些不是用Java编写的项目呢?例如,我必须将
    java_包
    csharp_名称空间
    放在同一个
    proto
    文件中,我想这是可行的,但这让我觉得Protobuf从来没有被设计成在不同的项目之间共享(更不用说在不同的局域网中编写的项目了)。也许我的整个方法都是错误的,我应该为每个项目维护一个单独的
    proto
    文件?@areller我只是在谈论这些特定的实体,而不是所有的东西——但是:是的;可能在一个只包含这些共享类型的库项目中—然后从这两个库中使用该库。至于语言之间的问题:这根本不是问题,效果很好。我们希望您在相同的.proto中有一个
    java_包
    和一个
    csharp_命名空间
    (显然,在您使用java和c#的情况下),这是有意义的。这让我有点困扰,因为我希望
    proto
    文件与语言无关,因为
    protoc
    已经生成了特定于语言的文件,所以它也可以接受名称空间/包。谢谢,非常有用的回答。存储
    proto
    文件怎么样?您是否建议将它们放在git存储库中并使用子模块?@areller我并不完全反对——事实上,对于protobuf net的code gen工具的“旧”版本,它允许在命令行上指定名称空间。对于protobuf net的代码生成工具的“新”版本,我没有保留这一点,主要是为了提供与protoc的一致性(protobuf net只是一个单独的实现,而不是基于Google的代码库)。谢谢,我来看看这个插件。我将把这个通用包存储在哪里?每个项目都有自己的git存储库?我应该为公共
    proto
    文件建立一个单独的git存储库吗?我将如何从我的项目中访问它们?@areller这取决于你如何构建你的项目。如果您只有一个存储库,那么将其放在公共/目录中就足够了。如果您有多个,那么将其放在自己的存储库中最有意义。我通常把它分成几个包,每个包都有自己的存储库。至少现在大多数工具都是这样工作的。对于较小的项目来说,这在基础设施方面有点复杂,但对于较大的项目来说,这是一个福音,因为项目之间有一个非常清晰的边界。