Copilot commented on code in PR #7867:
URL: https://github.com/apache/incubator-seata/pull/7867#discussion_r2633446019
##########
integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java:
##########
@@ -89,17 +94,40 @@ protected boolean existsAnnotation(Class<?>... classes) {
return true;
}
Method[] methods = clazz.getMethods();
- for (Method method : methods) {
- trxAnno = method.getAnnotation(GlobalTransactional.class);
- if (trxAnno != null) {
- methodsToProxy.add(method.getName());
- result = true;
- }
+ Method[] declaredMethods = clazz.getDeclaredMethods();
+ int arrayLength = methods.length + declaredMethods.length;
+ if (arrayLength > 0) {
+ Method[] allMethods = new Method[arrayLength];
+ System.arraycopy(methods, 0, allMethods, 0,
methods.length);
+ System.arraycopy(declaredMethods, 0, allMethods,
methods.length, declaredMethods.length);
+ Set<Method> processedMethods = new HashSet<>();
+ for (Method method : allMethods) {
+ if (!processedMethods.add(method)) {
+ continue;
+ }
+ trxAnno =
method.getAnnotation(GlobalTransactional.class);
+ if (trxAnno != null) {
+ methodsToProxy.add(method.getName());
+ if (!Modifier.isPrivate(method.getModifiers())) {
+ result = true;
+ } else {
+ LOGGER.warn(
+ "GlobalTransactional annotation found
on private method {}, which will be ignored.",
+ method.getName());
+ }
+ }
- GlobalLock lockAnno =
method.getAnnotation(GlobalLock.class);
- if (lockAnno != null) {
- methodsToProxy.add(method.getName());
- result = true;
+ GlobalLock lockAnno =
method.getAnnotation(GlobalLock.class);
+ if (lockAnno != null) {
+ methodsToProxy.add(method.getName());
+ if (!Modifier.isPrivate(method.getModifiers())) {
+ result = true;
+ } else {
+ LOGGER.warn(
+ "GlobalLock annotation found on
private method {}, which will be ignored.",
+ method.getName());
+ }
Review Comment:
Private methods with GlobalLock annotation are still being added to the
methodsToProxy set even though they should be ignored. The check on line 123
only affects the result boolean but doesn't prevent adding the method name to
methodsToProxy on line 122. This means private methods will be included in the
proxy set, which contradicts the intent of filtering them out. Consider moving
line 122 inside the non-private check block so that only non-private annotated
methods are added to methodsToProxy.
##########
integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java:
##########
@@ -89,17 +94,40 @@ protected boolean existsAnnotation(Class<?>... classes) {
return true;
}
Method[] methods = clazz.getMethods();
- for (Method method : methods) {
- trxAnno = method.getAnnotation(GlobalTransactional.class);
- if (trxAnno != null) {
- methodsToProxy.add(method.getName());
- result = true;
- }
+ Method[] declaredMethods = clazz.getDeclaredMethods();
+ int arrayLength = methods.length + declaredMethods.length;
+ if (arrayLength > 0) {
+ Method[] allMethods = new Method[arrayLength];
+ System.arraycopy(methods, 0, allMethods, 0,
methods.length);
+ System.arraycopy(declaredMethods, 0, allMethods,
methods.length, declaredMethods.length);
+ Set<Method> processedMethods = new HashSet<>();
+ for (Method method : allMethods) {
+ if (!processedMethods.add(method)) {
+ continue;
+ }
+ trxAnno =
method.getAnnotation(GlobalTransactional.class);
+ if (trxAnno != null) {
+ methodsToProxy.add(method.getName());
+ if (!Modifier.isPrivate(method.getModifiers())) {
+ result = true;
+ } else {
+ LOGGER.warn(
+ "GlobalTransactional annotation found
on private method {}, which will be ignored.",
+ method.getName());
+ }
Review Comment:
Private methods are still being added to the methodsToProxy set even though
they should be ignored. The check on line 112 only affects the result boolean
but doesn't prevent adding the method name to methodsToProxy on line 111. This
means private methods will be included in the proxy set, which contradicts the
intent of filtering them out. Consider moving line 111 inside the non-private
check block so that only non-private annotated methods are added to
methodsToProxy.
##########
integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java:
##########
@@ -89,17 +94,40 @@ protected boolean existsAnnotation(Class<?>... classes) {
return true;
}
Method[] methods = clazz.getMethods();
- for (Method method : methods) {
- trxAnno = method.getAnnotation(GlobalTransactional.class);
- if (trxAnno != null) {
- methodsToProxy.add(method.getName());
- result = true;
- }
+ Method[] declaredMethods = clazz.getDeclaredMethods();
+ int arrayLength = methods.length + declaredMethods.length;
+ if (arrayLength > 0) {
+ Method[] allMethods = new Method[arrayLength];
+ System.arraycopy(methods, 0, allMethods, 0,
methods.length);
+ System.arraycopy(declaredMethods, 0, allMethods,
methods.length, declaredMethods.length);
+ Set<Method> processedMethods = new HashSet<>();
Review Comment:
Creating a combined array of methods and declaredMethods using
System.arraycopy is inefficient when both arrays could be processed separately
in consecutive loops. Consider processing methods array first, then
declaredMethods array, using a single Set to track processed methods across
both loops. This would avoid the unnecessary array allocation and copying.
##########
integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java:
##########
@@ -89,17 +94,40 @@ protected boolean existsAnnotation(Class<?>... classes) {
return true;
}
Method[] methods = clazz.getMethods();
- for (Method method : methods) {
- trxAnno = method.getAnnotation(GlobalTransactional.class);
- if (trxAnno != null) {
- methodsToProxy.add(method.getName());
- result = true;
- }
+ Method[] declaredMethods = clazz.getDeclaredMethods();
+ int arrayLength = methods.length + declaredMethods.length;
+ if (arrayLength > 0) {
+ Method[] allMethods = new Method[arrayLength];
+ System.arraycopy(methods, 0, allMethods, 0,
methods.length);
+ System.arraycopy(declaredMethods, 0, allMethods,
methods.length, declaredMethods.length);
+ Set<Method> processedMethods = new HashSet<>();
+ for (Method method : allMethods) {
+ if (!processedMethods.add(method)) {
+ continue;
+ }
+ trxAnno =
method.getAnnotation(GlobalTransactional.class);
+ if (trxAnno != null) {
+ methodsToProxy.add(method.getName());
+ if (!Modifier.isPrivate(method.getModifiers())) {
+ result = true;
+ } else {
+ LOGGER.warn(
+ "GlobalTransactional annotation found
on private method {}, which will be ignored.",
+ method.getName());
+ }
+ }
- GlobalLock lockAnno =
method.getAnnotation(GlobalLock.class);
- if (lockAnno != null) {
- methodsToProxy.add(method.getName());
- result = true;
+ GlobalLock lockAnno =
method.getAnnotation(GlobalLock.class);
+ if (lockAnno != null) {
+ methodsToProxy.add(method.getName());
+ if (!Modifier.isPrivate(method.getModifiers())) {
+ result = true;
+ } else {
+ LOGGER.warn(
+ "GlobalLock annotation found on
private method {}, which will be ignored.",
+ method.getName());
+ }
Review Comment:
The logic for checking GlobalTransactional and GlobalLock annotations is
duplicated. Both blocks check for the annotation, add the method to
methodsToProxy, verify it's not private, and log a warning if it is private.
Consider extracting this repeated logic into a helper method that takes the
annotation and annotation name as parameters to reduce code duplication and
improve maintainability.
##########
integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java:
##########
@@ -26,13 +26,18 @@
import org.apache.seata.spring.annotation.GlobalLock;
import org.apache.seata.spring.annotation.GlobalTransactional;
import org.apache.seata.tm.api.FailureHandlerHolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.util.HashSet;
Review Comment:
The Arrays import is added but never used in the code. Consider removing
this unused import to keep the code clean.
##########
integration-tx-api/src/test/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParserTest.java:
##########
@@ -38,4 +38,19 @@ void parserInterfaceToProxy() throws Exception {
// then
Assertions.assertNotNull(proxyInvocationHandler);
}
+
+ @Test
+ void parserInterfaceToProxyNonPrivateMethod() throws Exception {
+ MethodImpl method = new MethodImpl();
+
+ GlobalTransactionalInterceptorParser
globalTransactionalInterceptorParser =
+ new GlobalTransactionalInterceptorParser();
+
+ ProxyInvocationHandler proxyInvocationHandler =
globalTransactionalInterceptorParser.parserInterfaceToProxy(
+ method, method.getClass().getName());
+
+ Assertions.assertNotNull(proxyInvocationHandler);
+
+ Assertions.assertEquals(2,
proxyInvocationHandler.getMethodsToProxy().size());
Review Comment:
The test expects 2 methods in methodsToProxy, but due to a bug in the
implementation where private methods are still added to the set (despite being
ignored for proxying), this will actually be 3. The MethodImpl class has three
annotated methods: dftMethod (package-private), protectedMethod (protected),
and privateMethod (private). Once the bug is fixed to exclude private methods
from methodsToProxy, this assertion will be correct, but currently it will fail.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]