Repository: flink Updated Branches: refs/heads/release-1.1 d3d6907b5 -> 5133bf9ea
[FLINK-4977] [core] Fix enum serializer to use proper access to enum constants Project: http://git-wip-us.apache.org/repos/asf/flink/repo Commit: http://git-wip-us.apache.org/repos/asf/flink/commit/5133bf9e Tree: http://git-wip-us.apache.org/repos/asf/flink/tree/5133bf9e Diff: http://git-wip-us.apache.org/repos/asf/flink/diff/5133bf9e Branch: refs/heads/release-1.1 Commit: 5133bf9ea4c9633ad3aa840f81f6dedaa0026994 Parents: d3d6907 Author: Stephan Ewen <[email protected]> Authored: Fri Nov 4 14:16:38 2016 +0100 Committer: Stephan Ewen <[email protected]> Committed: Fri Nov 4 14:51:31 2016 +0100 ---------------------------------------------------------------------- .../common/typeutils/base/EnumSerializer.java | 25 +++---- .../typeutils/SerializerTestInstance.java | 9 +-- .../typeutils/base/EnumSerializerTest.java | 70 ++++++++++++++++++++ 3 files changed, 83 insertions(+), 21 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flink/blob/5133bf9e/flink-core/src/main/java/org/apache/flink/api/common/typeutils/base/EnumSerializer.java ---------------------------------------------------------------------- diff --git a/flink-core/src/main/java/org/apache/flink/api/common/typeutils/base/EnumSerializer.java b/flink-core/src/main/java/org/apache/flink/api/common/typeutils/base/EnumSerializer.java index 21a6ea0..c45487f 100644 --- a/flink-core/src/main/java/org/apache/flink/api/common/typeutils/base/EnumSerializer.java +++ b/flink-core/src/main/java/org/apache/flink/api/common/typeutils/base/EnumSerializer.java @@ -20,13 +20,13 @@ package org.apache.flink.api.common.typeutils.base; import java.io.IOException; import java.io.ObjectInputStream; -import java.lang.reflect.Method; import org.apache.flink.annotation.Internal; import org.apache.flink.api.common.typeutils.TypeSerializer; import org.apache.flink.core.memory.DataInputView; import org.apache.flink.core.memory.DataOutputView; +import static org.apache.flink.util.Preconditions.checkArgument; import static org.apache.flink.util.Preconditions.checkNotNull; @Internal @@ -34,13 +34,16 @@ public final class EnumSerializer<T extends Enum<T>> extends TypeSerializer<T> { private static final long serialVersionUID = 1L; - private transient T[] values; - private final Class<T> enumClass; + private transient T[] values; + public EnumSerializer(Class<T> enumClass) { this.enumClass = checkNotNull(enumClass); - this.values = createValues(enumClass); + checkArgument(Enum.class.isAssignableFrom(enumClass), "not an enum"); + + this.values = enumClass.getEnumConstants(); + checkArgument(this.values.length > 0, "cannot use an empty enum"); } @Override @@ -118,18 +121,6 @@ public final class EnumSerializer<T extends Enum<T>> extends TypeSerializer<T> { private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); - this.values = createValues(this.enumClass); - } - - @SuppressWarnings("unchecked") - private static <T> T[] createValues(Class<T> enumClass) { - try { - Method valuesMethod = enumClass.getMethod("values"); - return (T[]) valuesMethod.invoke(null); - - } - catch (Exception e) { - throw new RuntimeException("Cannot access the constants of the enum " + enumClass.getName()); - } + this.values = enumClass.getEnumConstants(); } } http://git-wip-us.apache.org/repos/asf/flink/blob/5133bf9e/flink-core/src/test/java/org/apache/flink/api/common/typeutils/SerializerTestInstance.java ---------------------------------------------------------------------- diff --git a/flink-core/src/test/java/org/apache/flink/api/common/typeutils/SerializerTestInstance.java b/flink-core/src/test/java/org/apache/flink/api/common/typeutils/SerializerTestInstance.java index 7f65995..a720758 100644 --- a/flink-core/src/test/java/org/apache/flink/api/common/typeutils/SerializerTestInstance.java +++ b/flink-core/src/test/java/org/apache/flink/api/common/typeutils/SerializerTestInstance.java @@ -24,13 +24,14 @@ public class SerializerTestInstance<T> extends SerializerTestBase<T> { private final TypeSerializer<T> serializer; private final Class<T> typeClass; - + private final int length; - + private final T[] testData; - + // -------------------------------------------------------------------------------------------- - + + @SafeVarargs public SerializerTestInstance(TypeSerializer<T> serializer, Class<T> typeClass, int length, T... testData) { this.serializer = serializer; this.typeClass = typeClass; http://git-wip-us.apache.org/repos/asf/flink/blob/5133bf9e/flink-core/src/test/java/org/apache/flink/api/common/typeutils/base/EnumSerializerTest.java ---------------------------------------------------------------------- diff --git a/flink-core/src/test/java/org/apache/flink/api/common/typeutils/base/EnumSerializerTest.java b/flink-core/src/test/java/org/apache/flink/api/common/typeutils/base/EnumSerializerTest.java new file mode 100644 index 0000000..5e2e733 --- /dev/null +++ b/flink-core/src/test/java/org/apache/flink/api/common/typeutils/base/EnumSerializerTest.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.flink.api.common.typeutils.base; + +import org.apache.flink.api.common.typeutils.SerializerTestInstance; +import org.apache.flink.util.TestLogger; + +import org.junit.Test; + +public class EnumSerializerTest extends TestLogger { + + @Test + public void testPublicEnum() { + testEnumSerializer(PrivateEnum.ONE, PrivateEnum.TWO, PrivateEnum.THREE); + } + + @Test + public void testPrivateEnum() { + testEnumSerializer(PublicEnum.FOO, PublicEnum.BAR, PublicEnum.PETER, PublicEnum.NATHANIEL, + PublicEnum.EMMA, PublicEnum.PAULA); + } + + @Test(expected = IllegalArgumentException.class) + public void testEmptyEnum() { + new EnumSerializer<>(EmptyEnum.class); + } + + @SafeVarargs + public final <T extends Enum<T>> void testEnumSerializer(T... data) { + @SuppressWarnings("unchecked") + final Class<T> clazz = (Class<T>) data.getClass().getComponentType(); + + SerializerTestInstance<T> tester = new SerializerTestInstance<>( + new EnumSerializer<T>(clazz), clazz, 4, data); + + tester.testAll(); + } + + + + // ------------------------------------------------------------------------ + // Test enums + // ------------------------------------------------------------------------ + + public enum PublicEnum { + FOO, BAR, PETER, NATHANIEL, EMMA, PAULA + } + + public enum EmptyEnum {} + + private enum PrivateEnum { + ONE, TWO, THREE + } +}
