如何在 Java 中禁止特定方法(来自外部库)?

How to forbid specific methods (from external lib) in Java?

我找不到很多关于我的问题的资源,所以我想这不是一个简单的解决方案。

我们在代码库中使用 JodaTime,我希望禁止(或至少警告)使用此库中的某些方法,因为它们容易出错(围绕时区管理)。

我已经尝试了反射库,但由于未发布的问题而没有成功。 我们曾经有一个自定义声纳规则来处理这个问题,但声纳云不支持它,所以我正在寻找另一种方法。

你有线索来处理这个吗?

我通过编写如下拦截器解决了此类问题,如 https://docs.oracle.com/javaee/7/tutorial/interceptors002.htm 所述:

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

public class MethodCallTracerInterceptor {

    @AroundInvoke
    Object intercept(InvocationContext context)
        throws Exception
    {
        Method method      = context.getMethod();
        String methodClass = method.getDeclaringClass().getName();
        String methodName  = method.getName();

        if (methodClass.equals("myClass") && methodName.equals("myMethod")) {
            //TODO Raise an exception or log a warning.
        }

        return context.proceed();
    }

}

我建议为此使用 ArchUnit,它允许您指定像这样的限制作为单元测试:

public class DisallowedMethodsTest {
    @Test
    public void forbidJodaTimeMethods()
    {
        JavaClasses importedClasses = new ClassFileImporter().importPackages("your.base.package");

        ArchRule rule = noClasses().should()
            .callMethodWhere(target(name("disallowedMethodName"))
                .and(target(owner(assignableTo(DateTime.class)))))
            .because("Your reasons");

        rule.check(importedClasses);
    }
}

如果您正在寻找在单元测试环境中工作的东西,

如果您正在寻找在生产环境中工作的东西,您将需要 HOOK


如果您不能要求合作伙伴使用 java.lang.reflect.Proxy 来构造相关对象,如果您正在处理常规 Java 项目,我建议您查看 AspectJXposed 如果您正在从事 Android 项目。

他们都可以在不修改现有代码库或编程流程的情况下添加限制。