This is an automated email from the ASF dual-hosted git repository.
etudenhoefner pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg.git
The following commit(s) were added to refs/heads/main by this push:
new c469edf6cd Common: DynConstructors cleanup (#10542)
c469edf6cd is described below
commit c469edf6cd241e848d3926a07d978cc4b5994cc5
Author: Piotr Findeisen <[email protected]>
AuthorDate: Fri Jun 28 11:32:05 2024 +0200
Common: DynConstructors cleanup (#10542)
The `DynConstructors.Builder.hiddenImpl(Class<?>...)` is a varargs
method, but cannot be used as such, because `hiddenImpl(Class<T>,
Class<?>...)` exists and would be used instead. Since there are no
usages, deprecate it instead of fixing.
---
.../org/apache/iceberg/common/DynConstructors.java | 34 ++++++----
.../apache/iceberg/common/TestDynConstructors.java | 75 ++++++++++++++++++++++
2 files changed, 95 insertions(+), 14 deletions(-)
diff --git
a/common/src/main/java/org/apache/iceberg/common/DynConstructors.java
b/common/src/main/java/org/apache/iceberg/common/DynConstructors.java
index 4761be4f3e..7c77711287 100644
--- a/common/src/main/java/org/apache/iceberg/common/DynConstructors.java
+++ b/common/src/main/java/org/apache/iceberg/common/DynConstructors.java
@@ -43,6 +43,8 @@ public class DynConstructors {
this.constructed = constructed;
}
+ /** @deprecated since 1.6.0, will be removed in 1.7.0 */
+ @Deprecated
public Class<? extends C> getConstructedClass() {
return constructed;
}
@@ -57,9 +59,9 @@ public class DynConstructors {
} catch (InstantiationException | IllegalAccessException e) {
throw e;
} catch (InvocationTargetException e) {
- Throwables.propagateIfInstanceOf(e.getCause(), Exception.class);
- Throwables.propagateIfInstanceOf(e.getCause(), RuntimeException.class);
- throw Throwables.propagate(e.getCause());
+ Throwables.throwIfInstanceOf(e.getCause(), Exception.class);
+ Throwables.throwIfInstanceOf(e.getCause(), RuntimeException.class);
+ throw new RuntimeException(e.getCause());
}
}
@@ -67,8 +69,8 @@ public class DynConstructors {
try {
return newInstanceChecked(args);
} catch (Exception e) {
- Throwables.propagateIfInstanceOf(e, RuntimeException.class);
- throw Throwables.propagate(e);
+ Throwables.throwIfInstanceOf(e, RuntimeException.class);
+ throw new RuntimeException(e.getCause());
}
}
@@ -115,8 +117,8 @@ public class DynConstructors {
public static class Builder {
private final Class<?> baseClass;
private ClassLoader loader =
Thread.currentThread().getContextClassLoader();
- private Ctor ctor = null;
- private Map<String, Throwable> problems = Maps.newHashMap();
+ private Ctor<?> ctor = null;
+ private final Map<String, Throwable> problems = Maps.newHashMap();
public Builder(Class<?> baseClass) {
this.baseClass = baseClass;
@@ -162,7 +164,7 @@ public class DynConstructors {
}
try {
- ctor = new Ctor<T>(targetClass.getConstructor(types), targetClass);
+ ctor = new Ctor<>(targetClass.getConstructor(types), targetClass);
} catch (NoSuchMethodException e) {
// not the right implementation
problems.put(methodName(targetClass, types), e);
@@ -170,12 +172,16 @@ public class DynConstructors {
return this;
}
+ /**
+ * @deprecated since 1.6.0, will be removed in 1.7.0; This varargs method
conflicts with {@link
+ * #hiddenImpl(Class, Class...)}. Use {@link #builder(Class)} instead.
+ */
+ @Deprecated
public Builder hiddenImpl(Class<?>... types) {
hiddenImpl(baseClass, types);
return this;
}
- @SuppressWarnings("unchecked")
public Builder hiddenImpl(String className, Class<?>... types) {
// don't do any work if an implementation has been found
if (ctor != null) {
@@ -183,7 +189,7 @@ public class DynConstructors {
}
try {
- Class targetClass = Class.forName(className, true, loader);
+ Class<?> targetClass = Class.forName(className, true, loader);
hiddenImpl(targetClass, types);
} catch (NoClassDefFoundError | ClassNotFoundException e) {
// cannot load this implementation
@@ -201,7 +207,7 @@ public class DynConstructors {
try {
Constructor<T> hidden = targetClass.getDeclaredConstructor(types);
AccessController.doPrivileged(new MakeAccessible(hidden));
- ctor = new Ctor<T>(hidden, targetClass);
+ ctor = new Ctor<>(hidden, targetClass);
} catch (SecurityException e) {
// unusable
problems.put(methodName(targetClass, types), e);
@@ -215,7 +221,7 @@ public class DynConstructors {
@SuppressWarnings("unchecked")
public <C> Ctor<C> buildChecked() throws NoSuchMethodException {
if (ctor != null) {
- return ctor;
+ return (Ctor<C>) ctor;
}
throw buildCheckedException(baseClass, problems);
}
@@ -223,14 +229,14 @@ public class DynConstructors {
@SuppressWarnings("unchecked")
public <C> Ctor<C> build() {
if (ctor != null) {
- return ctor;
+ return (Ctor<C>) ctor;
}
throw buildRuntimeException(baseClass, problems);
}
}
private static class MakeAccessible implements PrivilegedAction<Void> {
- private Constructor<?> hidden;
+ private final Constructor<?> hidden;
MakeAccessible(Constructor<?> hidden) {
this.hidden = hidden;
diff --git
a/common/src/test/java/org/apache/iceberg/common/TestDynConstructors.java
b/common/src/test/java/org/apache/iceberg/common/TestDynConstructors.java
new file mode 100644
index 0000000000..baddcc8e2f
--- /dev/null
+++ b/common/src/test/java/org/apache/iceberg/common/TestDynConstructors.java
@@ -0,0 +1,75 @@
+/*
+ * 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.iceberg.common;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import org.junit.jupiter.api.Test;
+
+public class TestDynConstructors {
+ @Test
+ public void testImplNewInstance() throws Exception {
+ DynConstructors.Ctor<MyClass> ctor =
+ DynConstructors.builder().impl(MyClass.class).buildChecked();
+ assertThat(ctor.newInstance()).isInstanceOf(MyClass.class);
+ }
+
+ @Test
+ public void testInterfaceImplNewInstance() throws Exception {
+ DynConstructors.Ctor<MyInterface> ctor =
+ DynConstructors.builder(MyInterface.class)
+ .impl("org.apache.iceberg.common.TestDynConstructors$MyClass")
+ .buildChecked();
+ assertThat(ctor.newInstance()).isInstanceOf(MyClass.class);
+ }
+
+ @Test
+ public void testInterfaceWrongImplString() throws Exception {
+ DynConstructors.Ctor<MyInterface> ctor =
+ DynConstructors.builder(MyInterface.class)
+ // TODO this should throw, since the MyUnrelatedClass does not
implement MyInterface
+
.impl("org.apache.iceberg.common.TestDynConstructors$MyUnrelatedClass")
+ .buildChecked();
+ assertThatThrownBy(ctor::newInstance)
+ .isInstanceOf(ClassCastException.class)
+ .hasMessage(
+ "org.apache.iceberg.common.TestDynConstructors$MyUnrelatedClass
cannot be cast to org.apache.iceberg.common.TestDynConstructors$MyInterface");
+ }
+
+ @Test
+ public void testInterfaceWrongImplClass() throws Exception {
+ DynConstructors.Ctor<MyInterface> ctor =
+ DynConstructors.builder(MyInterface.class)
+ // TODO this should throw or not compile at all, since the
MyUnrelatedClass does not
+ // implement MyInterface
+ .impl(MyUnrelatedClass.class)
+ .buildChecked();
+ assertThatThrownBy(ctor::newInstance)
+ .isInstanceOf(ClassCastException.class)
+ .hasMessage(
+ "org.apache.iceberg.common.TestDynConstructors$MyUnrelatedClass
cannot be cast to org.apache.iceberg.common.TestDynConstructors$MyInterface");
+ }
+
+ public interface MyInterface {}
+
+ public static class MyClass implements MyInterface {}
+
+ public static class MyUnrelatedClass {}
+}