ninjudd / clojure-protobuf

Google protocol buffers wrapper for Clojure.
Eclipse Public License 1.0
217 stars 70 forks source link

README not working #52

Open xpe opened 10 years ago

xpe commented 10 years ago

I'm walking through the README example, but I get an error (see below).

I start a sample project with this project.clj:

(defproject sample "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.5.1"]
                 [org.flatland/protobuf "0.8.1"]]
  :plugins [[lein-protobuf "0.4.1"]]
  :profiles {:dev {:source-paths ["dev"]
                   :dependencies [[org.clojure/tools.namespace "0.2.4"]]}})

I create resources/proto/person.proto with these contents:

message Person {
  required int32  id    = 1;
  required string name  = 2;
  optional string email = 3;
  repeated string likes = 4;
}

Then I run lein protobuf and I get:

/Users/david/.lein/cache/lein-protobuf/protobuf-2.5.0/src/protoc person.proto --java_out=/Users/david/dev/maybe/sample/target/protosrc -I. -I/Users/david/dev/maybe/sample/target/proto -I/Users/david/dev/maybe/sample/resources/proto ERROR: /Users/david/dev/maybe/sample/target/proto: warning: directory does not exist. --java_out: person.proto: person.proto: Cannot generate Java output because the file's outer class name, "Person", matches the name of one of the types declared inside it. Please either rename the type or use the java_outer_classname option to specify a different outer class name for the .proto file.

xpe commented 10 years ago

To answer my question: the README should say to name the file as resources/proto/example.proto.

If you read https://developers.google.com/protocol-buffers/docs/javatutorial you'll see that there are 3 names involved:

  1. the protobuf namespace (may or may not be the same as the Java ones, below)
  2. the generated Java package name
  3. the generated Java class name

The .proto file starts with a package declaration, which helps to prevent naming conflicts between different projects. In Java, the package name is used as the Java package unless you have explicitly specified a java_package, as we have here. Even if you do provide a java_package, you should still define a normal package as well to avoid name collisions in the Protocol Buffers name space as well as in non-Java languages.

After the package declaration, you can see two options that are Java-specific: java_package and java_outer_classname. java_package specifies in what Java package name your generated classes should live. If you don't specify this explicitly, it simply matches the package name given by the package declaration, but these names usually aren't appropriate Java package names (since they usually don't start with a domain name). The java_outer_classname option defines the class name which should contain all of the classes in this file. If you don't give a java_outer_classname explicitly, it will be generated by converting the file name to camel case. For example, "my_proto.proto" would, by default, use "MyProto" as the outer class name.