Skip to content

Commit

Permalink
abstract method detect
Browse files Browse the repository at this point in the history
  • Loading branch information
sunwu51 committed Apr 30, 2024
1 parent 097a7f2 commit 07ccfff
Show file tree
Hide file tree
Showing 13 changed files with 134 additions and 39 deletions.
14 changes: 1 addition & 13 deletions src/main/java/w/core/Swapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,7 @@ public boolean swap(Message message) {

Set<Class<?>> classes = Global.allLoadedClasses.getOrDefault(transformer.getClassName(), new HashSet<>());

boolean classExists = false;
for (Class<?> aClass : classes) {
if (aClass.isInterface() || Modifier.isAbstract(aClass.getModifiers())) {
Set<String> candidates = new HashSet<>();
for (Object instances : Global.getInstances(aClass)) {
candidates.add(instances.getClass().getName());
}
Global.error("!Error: Should use a simple pojo, but " + aClass.getName() + " is a Interface or Abstract class or something wired, \nmaybe you should use: " + candidates);
return false;
}
classExists = true;
}

boolean classExists = !classes.isEmpty();
if (!classExists) {
Global.error("Class not exist: " + transformer.getClassName());
return false;
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/w/core/model/BaseClassTransformer.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package w.core.model;

import javassist.CtClass;
import javassist.CtMethod;
import javassist.LoaderClassPath;
import javassist.NotFoundException;
import lombok.Getter;
import lombok.Setter;
import w.Global;
Expand All @@ -10,8 +13,7 @@
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import java.util.Objects;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.CompletableFuture;

/**
Expand Down
9 changes: 8 additions & 1 deletion src/main/java/w/core/model/ChangeBodyTransformer.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.annotation.JsonIgnore;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.Modifier;
import lombok.Data;
import w.Global;
import w.web.message.ChangeBodyMessage;
Expand Down Expand Up @@ -44,12 +45,18 @@ public byte[] transform(String className, byte[] origin) throws Exception {
Arrays.equals(paramTypes.toArray(new String[0]),
Arrays.stream(declaredMethod.getParameterTypes()).map(CtClass::getName).toArray())
) {
if ((declaredMethod.getModifiers() & Modifier.ABSTRACT) != 0) {
throw new IllegalArgumentException("Cannot change abstract method.");
}
if ((declaredMethod.getModifiers() & Modifier.NATIVE) != 0) {
throw new IllegalArgumentException("Cannot change native method.");
}
declaredMethod.setBody(message.getBody());
effect = true;
}
}
if (!effect) {
throw new IllegalArgumentException("Class or Method not exist.");
throw new IllegalArgumentException("Method not declared here.");
}
byte[] result = ctClass.toBytecode();
ctClass.detach();
Expand Down
9 changes: 8 additions & 1 deletion src/main/java/w/core/model/ChangeResultTransformer.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.Modifier;
import javassist.expr.ExprEditor;
import javassist.expr.MethodCall;
import lombok.Data;
Expand Down Expand Up @@ -54,6 +55,12 @@ public byte[] transform(String className, byte[] origin) throws Exception {
Arrays.equals(paramTypes.toArray(new String[0]),
Arrays.stream(declaredMethod.getParameterTypes()).map(CtClass::getName).toArray())
) {
if ((declaredMethod.getModifiers() & Modifier.ABSTRACT) != 0) {
throw new IllegalArgumentException("Cannot change abstract method.");
}
if ((declaredMethod.getModifiers() & Modifier.NATIVE) != 0) {
throw new IllegalArgumentException("Cannot change native method.");
}
declaredMethod.instrument(new ExprEditor() {
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals(innerMethod)) {
Expand All @@ -67,7 +74,7 @@ public void edit(MethodCall m) throws CannotCompileException {
}
}
if (!effect) {
throw new IllegalArgumentException("Class or Method not exist.");
throw new IllegalArgumentException("Method not declared here.");
}
byte[] result = ctClass.toBytecode();
ctClass.detach();
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/w/core/model/OuterWatchTransformer.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,18 @@ public byte[] transform(String className, byte[] origin) throws Exception {
boolean effect = false;
for (CtMethod declaredMethod : ctClass.getDeclaredMethods()) {
if (Objects.equals(declaredMethod.getName(), method)) {
if ((declaredMethod.getModifiers() & Modifier.ABSTRACT) != 0) {
throw new IllegalArgumentException("Cannot change abstract method.");
}
if ((declaredMethod.getModifiers() & Modifier.NATIVE) != 0) {
throw new IllegalArgumentException("Cannot change native method.");
}
addOuterWatchCodeToMethod(declaredMethod);
effect = true;
}
}
if (!effect) {
throw new IllegalArgumentException("Class or Method not exist.");
throw new IllegalArgumentException("Method not declared here.");
}
byte[] result = ctClass.toBytecode();
ctClass.detach();
Expand Down
13 changes: 8 additions & 5 deletions src/main/java/w/core/model/TraceTransformer.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
import java.lang.reflect.Method;
import java.util.*;

import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
import javassist.*;
import javassist.expr.ExprEditor;
import javassist.expr.MethodCall;
import lombok.Data;
Expand Down Expand Up @@ -42,12 +39,18 @@ public byte[] transform(String className, byte[] origin) throws Exception {
boolean effect = false;
for (CtMethod declaredMethod : ctClass.getDeclaredMethods()) {
if (Objects.equals(declaredMethod.getName(), method)) {
if ((declaredMethod.getModifiers() & Modifier.ABSTRACT) != 0) {
throw new IllegalArgumentException("Cannot change abstract method.");
}
if ((declaredMethod.getModifiers() & Modifier.NATIVE) != 0) {
throw new IllegalArgumentException("Cannot change native method.");
}
addTraceCodeToMethod(declaredMethod);
effect = true;
}
}
if (!effect) {
throw new IllegalArgumentException("Class or Method not exist.");
throw new IllegalArgumentException("Method not declared here.");
}
byte[] result = ctClass.toBytecode();
ctClass.detach();
Expand Down
12 changes: 8 additions & 4 deletions src/main/java/w/core/model/WatchTransformer.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@

import java.io.ByteArrayInputStream;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;

Expand Down Expand Up @@ -44,12 +42,18 @@ public byte[] transform(String className, byte[] origin) throws Exception {
boolean effect = false;
for (CtMethod declaredMethod : ctClass.getDeclaredMethods()) {
if (Objects.equals(declaredMethod.getName(), method)) {
if ((declaredMethod.getModifiers() & Modifier.ABSTRACT) != 0) {
throw new IllegalArgumentException("Cannot change abstract method.");
}
if ((declaredMethod.getModifiers() & Modifier.NATIVE) != 0) {
throw new IllegalArgumentException("Cannot change native method.");
}
addWatchCodeToMethod(declaredMethod);
effect = true;
}
}
if (!effect) {
throw new IllegalArgumentException("Class or Method not exist.");
throw new IllegalArgumentException("Method not declared here.");
}
byte[] result = ctClass.toBytecode();
ctClass.detach();
Expand Down
13 changes: 13 additions & 0 deletions src/test/java/w/core/AbstractService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package w.core;

/**
* @author Frank
* @date 2024/4/30 19:26
*/
public abstract class AbstractService implements MyInterface {
public String normalParentMethod() {
return "a";
}

abstract String abstractParentMethod();
}
13 changes: 13 additions & 0 deletions src/test/java/w/core/MyInterface.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package w.core;

/**
* @author Frank
* @date 2024/4/30 19:29
*/
public interface MyInterface {
default String interfaceDefaultMethod() {
return "default";
}

String interfaceMethod();
}
25 changes: 25 additions & 0 deletions src/test/java/w/core/R.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package w.core;

import java.util.UUID;

/**
* @author Frank
* @date 2024/4/30 19:30
*/
public class R extends AbstractService {
@Override
String abstractParentMethod() {
return "R.abstractParentMethod";
}

@Override
public String interfaceMethod() {
return "R.interfaceMethod";
}

public int recursive(int n) {
if (n <= 1) return 1;
UUID.randomUUID();
return recursive(n - 1) + recursive(n - 2);
}
}
17 changes: 17 additions & 0 deletions src/test/java/w/core/R2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package w.core;

/**
* @author Frank
* @date 2024/4/30 19:30
*/
public class R2 extends AbstractService {
@Override
String abstractParentMethod() {
return "R2.abstractParentMethod";
}

@Override
public String interfaceMethod() {
return "R2.interfaceMethod";
}
}
28 changes: 22 additions & 6 deletions src/test/java/w/core/SwapperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ class SwapperTest {

Swapper swapper = Swapper.getInstance();;

TestClass t = new TestClass();;
TestClass t = new TestClass();

R r = new R();
R2 r2 = new R2();

@BeforeAll
public static void setUp() throws Exception {
Expand All @@ -37,10 +40,23 @@ public void reset() {
@Test
public void watchTest() {
WatchMessage watchMessage = new WatchMessage();
watchMessage.setSignature("w.core.TestClass#hello");
watchMessage.setMinCost(0);
watchMessage.setSignature("w.core.R#abstractParentMethod");
Assertions.assertTrue(swapper.swap(watchMessage));
t.hello("world");
WatchMessage watchMessage2 = new WatchMessage();
watchMessage2.setSignature("w.core.R#interfaceMethod");
Assertions.assertTrue(swapper.swap(watchMessage2));
WatchMessage watchMessage3 = new WatchMessage();
watchMessage3.setSignature("w.core.AbstractService#normalParentMethod");
Assertions.assertTrue(swapper.swap(watchMessage3));
WatchMessage watchMessage4 = new WatchMessage();
watchMessage4.setSignature("w.core.MyInterface#interfaceDefaultMethod");
Assertions.assertTrue(swapper.swap(watchMessage4));
r.abstractParentMethod();
r.interfaceMethod();
r.normalParentMethod();
r.interfaceDefaultMethod();
r2.normalParentMethod();
r2.interfaceDefaultMethod();
}

@Test
Expand Down Expand Up @@ -115,11 +131,11 @@ public void replaceClassTest() throws Exception {
@Test
public void traceRecursiveTest() {
TraceMessage message = new TraceMessage();
message.setSignature("w.core.TestClass#recursive");
message.setSignature("w.core.R#recursive");
message.setIgnoreZero(false);
Assertions.assertTrue(swapper.swap(message));
for (int i = 0; i < 10; i++) {
t.recursive(3);
r.recursive(3);
}
}
}
6 changes: 0 additions & 6 deletions src/test/java/w/core/TestClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,4 @@ public String wrapperHello(String name) {
return hello(name);
}


public int recursive(int n) {
if (n <= 1) return 1;
UUID.randomUUID();
return recursive(n - 1) + recursive(n - 2);
}
}

0 comments on commit 07ccfff

Please sign in to comment.