aboutsummaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/core/pom.xml2
-rw-r--r--java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java16
-rw-r--r--java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java70
-rw-r--r--java/pom.xml4
-rw-r--r--java/util/pom.xml2
-rw-r--r--java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java2
-rw-r--r--java/util/src/main/java/com/google/protobuf/util/JsonFormat.java17
-rw-r--r--java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java51
8 files changed, 150 insertions, 14 deletions
diff --git a/java/core/pom.xml b/java/core/pom.xml
index a7d4ea37..0c0fd8ff 100644
--- a/java/core/pom.xml
+++ b/java/core/pom.xml
@@ -6,7 +6,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
- <version>3.6.0</version>
+ <version>3.6.1</version>
</parent>
<artifactId>protobuf-java</artifactId>
diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
index 35b31f15..ff670fd8 100644
--- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
@@ -1406,7 +1406,7 @@ public abstract class GeneratedMessageLite<
/**
* A serialized (serializable) form of the generated message. Stores the
- * message as a class name and a byte array.
+ * message as a class and a byte array.
*/
protected static final class SerializedForm implements Serializable {
@@ -1416,6 +1416,9 @@ public abstract class GeneratedMessageLite<
private static final long serialVersionUID = 0L;
+ // since v3.6.1
+ private final Class<?> messageClass;
+ // only included for backwards compatibility before messageClass was added
private final String messageClassName;
private final byte[] asBytes;
@@ -1424,7 +1427,8 @@ public abstract class GeneratedMessageLite<
* @param regularForm the message to serialize
*/
SerializedForm(MessageLite regularForm) {
- messageClassName = regularForm.getClass().getName();
+ messageClass = regularForm.getClass();
+ messageClassName = messageClass.getName();
asBytes = regularForm.toByteArray();
}
@@ -1436,7 +1440,7 @@ public abstract class GeneratedMessageLite<
@SuppressWarnings("unchecked")
protected Object readResolve() throws ObjectStreamException {
try {
- Class<?> messageClass = Class.forName(messageClassName);
+ Class<?> messageClass = resolveMessageClass();
java.lang.reflect.Field defaultInstanceField =
messageClass.getDeclaredField("DEFAULT_INSTANCE");
defaultInstanceField.setAccessible(true);
@@ -1463,7 +1467,7 @@ public abstract class GeneratedMessageLite<
@Deprecated
private Object readResolveFallback() throws ObjectStreamException {
try {
- Class<?> messageClass = Class.forName(messageClassName);
+ Class<?> messageClass = resolveMessageClass();
java.lang.reflect.Field defaultInstanceField =
messageClass.getDeclaredField("defaultInstance");
defaultInstanceField.setAccessible(true);
@@ -1483,6 +1487,10 @@ public abstract class GeneratedMessageLite<
throw new RuntimeException("Unable to understand proto buffer", e);
}
}
+
+ private Class<?> resolveMessageClass() throws ClassNotFoundException {
+ return messageClass != null ? messageClass : Class.forName(messageClassName);
+ }
}
/**
diff --git a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
index a4143cd4..4489dace 100644
--- a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
+++ b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
@@ -32,6 +32,7 @@ package com.google.protobuf;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Int32Value;
import com.google.protobuf.test.UnittestImport;
import protobuf_unittest.EnumWithNoOuter;
import protobuf_unittest.MessageWithNoOuter;
@@ -853,6 +854,75 @@ public class GeneratedMessageTest extends TestCase {
assertEquals(expected, actual);
}
+ public void testDeserializeWithoutClassField() throws Exception {
+ // serialized form for version <=3.6.0
+ // just includes messageClassName and asBytes
+
+ // Int32Value.newBuilder().setValue(123).build()
+ byte[] int32ValueBytes = new byte[]{
+ -84, -19, 0, 5, 115, 114, 0, 55, 99, 111, 109, 46, 103, 111, 111,
+ 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 71,
+ 101, 110, 101, 114, 97, 116, 101, 100, 77, 101, 115, 115, 97, 103,
+ 101, 76, 105, 116, 101, 36, 83, 101, 114, 105, 97, 108, 105, 122,
+ 101, 100, 70, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 91,
+ 0, 7, 97, 115, 66, 121, 116, 101, 115, 116, 0, 2, 91, 66, 76, 0,
+ 16, 109, 101, 115, 115, 97, 103, 101, 67, 108, 97, 115, 115, 78,
+ 97, 109, 101, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110,
+ 103, 47, 83, 116, 114, 105, 110, 103, 59, 120, 112, 117, 114, 0,
+ 2, 91, 66, -84, -13, 23, -8, 6, 8, 84, -32, 2, 0, 0, 120, 112, 0,
+ 0, 0, 2, 8, 123, 116, 0, 30, 99, 111, 109, 46, 103, 111, 111, 103,
+ 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 73, 110,
+ 116, 51, 50, 86, 97, 108, 117, 101
+ };
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(int32ValueBytes);
+ ObjectInputStream in = new ObjectInputStream(bais);
+ Int32Value int32Value = (Int32Value) in.readObject();
+ assertEquals(123, int32Value.getValue());
+ }
+
+ public void testDeserializeWithClassField() throws Exception {
+ // serialized form for version > 3.6.0
+ // includes messageClass, messageClassName (for compatibility), and asBytes
+
+ // Int32Value.newBuilder().setValue(123).build()
+ byte[] int32ValueBytes = new byte[]{
+ -84, -19, 0, 5, 115, 114, 0, 55, 99, 111, 109, 46, 103, 111, 111,
+ 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 71,
+ 101, 110, 101, 114, 97, 116, 101, 100, 77, 101, 115, 115, 97, 103,
+ 101, 76, 105, 116, 101, 36, 83, 101, 114, 105, 97, 108, 105, 122,
+ 101, 100, 70, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 91,
+ 0, 7, 97, 115, 66, 121, 116, 101, 115, 116, 0, 2, 91, 66, 76, 0,
+ 12, 109, 101, 115, 115, 97, 103, 101, 67, 108, 97, 115, 115, 116,
+ 0, 17, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 67, 108,
+ 97, 115, 115, 59, 76, 0, 16, 109, 101, 115, 115, 97, 103, 101, 67,
+ 108, 97, 115, 115, 78, 97, 109, 101, 116, 0, 18, 76, 106, 97, 118,
+ 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59,
+ 120, 112, 117, 114, 0, 2, 91, 66, -84, -13, 23, -8, 6, 8, 84, -32,
+ 2, 0, 0, 120, 112, 0, 0, 0, 2, 8, 123, 118, 114, 0, 30, 99, 111,
+ 109, 46, 103, 111, 111, 103, 108, 101, 46, 112, 114, 111, 116, 111,
+ 98, 117, 102, 46, 73, 110, 116, 51, 50, 86, 97, 108, 117, 101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2, 0, 2, 66, 0, 21, 109, 101, 109, 111, 105, 122,
+ 101, 100, 73, 115, 73, 110, 105, 116, 105, 97, 108, 105, 122, 101,
+ 100, 73, 0, 6, 118, 97, 108, 117, 101, 95, 120, 114, 0, 38, 99, 111,
+ 109, 46, 103, 111, 111, 103, 108, 101, 46, 112, 114, 111, 116, 111,
+ 98, 117, 102, 46, 71, 101, 110, 101, 114, 97, 116, 101, 100, 77,
+ 101, 115, 115, 97, 103, 101, 86, 51, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0,
+ 1, 76, 0, 13, 117, 110, 107, 110, 111, 119, 110, 70, 105, 101, 108,
+ 100, 115, 116, 0, 37, 76, 99, 111, 109, 47, 103, 111, 111, 103, 108,
+ 101, 47, 112, 114, 111, 116, 111, 98, 117, 102, 47, 85, 110, 107,
+ 110, 111, 119, 110, 70, 105, 101, 108, 100, 83, 101, 116, 59, 120,
+ 112, 116, 0, 30, 99, 111, 109, 46, 103, 111, 111, 103, 108, 101, 46,
+ 112, 114, 111, 116, 111, 98, 117, 102, 46, 73, 110, 116, 51, 50, 86,
+ 97, 108, 117, 101
+ };
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(int32ValueBytes);
+ ObjectInputStream in = new ObjectInputStream(bais);
+ Int32Value int32Value = (Int32Value) in.readObject();
+ assertEquals(123, int32Value.getValue());
+ }
+
public void testEnumValues() {
assertEquals(TestAllTypes.NestedEnum.BAR_VALUE, TestAllTypes.NestedEnum.BAR.getNumber());
assertEquals(TestAllTypes.NestedEnum.BAZ_VALUE, TestAllTypes.NestedEnum.BAZ.getNumber());
diff --git a/java/pom.xml b/java/pom.xml
index 35d653b4..6526b650 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -11,7 +11,7 @@
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
- <version>3.6.0</version>
+ <version>3.6.1</version>
<packaging>pom</packaging>
<name>Protocol Buffers [Parent]</name>
@@ -92,7 +92,7 @@
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
- <version>3.6.0</version>
+ <version>3.6.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
diff --git a/java/util/pom.xml b/java/util/pom.xml
index 8ea4a40d..f175cf15 100644
--- a/java/util/pom.xml
+++ b/java/util/pom.xml
@@ -6,7 +6,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
- <version>3.6.0</version>
+ <version>3.6.1</version>
</parent>
<artifactId>protobuf-java-util</artifactId>
diff --git a/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java b/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java
index 7b4facc1..86f56ad9 100644
--- a/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java
+++ b/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java
@@ -240,7 +240,7 @@ final class FieldMaskTree {
"Field \""
+ field.getFullName()
+ "\" is not a "
- + "singluar message field and cannot have sub-fields.");
+ + "singular message field and cannot have sub-fields.");
continue;
}
if (!source.hasField(field) && !destination.hasField(field)) {
diff --git a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
index 973f1517..955dfd86 100644
--- a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
+++ b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
@@ -50,6 +50,7 @@ import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.EnumDescriptor;
import com.google.protobuf.Descriptors.EnumValueDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor.Type;
import com.google.protobuf.Descriptors.FileDescriptor;
import com.google.protobuf.Descriptors.OneofDescriptor;
import com.google.protobuf.DoubleValue;
@@ -1539,7 +1540,11 @@ public class JsonFormat {
Object key = parseFieldValue(keyField, new JsonPrimitive(entry.getKey()), entryBuilder);
Object value = parseFieldValue(valueField, entry.getValue(), entryBuilder);
if (value == null) {
- throw new InvalidProtocolBufferException("Map value cannot be null.");
+ if(ignoringUnknownFields && valueField.getType() == Type.ENUM) {
+ continue;
+ } else {
+ throw new InvalidProtocolBufferException("Map value cannot be null.");
+ }
}
entryBuilder.setField(keyField, key);
entryBuilder.setField(valueField, value);
@@ -1557,8 +1562,12 @@ public class JsonFormat {
for (int i = 0; i < array.size(); ++i) {
Object value = parseFieldValue(field, array.get(i), builder);
if (value == null) {
- throw new InvalidProtocolBufferException(
- "Repeated field elements cannot be null in field: " + field.getFullName());
+ if(ignoringUnknownFields && field.getType() == Type.ENUM) {
+ continue;
+ } else {
+ throw new InvalidProtocolBufferException(
+ "Repeated field elements cannot be null in field: " + field.getFullName());
+ }
}
builder.addRepeatedField(field, value);
}
@@ -1748,7 +1757,7 @@ public class JsonFormat {
// an exception later.
}
- if (result == null) {
+ if (result == null && !ignoringUnknownFields) {
throw new InvalidProtocolBufferException(
"Invalid enum value: " + value + " for enum type: " + enumDescriptor.getFullName());
}
diff --git a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
index d9bbe587..7637c267 100644
--- a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
+++ b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
@@ -161,6 +161,10 @@ public class JsonFormatTest extends TestCase {
JsonFormat.parser().merge(json, builder);
}
+ private void mergeFromJsonIgnoringUnknownFields(String json, Message.Builder builder) throws IOException {
+ JsonFormat.parser().ignoringUnknownFields().merge(json, builder);
+ }
+
public void testAllFields() throws Exception {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
setAllFields(builder);
@@ -668,10 +672,22 @@ public class JsonFormatTest extends TestCase {
+ "}",
builder);
fail();
+
} catch (InvalidProtocolBufferException e) {
// Exception expected.
}
}
+
+ public void testMapEnumNullValueIsIgnored() throws Exception {
+ TestMap.Builder builder = TestMap.newBuilder();
+ mergeFromJsonIgnoringUnknownFields(
+ "{\n"
+ + " \"int32ToEnumMap\": {\"1\": null}\n"
+ + "}",
+ builder);
+ TestMap map = builder.build();
+ assertEquals(0, map.getInt32ToEnumMapMap().entrySet().size());
+ }
public void testParserAcceptNonQuotedObjectKey() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
@@ -1172,7 +1188,40 @@ public class JsonFormatTest extends TestCase {
String json = "{\n" + " \"unknownField\": \"XXX\"\n" + "}";
JsonFormat.parser().ignoringUnknownFields().merge(json, builder);
}
-
+
+ public void testParserIgnoringUnknownEnums() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ String json = "{\n" + " \"optionalNestedEnum\": \"XXX\"\n" + "}";
+ JsonFormat.parser().ignoringUnknownFields().merge(json, builder);
+ assertEquals(0, builder.getOptionalNestedEnumValue());
+ }
+
+ public void testUnknownEnumMap() throws Exception {
+ TestMap.Builder builder = TestMap.newBuilder();
+ JsonFormat.parser().ignoringUnknownFields().merge(
+ "{\n"
+ + " \"int32ToEnumMap\": {1: XXX, 2: FOO}"
+ + "}",
+ builder);
+
+ assertEquals(NestedEnum.FOO, builder.getInt32ToEnumMapMap().get(2));
+ assertEquals(1, builder.getInt32ToEnumMapMap().size());
+ }
+
+ public void testRepeatedUnknownEnum() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ JsonFormat.parser().ignoringUnknownFields().merge(
+ "{\n"
+ + " \"repeatedNestedEnum\": [XXX, FOO, BAR, BAZ]"
+ + "}",
+ builder);
+
+ assertEquals(NestedEnum.FOO, builder.getRepeatedNestedEnum(0));
+ assertEquals(NestedEnum.BAR, builder.getRepeatedNestedEnum(1));
+ assertEquals(NestedEnum.BAZ, builder.getRepeatedNestedEnum(2));
+ assertEquals(3, builder.getRepeatedNestedEnumList().size());
+ }
+
public void testParserIntegerEnumValue() throws Exception {
TestAllTypes.Builder actualBuilder = TestAllTypes.newBuilder();
mergeFromJson("{\n" + " \"optionalNestedEnum\": 2\n" + "}", actualBuilder);