Java 协议缓冲区无效嵌入描述符问题

Java 协议缓冲区无效嵌入描述符问题,java,protocol-buffers,Java,Protocol Buffers,我的一些生成的协议缓冲区类在运行时遇到一些问题 我的项目布局如下: module/ protobuf-api/ proto/ com/foo/api/Service.proto com/foo/shared/Shared.proto org/bar/api/Message1.proto org/bar/api/Message2.proto 我读过这篇文章,但我认为我做的每件事都是正确的。关于我为什么会出现初始化错误有什么建议吗?我使用相

我的一些生成的协议缓冲区类在运行时遇到一些问题

我的项目布局如下:

module/ protobuf-api/ proto/ com/foo/api/Service.proto com/foo/shared/Shared.proto org/bar/api/Message1.proto org/bar/api/Message2.proto 我读过这篇文章,但我认为我做的每件事都是正确的。关于我为什么会出现初始化错误有什么建议吗?我使用相同的-I标志编译所有内容。

我怀疑问题在于,当您查找proto文件时,您已经给了它完整的路径,例如proto/com/foo/api/Service.proto,但是当它通过include目录引用它时,它使用的是com/foo/api/Service.proto

简单修复-从
proto
目录运行此操作:

find . -name *.proto -exec protoc --java_out=../java -I=. {} \;
我必须承认,我记不起protoc的很多细节(我真的应该记得),但我怀疑这会起作用

另一个可行的替代方案:


i、 e.将所有proto文件传递到对protoc的单个调用中。

我在C#中遇到了相同的错误类型,这就是我的问题:我在项目的预构建步骤中调用了
protoc
。在那里,我使用Visual Studio内置宏,如
$(SolutionDir)
$(ProjectDir)
来检索必要的路径。由于我引用了其他项目中的
*.proto
文件,因此我使用了两个
--proto_path
选项:一个用于根路径(解析
导入
路径),另一个用于文件本身。我的解决方案文件位于根目录的子目录中,因此我使用相对路径
访问根目录。原型文件始终位于特定项目的子目录
gen
。总而言之,命令是这样的:

protoc.exe --proto_path=$(SolutionDir).. --proto_path=$(ProjectDir)gen  $(ProjectDir)gen\DemoFile.proto
protoc.exe --proto_path=$(SolutionDir).. $(SolutionDir)..\My\Demo\Project\Directory\gen\DemoFile.proto
它编译得很好,但是我在运行时调用
CreateBuilder()
方法时得到了
System.TypeInitializationException
。问题在于,由于相对路径组件
,路径
$(SolutionDir)
$(ProjectDir)
(虽然实际上指向同一目录)具有不同的文本表示形式。我始终使用相同的路径解决了问题,如下所示:

protoc.exe --proto_path=$(SolutionDir).. --proto_path=$(ProjectDir)gen  $(ProjectDir)gen\DemoFile.proto
protoc.exe --proto_path=$(SolutionDir).. $(SolutionDir)..\My\Demo\Project\Directory\gen\DemoFile.proto

我花了将近3天的时间来缩小范围并认识到这个问题,所以我在这里分享我的解决方案,希望它能为某人节省一些时间。

我很肯定你是对的,但在你提出建议后,我仍然有困难。我的导入看起来确实像
com/foo/shared/shared.proto
我现在正试图传递路径ala
protoc--java_out=module/protobuf-api/java-I=module/protobuf-api/proto-module/protobuf-api/proto/com/foo/api/Service.proto
。我认为这应该是可行的,因为导入现在与-I给出的路径是相对的。我不希望从项目根导入整个路径,而只是从一些基本包导入相对路径,这样我就可以更容易地将其与构建系统集成。我会继续努力的。非常感谢@约书亚:如果你能拿出一个简短但完整的例子来说明这一点,那将非常有帮助。除此之外,我还想检查一下我的C#port的性能:)事实上,我们的测试框架一定做了一些非常奇怪的事情。当我使用org.junit.runner.JUnitCore从命令行调用测试时,一切正常。由于某些原因,FileDescriptor在与我们的框架一起运行时没有完全限定的名称。如果我能找到对其他人有用的东西,我会报告更多。谢谢