mpetitdant
mpetitdant

Reputation: 75

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

I could not find much resources on my question so I guess this is not an easy resolution.

We use JodaTime in our codebase and I wish to forbid (or at least warn) using some methods from this library as they are prone to errors (around timezone management).

I tried the reflections library already, without success due to a non released issue. We used to have a custom sonar rule to handle this but it is not supported by sonarcloud so I looking for another way.

Do you have any lead to handle this?

Upvotes: 2

Views: 326

Answers (3)

DevDengChao
DevDengChao

Reputation: 308

If you are looking for something works in unit test environment, Jeroen Steenbeeke' answer might be helpful.

If you are looking for something works in production environmen, you'll need HOOK.


In case you cannot require partners to use java.lang.reflect.Proxy to construct related object, I'd recommend you have a look on AspectJ if you are working on a regular Java project or Xposed if you are working on an Android project.

Both of them could add restrictions without modifing existing codebase nor programming flow.

Upvotes: 1

Jeroen Steenbeeke
Jeroen Steenbeeke

Reputation: 4013

I would recommend using ArchUnit for this, which allows you to specify restrictions such as this as unit tests:

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);
    }
}

Upvotes: 4

Antonio Petricca
Antonio Petricca

Reputation: 11006

I solved such kind of problems by writing an interceptor like the following, as explained at 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();
    }

}

Upvotes: 0

Related Questions