Как предотвратить вызов метода? - PullRequest
1 голос
/ 22 сентября 2019

Как я могу предотвратить вызов метода?Он находится в классе, импортированном из jar, и, следовательно, я не могу редактировать класс.

Причина : Я хочу предотвратить это, поскольку этот метод вызывает другой API REST и получает несколько значенийоттуда, что мне не нужно.Если есть какой-либо способ превзойти http-вызов, это также сработает.

Пример кода:

public class class_name {
  public void method_name() {
    method1();
    method2();
    method3();
  }
  public void method1() {
  }
  public void method2() {
  }
  public void method3() {
  }
}

Я хочу запретить method2()от вызова.Есть какой-либо способ сделать это?Поскольку мне нужно использовать этот класс только без этого метода.

Кроме того, этот класс также вызывается изнутри другим классом, импортированным из jar.

Ответы [ 4 ]

1 голос
/ 22 сентября 2019

Может быть сделано с аспектами.

Следующий пример относится к реализации Spring AOP:

@Aspect
@Component
public class MethodCallPreventAspect {

    @Pointcut("execution(* com.thirdpartylib.class_name.method2(..))")
    public void thirdParty() {
    }

    @Around("thirdParty()")
    public Object preventInvocation(ProceedingJoinPoint pjp) throws Throwable {
         // return pjp.proceed(); // original behaviour
         return null; // invocation is bypassed
    }
}

Чтобы все заработало, просто поместите аннотацию @EnableAspectJAutoProxy в любой класс конфигурации (@Configuration) и убедитесь, что MethodCallPreventAspect можно обнаружить с помощью сканирования компонентов

Подробнее об AOP - https://howtodoinjava.com/spring-aop-tutorial/

1 голос
/ 22 сентября 2019

Поскольку метод вызывается из других классов в jar, вам может потребоваться исправить класс во время выполнения.Обычно это плохая идея, и лучшим способом было бы отредактировать файл класса в банке, создав новую банку.

Самый простой способ переопределить класс во время выполнения - с помощью ByteBuddy * 1004.*.
Этот код должен помочь:

ByteBuddyAgent.install();
new ByteBuddy()
    .redefine(class_name.class)
    .method(named("method2"))
    .intercept(StubMethod.INSTANCE)
    .make()
    .load(class_name.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());

Хотя это и должно сработать, возможно, лучше всего просто удалить весь код из метода в файле jar, исправив байт-код.

1 голос
/ 22 сентября 2019

Вы можете использовать Javassist или любое другое третье лицо.

Здесь я показываю это с Javassist.

Javassist deals with Java bytecode through .class files.

Если у вас есть проект Maven, добавьте эту зависимость в pom.xml:

<dependency>
    <groupId>javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.12.1.GA</version>
</dependency>

или загрузите jar отсюда: mvnrepository


Я предоставил пример кода для понимания:

package test;

import java.io.IOException;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;

class class_name {
    public static void method_name() {
        method1();
        method2();
        method3();
    }

    public static void method1() {
        System.out.println("In method1");
    }

    public static void method2() {
        System.out.println("In method2");
    }

    public static void method3() {
        System.out.println("In method3");
    }
}

public class Testing {
    public static void main(String args[]) throws NotFoundException, CannotCompileException, IOException {
        ClassPool pool = ClassPool.getDefault();
        CtClass ctClass = pool.get("test.class_name");
        ctClass.defrost();
        CtMethod ctMethod = ctClass.getDeclaredMethod("method_name");
        ctMethod.setBody("{ method1();\r\n" + "method3(); }");
        ctClass.writeFile(".");
        ctClass.toClass();
        class_name className = new class_name();
        class_name.method_name();
    }

}

Вывод:

In method1
In method3

В библиотеке много функций.Итак, прочитайте документацию.

См. Документацию Javassist: Документ Javassist

Надеюсь, это поможет вам.

Спасибо:)

0 голосов
/ 22 сентября 2019

Вы можете попробовать расширить класс и предоставить собственную реализацию, переопределив его метод, например,

// Class in jar
class Dummy {
      public void method_name(){
            method1();
            method2();
            method3();
          }
          public void method1(){
              System.out.println("method 1 invoked from Dummy");
          }
          public void method2(){
              System.out.println("method 2 invoked from Dummy");
          }
          public void method3(){
              System.out.println("method 3 invoked from Dummy");
          }

}


//Your class
public class Test3 extends Dummy {

    @Override
    public void method_name() {
        method1();
        method2();
        method3();
    }

    @Override
    public void method1() {
        super.method1();
    }

    @Override
    public void method2() {
        // No call from here
    }

    @Override
    public void method3() {
        super.method3();
    }

    public static void main(String[] args) {

        // Use you own class' objects to use jar class methods
        Test3 test = new Test3();
        test.method_name();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...