| Protocol Buffers - Google's data interchange format |
| Copyright 2008 Google Inc. |
| |
| This directory contains the Java Protocol Buffers runtime library. |
| |
| Installation - With Maven |
| ========================= |
| |
| The Protocol Buffers build is managed using Maven. If you would |
| rather build without Maven, see below. |
| |
| 1) Install Apache Maven if you don't have it: |
| |
| http://maven.apache.org/ |
| |
| 2) Build the C++ code, or obtain a binary distribution of protoc. If |
| you install a binary distribution, make sure that it is the same |
| version as this package. If in doubt, run: |
| |
| $ protoc --version |
| |
| You will need to place the protoc executable in ../src. (If you |
| built it yourself, it should already be there.) |
| |
| 3) Run the tests: |
| |
| $ mvn test |
| |
| If some tests fail, this library may not work correctly on your |
| system. Continue at your own risk. |
| |
| 4) Install the library into your Maven repository: |
| |
| $ mvn install |
| |
| 5) If you do not use Maven to manage your own build, you can build a |
| .jar file to use: |
| |
| $ mvn package |
| |
| The .jar will be placed in the "target" directory. |
| |
| Installation - 'Lite' Version - With Maven |
| ========================================== |
| |
| Building the 'lite' version of the Java Protocol Buffers library is |
| the same as building the full version, except that all commands are |
| run using the 'lite' profile. (see |
| http://maven.apache.org/guides/introduction/introduction-to-profiles.html) |
| |
| E.g. to install the lite version of the jar, you would run: |
| |
| $ mvn install -P lite |
| |
| The resulting artifact has the 'lite' classifier. To reference it |
| for dependency resolution, you would specify it as: |
| |
| <dependency> |
| <groupId>com.google.protobuf</groupId> |
| <artifactId>protobuf-java</artifactId> |
| <version>${version}</version> |
| <classifier>lite</classifier> |
| </dependency> |
| |
| Installation - Without Maven |
| ============================ |
| |
| If you would rather not install Maven to build the library, you may |
| follow these instructions instead. Note that these instructions skip |
| running unit tests. |
| |
| 1) Build the C++ code, or obtain a binary distribution of protoc. If |
| you install a binary distribution, make sure that it is the same |
| version as this package. If in doubt, run: |
| |
| $ protoc --version |
| |
| If you built the C++ code without installing, the compiler binary |
| should be located in ../src. |
| |
| 2) Invoke protoc to build DescriptorProtos.java: |
| |
| $ protoc --java_out=src/main/java -I../src \ |
| ../src/google/protobuf/descriptor.proto |
| |
| 3) Compile the code in src/main/java using whatever means you prefer. |
| |
| 4) Install the classes wherever you prefer. |
| |
| Micro version |
| ============================ |
| |
| The runtime and generated code for MICRO_RUNTIME is smaller |
| because it does not include support for the descriptor and |
| reflection, and enums are generated as integer constants in |
| the parent message or the file's outer class. Also, not |
| currently supported are packed repeated elements or |
| extensions. |
| |
| To create a jar file for the runtime and run tests invoke |
| "mvn package -P micro" from the <protobuf-root>/java |
| directory. The generated jar file is |
| <protobuf-root>java/target/protobuf-java-2.2.0-micro.jar. |
| |
| If you wish to compile the MICRO_RUNTIME your self, place |
| the 7 files below, in <root>/com/google/protobuf and |
| create a jar file for use with your code and the generated |
| code: |
| |
| ByteStringMicro.java |
| CodedInputStreamMicro.java |
| CodedOutputStreamMicro.java |
| InvalidProtocolBufferException.java |
| MessageMicro.java |
| WireFormatMicro.java |
| |
| If you wish to change on the code generator it is located |
| in /src/google/protobuf/compiler/javamicro. |
| |
| To generate code for the MICRO_RUNTIME invoke protoc with |
| --javamicro_out command line parameter. javamicro_out takes |
| a series of optional sub-parameters separated by commas |
| and a final parameter, with a colon separator, which defines |
| the source directory. Sub-parameters begin with a name |
| followed by an equal and if that sub-parameter has multiple |
| parameters they are seperated by "|". The command line options |
| are: |
| |
| opt -> speed or space |
| java_use_vector -> true or false |
| java_package -> <file-name>|<package-name> |
| java_outer_classname -> <file-name>|<package-name> |
| java_multiple_files -> true or false |
| |
| opt={speed,space} (default: space) |
| This changes the code generation to optimize for speed or |
| space. When opt=speed this changes the code generation |
| for strings so that multiple conversions to Utf8 are |
| eliminated. |
| |
| java_use_vector={true,false} (default: false) |
| This specifies the collection class for repeated elements. |
| If false, repeated elements use java.util.ArrayList<> and |
| the code must be compiled with Java 1.5 or above. If true, |
| repeated elements use java.util.Vector and the code can |
| be compiled with Java 1.3 or above. The 'source' |
| parameter of 'javac' may be used to control the version |
| of the source: "javac -source 1.3". You can also change |
| the <source> xml element for the maven-compiler-plugin. |
| Below is for 1.5 sources: |
| |
| <plugin> |
| <artifactId>maven-compiler-plugin</artifactId> |
| <configuration> |
| <source>1.5</source> |
| <target>1.5</target> |
| </configuration> |
| </plugin> |
| |
| And below would be for 1.3 sources (note when changing |
| to 1.3 you must also set java_use_vector=true): |
| |
| <plugin> |
| <artifactId>maven-compiler-plugin</artifactId> |
| <configuration> |
| <source>1.3</source> |
| <target>1.5</target> |
| </configuration> |
| </plugin> |
| |
| java_package=<file-name>|<package-name> (no default) |
| This allows overriding the 'java_package' option value |
| for the given file from the command line. Use multiple |
| java_package options to override the option for multiple |
| files. The final Java package for each file is the value |
| of this command line option if present, or the value of |
| the same option defined in the file if present, or the |
| proto package if present, or the default Java package. |
| |
| java_outer_classname=<file-name>|<outer-classname> (no default) |
| This allows overriding the 'java_outer_classname' option |
| for the given file from the command line. Use multiple |
| java_outer_classname options to override the option for |
| multiple files. The final Java outer class name for each |
| file is the value of this command line option if present, |
| or the value of the same option defined in the file if |
| present, or the file name converted to CamelCase. This |
| outer class will nest all classes and integer constants |
| generated from file-scope messages and enums. |
| |
| java_multiple_files={true,false} (no default) |
| This allows overriding the 'java_multiple_files' option |
| in all source files and their imported files from the |
| command line. The final value of this option for each |
| file is the value defined in this command line option, or |
| the value of the same option defined in the file if |
| present, or false. This specifies whether to generate |
| package-level classes for the file-scope messages in the |
| same Java package as the outer class (instead of nested |
| classes in the outer class). File-scope enum constants |
| are still generated as integer constants in the outer |
| class. This affects the fully qualified references in the |
| Java code. NOTE: because the command line option |
| overrides the value for all files and their imported |
| files, using this option inconsistently may result in |
| incorrect references to the imported messages and enum |
| constants. |
| |
| |
| IMPORTANT: change of javamicro_out behavior: |
| |
| In previous versions, if the outer class name has not been |
| given explicitly, javamicro_out would not infer the outer |
| class name from the file name, and would skip the outer |
| class generation. This makes the compilation succeed only |
| if the source file contains a single message and no enums, |
| and the generated class for that message is placed at the |
| package level. To re-align with java_out, javamicro_out |
| will now always generate the outer class, inferring its |
| name from the file name if not given, as a container of the |
| message classes and enum constants. To keep any existing |
| single-message source file from causing the generation of |
| an unwanted outer class, you can set the option |
| java_multiple_files to true, either in the file or as a |
| command line option. |
| |
| |
| Below are a series of examples for clarification of the |
| various parameters and options. Assuming this file: |
| |
| src/proto/simple-data-protos.proto: |
| |
| package testprotobuf; |
| |
| message SimpleData { |
| optional fixed64 id = 1; |
| optional string description = 2; |
| optional bool ok = 3 [default = false]; |
| }; |
| |
| and the compiled protoc in the current working directory, |
| then a simple command line to compile this file would be: |
| |
| ./protoc --javamicro_out=. src/proto/simple-data-protos.proto |
| |
| This will create testprotobuf/SimpleDataProtos.java, which |
| has the following content (extremely simplified): |
| |
| package testprotobuf; |
| |
| public final class SimpleDataProtos { |
| public static final class SimpleData |
| extends MessageMicro { |
| ... |
| } |
| } |
| |
| The message SimpleData is compiled into the SimpleData |
| class, nested in the file's outer class SimpleDataProtos, |
| whose name is implicitly defined by the proto file name |
| "simple-data-protos". |
| |
| The directory, aka Java package, testprotobuf is created |
| because on line 1 of simple-data-protos.proto is |
| "package testprotobuf;". If you wanted a different |
| package name you could use the java_package option in the |
| file: |
| |
| option java_package = "my_package"; |
| |
| or in command line sub-parameter: |
| |
| ./protoc '--javamicro_out=\ |
| java_package=src/proto/simple-data-protos.proto|my_package:\ |
| .' src/proto/simple-data-protos.proto |
| |
| Here you see the new java_package sub-parameter which |
| itself needs two parameters the file name and the |
| package name, these are separated by "|". The value set |
| in the command line overrides the value set in the file. |
| Now you'll find SimpleDataProtos.java in the my_package/ |
| directory. |
| |
| If you wanted to also change the optimization for |
| speed you'd add opt=speed with the comma seperator |
| as follows: |
| |
| ./protoc '--javamicro_out=\ |
| opt=speed,\ |
| java_package=src/proto/simple-data-protos.proto|my_package: |
| .' src/proto/simple-data-protos.proto |
| |
| If you also wanted a different outer class name you'd |
| do the following: |
| |
| ./protoc '--javamicro_out=\ |
| opt=speed,\ |
| java_package=src/proto/simple-data-protos.proto|my_package,\ |
| java_outer_classname=src/proto/simple-data-protos.proto|OuterName:\ |
| .' src/proto/simple-data-protos.proto |
| |
| Now you'll find my_package/OuterName.java and the |
| message class SimpleData nested in it. |
| |
| As mentioned java_package, java_outer_classname and |
| java_multiple_files may also be specified in the file. |
| In the example below we must define |
| java_outer_classname because otherwise the outer class |
| and one of the message classes will have the same name, |
| which is forbidden to prevent name ambiguity: |
| |
| src/proto/sample-message.proto: |
| |
| package testmicroruntime; |
| |
| option java_package = "com.example"; |
| option java_outer_classname = "SampleMessageProtos"; |
| |
| enum MessageType { |
| SAMPLE = 1; |
| EXAMPLE = 2; |
| } |
| |
| message SampleMessage { |
| required int32 id = 1; |
| required MessageType type = 2; |
| } |
| |
| message SampleMessageContainer { |
| required SampleMessage message = 1; |
| } |
| |
| This could be compiled using: |
| |
| ./protoc --javamicro_out=. src/proto/sample-message.proto |
| |
| and the output will be: |
| |
| com/example/SampleMessageProtos.java: |
| |
| package com.example; |
| |
| public final class SampleMessageProtos { |
| public static final int SAMPLE = 1; |
| public static final int EXAMPLE = 2; |
| public static final class SampleMessage |
| extends MessageMicro { |
| ... |
| } |
| public static final class SampleMessageContainer |
| extends MessageMicro { |
| ... |
| } |
| } |
| |
| As you can see the file-scope enum MessageType is |
| disassembled into two integer constants in the outer class. |
| In javamicro_out, all enums are disassembled and compiled |
| into integer constants in the parent scope (the containing |
| message's class or the file's (i.e. outer) class). |
| |
| You may prefer the file-scope messages to be saved in |
| separate files. You can do this by setting the option |
| java_multiple_files to true, in either the file like this: |
| |
| option java_multiple_files = true; |
| |
| or the command line like this: |
| |
| ./protoc --javamicro_out=\ |
| java_multiple_files=true:\ |
| . src/proto/sample-message.proto |
| |
| The java_multiple_files option causes javamicro to use a |
| separate file for each file-scope message, which resides |
| directly in the Java package alongside the outer class: |
| |
| com/example/SampleMessageProtos.java: |
| |
| package com.example; |
| public final class SampleMessageProtos { |
| public static final int SAMPLE = 1; |
| public static final int EXAMPLE = 2; |
| } |
| |
| com/example/SampleMessage.java: |
| |
| package com.example; |
| public final class SampleMessage |
| extends MessageMicro { |
| ... |
| } |
| |
| com/example/SampleMessageContainer.java: |
| |
| package com.example; |
| public final class SampleMessageContainer |
| extends MessageMicro { |
| ... |
| } |
| |
| As you can see, the outer class now contains only the |
| integer constants, generated from the file-scope enum |
| "MessageType". Please note that message-scope enums are |
| still generated as integer constants in the message class. |
| |
| |
| Nano version |
| ============================ |
| |
| Nano is even smaller than micro, especially in the number of generated |
| functions. It is like micro except: |
| |
| - No setter/getter/hazzer functions. |
| - Has state is not available. Outputs all fields not equal to their |
| default. (See important implications below.) |
| - CodedInputStreamMicro is renamed to CodedInputByteBufferNano and can |
| only take byte[] (not InputStream). |
| - Similar rename from CodedOutputStreamMicro to |
| CodedOutputByteBufferNano. |
| - Repeated fields are in arrays, not ArrayList or Vector. |
| - Unset messages/groups are null, not an immutable empty default |
| instance. |
| - Required fields are always serialized. |
| - toByteArray(...) and mergeFrom(...) are now static functions of |
| MessageNano. |
| - "bytes" are of java type byte[]. |
| |
| IMPORTANT: If you have fields with defaults |
| |
| How fields with defaults are serialized has changed. Because we don't |
| keep "has" state, any field equal to its default is assumed to be not |
| set and therefore is not serialized. Consider the situation where we |
| change the default value of a field. Senders compiled against an older |
| version of the proto continue to match against the old default, and |
| don't send values to the receiver even though the receiver assumes the |
| new default value. Therefore, think carefully about the implications |
| of changing the default value. |
| |
| IMPORTANT: If you have "bytes" fields with non-empty defaults |
| |
| Because the byte buffer is now of mutable type byte[], the default |
| static final cannot be exposed through a public field. Each time a |
| message's constructor or clear() function is called, the default value |
| (kept in a private byte[]) is cloned. This causes a small memory |
| penalty. This is not a problem if the field has no default or is an |
| empty default. |
| |
| Nano Generator options |
| |
| java_package -> <file-name>|<package-name> |
| java_outer_classname -> <file-name>|<package-name> |
| java_multiple_files -> true or false |
| java_nano_generate_has -> true or false |
| |
| java_package: |
| java_outer_classname: |
| java_multiple_files: |
| Same as Micro version. |
| |
| java_nano_generate_has={true,false} (default: false) |
| If true, generates a public boolean variable has<fieldname> |
| accompanying each optional or required field (not present for |
| repeated fields, groups or messages). It is set to false initially |
| and upon clear(). If parseFrom(...) reads the field from the wire, |
| it is set to true. This is a way for clients to inspect the "has" |
| value upon parse. If it is set to true, writeTo(...) will ALWAYS |
| output that field (even if field value is equal to its |
| default). |
| |
| IMPORTANT: This option costs an extra 4 bytes per primitive field in |
| the message. Think carefully about whether you really need this. In |
| many cases reading the default works and determining whether the |
| field was received over the wire is irrelevant. |
| |
| To use nano protobufs: |
| |
| - Link with the generated jar file |
| <protobuf-root>java/target/protobuf-java-2.3.0-nano.jar. |
| - Invoke with --javanano_out, e.g.: |
| |
| ./protoc '--javanano_out=\ |
| java_package=src/proto/simple-data.proto|my_package,\ |
| java_outer_classname=src/proto/simple-data.proto|OuterName:\ |
| .' src/proto/simple-data.proto |
| |
| Contributing to nano: |
| |
| Please add/edit tests in NanoTest.java. |
| |
| Please run the following steps to test: |
| |
| - cd external/protobuf |
| - ./configure |
| - Run "make -j12 check" and verify all tests pass. |
| - cd java |
| - Run "mvn test" and verify all tests pass. |
| - cd ../../.. |
| - . build/envsetup.sh |
| - lunch 1 |
| - "make -j12 aprotoc libprotobuf-java-2.3.0-nano aprotoc-test-nano-params" and |
| check for build errors. |
| - repo sync -c -j256 |
| - "make -j12" and check for build errors |
| |
| |
| Usage |
| ===== |
| |
| The complete documentation for Protocol Buffers is available via the |
| web at: |
| |
| http://code.google.com/apis/protocolbuffers/ |