views:

36

answers:

1

Hi,

I'm having some problems at runtime with some of my generated protocol buffer classes.

My project layout is as follows:

module/
  protobuf-api/
    proto/
      com/foo/api/Service.proto
      com/foo/shared/Shared.proto
      org/bar/api/Message1.proto
      org/bar/api/Message2.proto

The Service.proto file depends on Shared.proto and some of the Message*.proto files. From the protobuf-api directory, I run the following command to compile:
find . -name *.proto -exec protoc --java_out=java -I=proto {} \;

When I attempt to run my Service, I get the following exception:

java.lang.ExceptionInInitializerError
    at com.linkedin.history.api.protobuf.HistoryServiceProtos$HistoryServiceQuery.(HistoryServiceProtos.java:544)
    at com.linkedin.history.api.serializer.HistoryServiceSerializer.serialize(HistoryServiceSerializer.java:47)
     at test.history.serializer.TestSerializer.testHistoryServiceQuery(TestSerializer.java:38)
    at test.fwk.util.core.BaseTestSuiteCore.run(BaseTestSuiteCore.java:304)
     at test.fwk.util.core.BaseTestSuiteConf.run(BaseTestSuiteConf.java:186)
    at test.fwk.lispring.BaseTestSuite.run(BaseTestSuite.java:232)
    at test.fwk.lispring.BaseTestSuite.callAppropriateRun(BaseTestSuite.java:265)
    at test.fwk.util.core.BaseTestSuiteCore.run(BaseTestSuiteCore.java:199)
Caused by: java.lang.IllegalArgumentException: Invalid embedded descriptor for "com/linkedin/history/api/protobuf/HistoryService.proto".
     at com.google.protobuf.Descriptors$FileDescriptor.internalBuildGeneratedFileFrom(Descriptors.java:268)
     at com.linkedin.history.api.protobuf.HistoryServiceProtos.(HistoryServiceProtos.java:1794)
Caused by: com.google.protobuf.Descriptors$DescriptorValidationException: com/linkedin/history/api/protobuf/HistoryService.proto: Dependencies passed to FileDescriptor.buildFrom() don't match those listed in the FileDescriptorProto.
     at com.google.protobuf.Descriptors$FileDescriptor.buildFrom(Descriptors.java:221)
     at com.google.protobuf.Descriptors$FileDescriptor.internalBuildGeneratedFileFrom(Descriptors.java:266)

I've read the post here but I think I'm doing everything correctly. Any suggestions on why I'm having the initializer errors? I'm compiling everything with the same -I flag.

+1  A: 

I suspect that the problem is that when you're finding the proto file, you've given it the full path, e.g. proto/com/foo/api/Service.proto but when it refers to it via the include directory, it's using com/foo/api/Service.proto

Simple fix - run this from the proto directory:

find . -name *.proto -exec protoc --java_out=../java -I=. {} \;

I must admit I can't remember a lot of the details of protoc (which I really should) but I suspect that will work.

Another alternative which may work:

protoc --java_out=java `find . -name '*.proto'`

i.e. pass all the proto files into a single call to protoc.

Jon Skeet
I'm pretty sure that you're right, but I'm still having trouble after your suggestions. My imports do look like `com/foo/shared/Shared.proto` I'm now trying to pass the path ala `protoc --java_out=module/protobuf-api/java -I=module/protobuf-api/proto module/protobuf-api/proto/com/foo/api/Service.proto`. I think this *should* work since the imports are now relative from the path given with -I. I'd prefer not to import the whole path from the project root, just a relative path from some base package so I can more easily integrate it with our build system. I'll keep trying. Thanks so much!
Joshua Hartman
@Joshua: If you could come up with a short but complete example which shows this, it would be really helpful. Apart from anything else, I'd like to check how it fares with my C# port :)
Jon Skeet
@Jon: Actually, our test framework must be doing something very odd. When I invoke the test from the command line with org.junit.runner.JUnitCore, everything works fine. For some reason the FileDescriptor doesn't have the fully qualified name when run with our Framework. I'll report more if I can find anything useful for others. Thanks!
Joshua Hartman
@Joshua: That's *really* weird. I have no idea why that would happen...
Jon Skeet