This is an automated email from the ASF dual-hosted git repository.

jinsongzhou pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/amoro.git


The following commit(s) were added to refs/heads/master by this push:
     new 6ead3dc5f [Improvement] refactor krb5 avoid starting error in idea 
(#3377)
6ead3dc5f is described below

commit 6ead3dc5fd8b6c0379520962c80411bfcef08cc4
Author: sunshine <[email protected]>
AuthorDate: Fri Jan 10 15:27:20 2025 +0800

    [Improvement] refactor krb5 avoid starting error in idea (#3377)
    
    * try to start up error
    
    * update,remove unused codes
    
    * update,remove unused codes
    
    * add utils for reflection and deal with IBM JDK
    
    * add utils for reflection and deal with IBM JDK
    
    * add utils for reflection and deal with IBM JDK
    
    * format style
    
    * format style
    
    * format style
    
    * add ut
    
    * add ut
    
    * add ut
---
 .../org/apache/amoro/table/TableMetaStore.java     | 12 +++--
 .../org/apache/amoro/utils/ReflectionUtils.java    | 55 ++++++++++++++++++++++
 .../apache/amoro/utils/ReflectionUtilsTest.java    | 50 ++++++++++++++++++++
 3 files changed, 113 insertions(+), 4 deletions(-)

diff --git 
a/amoro-common/src/main/java/org/apache/amoro/table/TableMetaStore.java 
b/amoro-common/src/main/java/org/apache/amoro/table/TableMetaStore.java
index 4bf9b732f..1bd0c56bb 100644
--- a/amoro-common/src/main/java/org/apache/amoro/table/TableMetaStore.java
+++ b/amoro-common/src/main/java/org/apache/amoro/table/TableMetaStore.java
@@ -25,6 +25,7 @@ import 
org.apache.amoro.shade.guava32.com.google.common.base.Strings;
 import org.apache.amoro.shade.guava32.com.google.common.collect.Maps;
 import org.apache.amoro.shade.guava32.com.google.common.hash.Hashing;
 import org.apache.amoro.shade.guava32.com.google.common.io.ByteStreams;
+import org.apache.amoro.utils.ReflectionUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -35,7 +36,6 @@ import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.security.authentication.util.KerberosName;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import sun.security.krb5.KrbException;
 
 import java.io.ByteArrayInputStream;
 import java.io.FileOutputStream;
@@ -383,7 +383,7 @@ public class TableMetaStore implements Serializable {
             constructKerberosUgi();
           }
           LOG.info("Completed to build ugi {}", authInformation());
-        } catch (IOException | KrbException e) {
+        } catch (Exception e) {
           throw new RuntimeException("Fail to init user group information", e);
         }
       } else {
@@ -407,13 +407,17 @@ public class TableMetaStore implements Serializable {
       return ugi;
     }
 
-    private void constructKerberosUgi() throws IOException, KrbException {
+    private void constructKerberosUgi() throws Exception {
       Path confPath = generateKrbConfPath();
       String krbConfFile = saveConfInPath(confPath, KRB_CONF_FILE_NAME, 
krbConf);
       String keyTabFile = saveConfInPath(confPath, KEY_TAB_FILE_NAME, 
krbKeyTab);
       System.clearProperty(HADOOP_USER_PROPERTY);
       System.setProperty(KRB5_CONF_PROPERTY, krbConfFile);
-      sun.security.krb5.Config.refresh();
+      if (System.getProperty("java.vendor").contains("IBM")) {
+        ReflectionUtils.invoke("com.ibm.security.krb5.internal.Config", 
"refresh");
+      } else {
+        ReflectionUtils.invoke("sun.security.krb5.Config", "refresh");
+      }
       UserGroupInformation.setConfiguration(getConfiguration());
       KerberosName.resetDefaultRealm();
       this.ugi = 
UserGroupInformation.loginUserFromKeytabAndReturnUGI(krbPrincipal, keyTabFile);
diff --git 
a/amoro-common/src/main/java/org/apache/amoro/utils/ReflectionUtils.java 
b/amoro-common/src/main/java/org/apache/amoro/utils/ReflectionUtils.java
new file mode 100644
index 000000000..a60e4c3f7
--- /dev/null
+++ b/amoro-common/src/main/java/org/apache/amoro/utils/ReflectionUtils.java
@@ -0,0 +1,55 @@
+/*
+ * 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.amoro.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+public class ReflectionUtils {
+
+  private static final Logger LOG = 
LoggerFactory.getLogger(ReflectionUtils.class);
+  private static final Map<String, Class> CLASS_MAP = new HashMap<>();
+
+  public static Object invoke(String className, String methodName)
+      throws InvocationTargetException, IllegalAccessException, 
NoSuchMethodException {
+    Class<?> classRef =
+        CLASS_MAP.computeIfAbsent(
+            className,
+            key -> {
+              try {
+                return Class.forName(className);
+              } catch (ClassNotFoundException e) {
+                // ignore error
+                return null;
+              }
+            });
+    if (Objects.isNull(classRef)) {
+      LOG.warn("cannot load class {}, skip execute method {}", className, 
methodName);
+      return null;
+    }
+    Method method = classRef.getDeclaredMethod(methodName);
+    return method.invoke(null);
+  }
+}
diff --git 
a/amoro-common/src/test/java/org/apache/amoro/utils/ReflectionUtilsTest.java 
b/amoro-common/src/test/java/org/apache/amoro/utils/ReflectionUtilsTest.java
new file mode 100644
index 000000000..46931101d
--- /dev/null
+++ b/amoro-common/src/test/java/org/apache/amoro/utils/ReflectionUtilsTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.amoro.utils;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import org.junit.jupiter.api.Test;
+
+class ReflectionUtilsTest {
+
+  @Test
+  void testInvokeValidClassAndMethod() {
+    try {
+      // Invoke the static method in TestClass
+      Object result = ReflectionUtils.invoke("java.lang.System", 
"currentTimeMillis");
+      assertNotNull(result);
+    } catch (Exception e) {
+      fail("Invocation failed: " + e.getMessage());
+    }
+  }
+
+  @Test
+  void testInvokeNonExistentClass() {
+    try {
+      Object result =
+          ReflectionUtils.invoke("com.example.nonexistent.NonExistentClass", 
"testMethod");
+      assertNull(result); // The method should return null for non-existent 
class
+    } catch (Exception e) {
+      fail("Exception should not be thrown for non-existent class: " + 
e.getMessage());
+    }
+  }
+}

Reply via email to