This is an automated email from the ASF dual-hosted git repository. yihua pushed a commit to branch release-1.2.0 in repository https://gitbox.apache.org/repos/asf/hudi.git
commit 371e02d2abb759017b4004f2dfc494234f45127e Author: Matthew <[email protected]> AuthorDate: Thu May 7 18:25:28 2026 +0800 fix: Fix reflection ctor signature for AwsGlueCatalogSyncTool in HiveSyncContext (#18697) --- .../apache/hudi/aws/sync/TestAwsGlueSyncTool.java | 31 ++++++++++++++++++++++ .../apache/hudi/sink/utils/HiveSyncContext.java | 6 +++-- .../hudi/sink/utils/TestHiveSyncContext.java | 16 +++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/hudi-aws/src/test/java/org/apache/hudi/aws/sync/TestAwsGlueSyncTool.java b/hudi-aws/src/test/java/org/apache/hudi/aws/sync/TestAwsGlueSyncTool.java index 2135c151cf1f..cbee3fc60f65 100644 --- a/hudi-aws/src/test/java/org/apache/hudi/aws/sync/TestAwsGlueSyncTool.java +++ b/hudi-aws/src/test/java/org/apache/hudi/aws/sync/TestAwsGlueSyncTool.java @@ -21,9 +21,11 @@ package org.apache.hudi.aws.sync; import org.apache.hudi.aws.testutils.GlueTestUtil; import org.apache.hudi.common.config.TypedProperties; import org.apache.hudi.common.util.Option; +import org.apache.hudi.common.util.ReflectionUtils; import org.apache.hudi.sync.common.HoodieSyncTool; import org.apache.hudi.sync.common.util.SyncUtilHelpers; +import org.apache.hadoop.conf.Configuration; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -38,6 +40,7 @@ import software.amazon.awssdk.services.sts.model.GetCallerIdentityRequest; import software.amazon.awssdk.services.sts.model.GetCallerIdentityResponse; import java.io.IOException; +import java.util.Properties; import static org.apache.hudi.aws.testutils.GlueTestUtil.getHadoopConf; import static org.apache.hudi.aws.testutils.GlueTestUtil.glueSyncProps; @@ -105,4 +108,32 @@ class TestAwsGlueSyncTool { syncTool.close(); } } + + /** + * Verifies the 3-arg {@code (Properties, Configuration, Option)} reflection path used by Flink's + * {@code HiveSyncContext#hiveSyncTool()} can fully instantiate {@link AwsGlueCatalogSyncTool}. + */ + @Test + void validateInitThroughHiveSyncContextReflectionSignature() throws Exception { + try (MockedStatic<GlueAsyncClient> mockedStatic = mockStatic(GlueAsyncClient.class); + MockedStatic<StsClient> mockedStsStatic = mockStatic(StsClient.class)) { + GlueAsyncClientBuilder builder = mock(GlueAsyncClientBuilder.class); + mockedStatic.when(GlueAsyncClient::builder).thenReturn(builder); + when(builder.credentialsProvider(any())).thenReturn(builder); + GlueAsyncClient mockClient = mock(GlueAsyncClient.class); + when(builder.build()).thenReturn(mockClient); + StsClient mockSts = mock(StsClient.class); + mockedStsStatic.when(StsClient::create).thenReturn(mockSts); + when(mockSts.getCallerIdentity(GetCallerIdentityRequest.builder().build())) + .thenReturn(GetCallerIdentityResponse.builder().account("").build()); + + Object syncTool = ReflectionUtils.loadClass( + AwsGlueCatalogSyncTool.class.getName(), + new Class<?>[] {Properties.class, Configuration.class, Option.class}, + glueSyncProps, getHadoopConf(), Option.empty()); + assertTrue(syncTool instanceof AwsGlueCatalogSyncTool, + "Reflection through the HiveSyncContext signature must yield an AwsGlueCatalogSyncTool instance"); + ((AwsGlueCatalogSyncTool) syncTool).close(); + } + } } diff --git a/hudi-flink-datasource/hudi-flink/src/main/java/org/apache/hudi/sink/utils/HiveSyncContext.java b/hudi-flink-datasource/hudi-flink/src/main/java/org/apache/hudi/sink/utils/HiveSyncContext.java index 0a34a5ad622b..05b8878c0157 100644 --- a/hudi-flink-datasource/hudi-flink/src/main/java/org/apache/hudi/sink/utils/HiveSyncContext.java +++ b/hudi-flink-datasource/hudi-flink/src/main/java/org/apache/hudi/sink/utils/HiveSyncContext.java @@ -19,6 +19,8 @@ package org.apache.hudi.sink.utils; import org.apache.hudi.common.config.TypedProperties; +import org.apache.hudi.common.table.HoodieTableMetaClient; +import org.apache.hudi.common.util.Option; import org.apache.hudi.common.util.ReflectionUtils; import org.apache.hudi.configuration.FlinkOptions; import org.apache.hudi.configuration.HadoopConfigurations; @@ -78,8 +80,8 @@ public class HiveSyncContext { HiveSyncMode syncMode = HiveSyncMode.of(props.getProperty(HIVE_SYNC_MODE.key())); if (syncMode == HiveSyncMode.GLUE) { return ((HiveSyncTool) ReflectionUtils.loadClass(AWS_GLUE_CATALOG_SYNC_TOOL_CLASS, - new Class<?>[] {Properties.class, org.apache.hadoop.conf.Configuration.class}, - props, hiveConf)); + new Class<?>[] {Properties.class, org.apache.hadoop.conf.Configuration.class, Option.class}, + props, hiveConf, Option.<HoodieTableMetaClient>empty())); } return new HiveSyncTool(props, hiveConf); } diff --git a/hudi-flink-datasource/hudi-flink/src/test/java/org/apache/hudi/sink/utils/TestHiveSyncContext.java b/hudi-flink-datasource/hudi-flink/src/test/java/org/apache/hudi/sink/utils/TestHiveSyncContext.java index dff96350dd7c..f246662b5efe 100644 --- a/hudi-flink-datasource/hudi-flink/src/test/java/org/apache/hudi/sink/utils/TestHiveSyncContext.java +++ b/hudi-flink-datasource/hudi-flink/src/test/java/org/apache/hudi/sink/utils/TestHiveSyncContext.java @@ -18,6 +18,8 @@ package org.apache.hudi.sink.utils; +import org.apache.hudi.common.util.Option; +import org.apache.hudi.common.util.ReflectionUtils; import org.apache.hudi.configuration.FlinkOptions; import org.apache.hudi.hive.HiveSyncConfig; @@ -66,4 +68,18 @@ public class TestHiveSyncContext { Properties props3 = HiveSyncContext.buildSyncConfig(configuration3); assertTrue(Boolean.parseBoolean(props3.getProperty(HiveSyncConfig.HIVE_CREATE_MANAGED_TABLE.key(), "false"))); } + + /** + * Pins the constructor signature {@link HiveSyncContext#hiveSyncTool()} relies on via reflection. + * End-to-end instantiation is covered in {@code hudi-aws}'s {@code TestAwsGlueSyncTool}. + */ + @Test + void testAwsGlueSyncToolReflectionConstructorExists() { + assertTrue( + ReflectionUtils.hasConstructor( + HiveSyncContext.AWS_GLUE_CATALOG_SYNC_TOOL_CLASS, + new Class<?>[] {Properties.class, org.apache.hadoop.conf.Configuration.class, Option.class}), + "AwsGlueCatalogSyncTool must expose the constructor used by HiveSyncContext#hiveSyncTool() " + + "via reflection; otherwise Flink GLUE sync fails with NoSuchMethodException."); + } }
