{"action":"created","issue":{"url":"https://api.github.com/repos/google/protobuf-gradle-plugin/issues/8","labels_url":"https://api.github.com/repos/google/protobuf-gradle-plugin/issues/8/labels{/name}","comments_url":"https://api.github.com/repos/google/protobuf-gradle-plugin/issues/8/comments","events_url":"https://api.github.com/repos/google/protobuf-gradle-plugin/issues/8/events","html_url":"https://github.com/google/protobuf-gradle-plugin/issues/8","id":72992304,"number":8,"title":"Support protoc --proto_path","user":{"login":"mmmdreg","id":510042,"avatar_url":"https://avatars.githubusercontent.com/u/510042?v=3","gravatar_id":"","url":"https://api.github.com/users/mmmdreg","html_url":"https://github.com/mmmdreg","followers_url":"https://api.github.com/users/mmmdreg/followers","following_url":"https://api.github.com/users/mmmdreg/following{/other_user}","gists_url":"https://api.github.com/users/mmmdreg/gists{/gist_id}","starred_url":"https://api.github.com/users/mmmdreg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mmmdreg/subscriptions","organizations_url":"https://api.github.com/users/mmmdreg/orgs","repos_url":"https://api.github.com/users/mmmdreg/repos","events_url":"https://api.github.com/users/mmmdreg/events{/privacy}","received_events_url":"https://api.github.com/users/mmmdreg/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/google/protobuf-gradle-plugin/milestones/2","html_url":"https://github.com/google/protobuf-gradle-plugin/milestones/0.6.0","labels_url":"https://api.github.com/repos/google/protobuf-gradle-plugin/milestones/2/labels","id":1199691,"number":2,"title":"0.6.0","description":"","creator":{"login":"zhangkun83","id":9053690,"avatar_url":"https://avatars.githubusercontent.com/u/9053690?v=3","gravatar_id":"","url":"https://api.github.com/users/zhangkun83","html_url":"https://github.com/zhangkun83","followers_url":"https://api.github.com/users/zhangkun83/followers","following_url":"https://api.github.com/users/zhangkun83/following{/other_user}","gists_url":"https://api.github.com/users/zhangkun83/gists{/gist_id}","starred_url":"https://api.github.com/users/zhangkun83/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zhangkun83/subscriptions","organizations_url":"https://api.github.com/users/zhangkun83/orgs","repos_url":"https://api.github.com/users/zhangkun83/repos","events_url":"https://api.github.com/users/zhangkun83/events{/privacy}","received_events_url":"https://api.github.com/users/zhangkun83/received_events","type":"User","site_admin":false},"open_issues":3,"closed_issues":0,"state":"open","created_at":"2015-07-09T00:04:20Z","updated_at":"2015-07-09T00:05:03Z","due_on":"2015-07-31T07:00:00Z","closed_at":null},"comments":12,"created_at":"2015-05-04T11:07:24Z","updated_at":"2015-07-09T19:25:58Z","closed_at":null,"body":"When you define protos importing definitions from another project, protoc --proto_path=blah allows you to depend on these without re-compiling them. \r\n\r\nIn your plugin, adding another srcDir will compile the dependent protos, resulting in duplicates in a multi module project. The maven proto plugin correctly adds dependent protos to the include path without compiling them,  as does the Thomas lee gradle-protoc-plugin. \r\n\r\nWould be great if you can include the ability to modify the include path only, without adding the included proto files as arguments requiring compilation. Whether this is done using simple filesets or dependency archives isn't an issue. \r\n\r\nThanks"},"comment":{"url":"https://api.github.com/repos/google/protobuf-gradle-plugin/issues/comments/120118143","html_url":"https://github.com/google/protobuf-gradle-plugin/issues/8#issuecomment-120118143","issue_url":"https://api.github.com/repos/google/protobuf-gradle-plugin/issues/8","id":120118143,"user":{"login":"aantono","id":22290,"avatar_url":"https://avatars.githubusercontent.com/u/22290?v=3","gravatar_id":"","url":"https://api.github.com/users/aantono","html_url":"https://github.com/aantono","followers_url":"https://api.github.com/users/aantono/followers","following_url":"https://api.github.com/users/aantono/following{/other_user}","gists_url":"https://api.github.com/users/aantono/gists{/gist_id}","starred_url":"https://api.github.com/users/aantono/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aantono/subscriptions","organizations_url":"https://api.github.com/users/aantono/orgs","repos_url":"https://api.github.com/users/aantono/repos","events_url":"https://api.github.com/users/aantono/events{/privacy}","received_events_url":"https://api.github.com/users/aantono/received_events","type":"User","site_admin":false},"created_at":"2015-07-09T19:25:58Z","updated_at":"2015-07-09T19:25:58Z","body":"One issue we have run into while figuring out how to share message definitions was the question of where should the Java code be generated, compiled and shared.  The problem is that the generated Java code by *protoc* is reliant upon a specific version of a *protoc* compiler, which in turn expects that the generated code is compiled against a specific version of the *protobuf-java* library.  But not only should it be compiled against that version it also **MUST** be the same version that is used at runtime, otherwise you can get Linking errors if you for example used *protoc* version 2.3 to generate the Java code, but at runtime you end up using version 2.5 of the library.\r\n\r\nThe general solution that we came up with was to **NEVER** share the generated Java classes, but instead always share the *proto* artifacts and each **deployable** service (**not a library or api**) should **ALWAYS** generate their own Java version of the protos and compile them against whatever version of supported *protoc* they wish.\r\n\r\nFor libraries and apis we recommend in general not to make signatures that depend on specific generated *protoc* Java classes, but instead define their own *interface facades*, so that the consumer end service, if they choose to, can provide a wrapper implementation that uses the underlying Proto object as a data source.  This also has a nice benefit of having a place to define various business logic and other processing functions, since Protobuf is a data structure and not a reach object.  \r\n\r\nTo simplify the coding effort and the code maintenance, we rely on the *protoc* code generator plugins to apply code templates that encapsulate the wrapper class code, so it all gets embedded into the generated Java class, i.e. in a ```money.proto``` we would define a ```Money``` message.  The rich Java *Money* object would also have various behavior functions, like *add*, *divide*, *convert*, etc.  So we have a *Money.template* that defines an implementation of *api.Money* interface which internally wraps the *proto.Money* protobuf message and uses its data during invocation of the various functional methods like *add*, etc.  The various *libraries* do not directly depend on *proto.Money* class, but instead all code to *api.Money*, and rely on the consuming services to provide the implementation.\r\n\r\nGood news is that the code templates can also be packaged as artifacts and shared as build dependencies. :)  So if it seems like a complex setup, it is only sounds like it from the explanation, but in reality is very simple and has very low cost of maintenance, while virtually preventing any case of Java Serialization or signature incompatible Linking Errors to throw a wrench into a gearbox.  It also aids with being able to create easy test mocks, since the interfaces don't have to be *Proto Wrappers*, but can just be locally created mocks, etc.  All-in-all, we praise this solution as a triple-win scenario.\r\n\r\nFeel free to ask clarifying questions in case I've rambled through some things without clearly explaining the details, I would be happy to explain and provide more info."}}