Skip to content

Commit 554ad3e

Browse files
fix(sql-execute): fail to execute statement on OceanBase 2.2.30 (#1487)
* get actual connection by Proxy#getInvocationHandler * use reflection to get private field * update license
1 parent fc39c04 commit 554ad3e

5 files changed

Lines changed: 132 additions & 1 deletion

File tree

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright (c) 2023 OceanBase.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.oceanbase.odc.common.util;
17+
18+
import java.lang.reflect.Field;
19+
import java.lang.reflect.InvocationHandler;
20+
import java.lang.reflect.Proxy;
21+
22+
/**
23+
* @author liuyizhuo.lyz
24+
* @date 2024/1/30
25+
*/
26+
public class ReflectionUtils {
27+
28+
public static <T> T getProxiedFieldValue(Object any, Class<?> type, String fieldName) {
29+
if (!Proxy.isProxyClass(any.getClass()) || Proxy.getInvocationHandler(any).getClass() != type) {
30+
return null;
31+
}
32+
InvocationHandler handler = Proxy.getInvocationHandler(any);
33+
return getFieldValue(handler, fieldName);
34+
}
35+
36+
public static <T> T getFieldValue(Object any, String fieldName) {
37+
try {
38+
Field field = any.getClass().getDeclaredField(fieldName);
39+
if (!field.isAccessible()) {
40+
field.setAccessible(true);
41+
}
42+
return (T) field.get(any);
43+
} catch (NoSuchFieldException | IllegalAccessException | ClassCastException e) {
44+
return null;
45+
}
46+
}
47+
48+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (c) 2023 OceanBase.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.oceanbase.odc.common.util;
17+
18+
import java.lang.reflect.InvocationHandler;
19+
import java.lang.reflect.Method;
20+
import java.lang.reflect.Proxy;
21+
22+
import org.junit.Assert;
23+
import org.junit.Test;
24+
25+
/**
26+
* @author liuyizhuo.lyz
27+
* @date 2024/1/30
28+
*/
29+
public class ReflectionUtilsTest {
30+
31+
@Test
32+
public void test_getFieldValue() throws NoSuchFieldException, IllegalAccessException {
33+
Pojo pojo = new Pojo("fuzzyname");
34+
Object name = ReflectionUtils.getFieldValue(pojo, "name");
35+
Assert.assertEquals("fuzzyname", name);
36+
}
37+
38+
@Test
39+
public void test_getProxiedFieldValue() throws NoSuchFieldException, IllegalAccessException {
40+
Object instance = Proxy.newProxyInstance(Pojo.class.getClassLoader(), new Class[] {FooInterface.class},
41+
new PojoInvocationHandler(new FooInterface() {}));
42+
Object target = ReflectionUtils.getProxiedFieldValue(instance, PojoInvocationHandler.class, "target");
43+
Assert.assertTrue(target instanceof FooInterface);
44+
}
45+
46+
private static class Pojo {
47+
private final String name;
48+
49+
public Pojo(String name) {
50+
this.name = name;
51+
}
52+
}
53+
54+
private interface FooInterface {
55+
}
56+
57+
private static class PojoInvocationHandler implements InvocationHandler {
58+
59+
private FooInterface target;
60+
61+
public PojoInvocationHandler(FooInterface target) {
62+
this.target = target;
63+
}
64+
65+
@Override
66+
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
67+
return null;
68+
}
69+
}
70+
71+
}

server/odc-core/src/main/java/com/oceanbase/odc/core/datasource/SingleConnectionDataSource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ private Connection innerCreateConnection() throws SQLException {
206206
* @since ODC_release_3.2.2
207207
* @see java.lang.reflect.InvocationHandler
208208
*/
209-
private static class CloseIgnoreInvocationHandler implements InvocationHandler {
209+
public static class CloseIgnoreInvocationHandler implements InvocationHandler {
210210
private final Connection target;
211211
private final Lock lock;
212212

server/plugins/connect-plugin-ob-mysql/src/main/java/com/oceanbase/odc/plugin/connect/obmysql/OBMySQLSessionExtension.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323

2424
import com.oceanbase.jdbc.OceanBaseConnection;
2525
import com.oceanbase.odc.common.util.JdbcOperationsUtil;
26+
import com.oceanbase.odc.common.util.ReflectionUtils;
27+
import com.oceanbase.odc.core.datasource.SingleConnectionDataSource.CloseIgnoreInvocationHandler;
2628
import com.oceanbase.odc.plugin.connect.api.SessionExtensionPoint;
2729

2830
import lombok.extern.slf4j.Slf4j;
@@ -65,6 +67,10 @@ public String getConnectionId(Connection connection) {
6567
} catch (Exception e) {
6668
if (connection instanceof OceanBaseConnection) {
6769
connectionId = ((OceanBaseConnection) connection).getServerThreadId() + "";
70+
} else {
71+
OceanBaseConnection actual =
72+
ReflectionUtils.getProxiedFieldValue(connection, CloseIgnoreInvocationHandler.class, "target");
73+
connectionId = actual == null ? "" : actual.getServerThreadId() + "";
6874
}
6975
}
7076
return connectionId;

server/plugins/connect-plugin-ob-oracle/src/main/java/com/oceanbase/odc/plugin/connect/oboracle/OBOracleSessionExtension.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323

2424
import com.oceanbase.jdbc.OceanBaseConnection;
2525
import com.oceanbase.odc.common.util.JdbcOperationsUtil;
26+
import com.oceanbase.odc.common.util.ReflectionUtils;
2627
import com.oceanbase.odc.common.util.StringUtils;
28+
import com.oceanbase.odc.core.datasource.SingleConnectionDataSource.CloseIgnoreInvocationHandler;
2729
import com.oceanbase.odc.plugin.connect.api.SessionExtensionPoint;
2830

2931
import lombok.extern.slf4j.Slf4j;
@@ -67,6 +69,10 @@ public String getConnectionId(Connection connection) {
6769
} catch (Exception e) {
6870
if (connection instanceof OceanBaseConnection) {
6971
connectionId = ((OceanBaseConnection) connection).getServerThreadId() + "";
72+
} else {
73+
OceanBaseConnection actual =
74+
ReflectionUtils.getProxiedFieldValue(connection, CloseIgnoreInvocationHandler.class, "target");
75+
connectionId = actual == null ? "" : actual.getServerThreadId() + "";
7076
}
7177
}
7278
return connectionId;

0 commit comments

Comments
 (0)