This is an automated email from the ASF dual-hosted git repository. wu-sheng pushed a commit to branch feature/jetty12-struts7-jakarta-plugins in repository https://gitbox.apache.org/repos/asf/skywalking-java.git
commit 7aad545a14dfe84bc7878dd88e53eea60143be99 Author: Wu Sheng <[email protected]> AuthorDate: Tue Jul 7 08:48:47 2026 +0800 Add Jetty 12 and Struts 7 (Jakarta) agent plugins Jetty 12 removed the concrete HttpChannel whose handle() the merged jetty-server plugin enhances, and moved request handling to the async, namespace-neutral core API Server#handle(Request, Response, Callback). Add a separate jetty-server-12.x plugin that enhances it and records an async entry span (finished with the response status when the wrapped Callback completes). Struts 7 relocated DefaultActionInvocation from com.opensymphony.xwork2 to org.apache.struts2 and switched to jakarta.servlet. Add a struts2-7.x plugin enhancing the new class (a distinct package from struts2-2.x avoids collision). Both reuse existing components (JettyServer, Struts2). Add plugin test scenarios covering the versions (Jetty 12.0.x/12.1.x; Struts 7.0.x/7.1.x/7.2.x) and update the supported list, plugin list and CHANGES. Add test/plugin/CLAUDE.md describing the plugin-test-first testing approach. --- .github/workflows/plugins-jdk17-test.0.yaml | 1 + .github/workflows/plugins-jdk17-test.1.yaml | 1 + CHANGES.md | 2 + apm-sniffer/apm-sdk-plugin/CLAUDE.md | 2 + .../{ => jetty-server-12.x-plugin}/pom.xml | 36 ++-- .../plugin/jetty/v12/server/HandleInterceptor.java | 100 +++++++++++ .../apm/plugin/jetty/v12/server/SwCallback.java | 98 +++++++++++ .../define/Jetty12ServerInstrumentation.java | 89 ++++++++++ .../src/main/resources/skywalking-plugin.def | 18 ++ apm-sniffer/apm-sdk-plugin/jetty-plugin/pom.xml | 1 + apm-sniffer/apm-sdk-plugin/pom.xml | 1 + .../{jetty-plugin => struts2-7.x-plugin}/pom.xml | 40 +++-- .../apm/plugin/struts2/v7/Struts2Interceptor.java | 82 +++++++++ .../struts2/v7/define/Struts2Instrumentation.java | 75 ++++++++ .../src/main/resources/skywalking-plugin.def | 18 ++ .../setup/service-agent/java-agent/Plugin-list.md | 2 + .../service-agent/java-agent/Supported-list.md | 6 +- javaagent-position.txt | 182 ++++++++++++++++++++ test/plugin/CLAUDE.md | 43 +++++ .../scenarios/jetty-12.x-scenario/bin/startup.sh | 21 +++ .../jetty-12.x-scenario/config/expectedData.yaml | 39 +++++ .../jetty-12.x-scenario/configuration.yml | 22 +++ test/plugin/scenarios/jetty-12.x-scenario/pom.xml | 117 +++++++++++++ .../src/main/assembly/assembly.xml | 41 +++++ .../apm/testcase/jetty12xserver/Application.java | 37 ++++ .../jetty12xserver/handler/CaseHandler.java | 43 +++++ .../src/main/resources/log4j2.xml | 30 ++++ .../jetty-12.x-scenario/support-version.list | 18 ++ .../struts2.7-scenario/config/expectedData.yaml | 72 ++++++++ .../scenarios/struts2.7-scenario/configuration.yml | 21 +++ test/plugin/scenarios/struts2.7-scenario/pom.xml | 96 +++++++++++ .../apm/testcase/struts/Case1Action.java | 28 +++ .../skywalking/apm/testcase/struts/CaseAction.java | 47 +++++ .../apm/testcase/struts/HealthCheckServlet.java | 41 +++++ .../src/main/resources/log4j2.xml | 30 ++++ .../src/main/resources/struts.xml | 32 ++++ .../src/main/webapp/WEB-INF/web.xml | 44 +++++ .../src/main/webapp/jsp/success.jsp | 25 +++ .../struts2.7-scenario/support-version.list | 19 ++ tools/plugin/genernate-javaagent-plugin-list.txt | 191 +++++++++++++++++++++ tools/plugin/md-javaagent-plugin-list.txt | 191 +++++++++++++++++++++ 41 files changed, 1971 insertions(+), 31 deletions(-) diff --git a/.github/workflows/plugins-jdk17-test.0.yaml b/.github/workflows/plugins-jdk17-test.0.yaml index 49b3675c01..b62166b155 100644 --- a/.github/workflows/plugins-jdk17-test.0.yaml +++ b/.github/workflows/plugins-jdk17-test.0.yaml @@ -79,6 +79,7 @@ jobs: - grizzly-2.3.x-4.x-workthreadpool-scenario - jetty-11.x-scenario - jetty-10.x-scenario + - jetty-12.x-scenario - spring-ai-1.x-scenario - spring-rabbitmq-scenario - graphql-20plus-scenario diff --git a/.github/workflows/plugins-jdk17-test.1.yaml b/.github/workflows/plugins-jdk17-test.1.yaml index 6be997dc0e..e4f7144dfd 100644 --- a/.github/workflows/plugins-jdk17-test.1.yaml +++ b/.github/workflows/plugins-jdk17-test.1.yaml @@ -72,6 +72,7 @@ jobs: case: - spring-6.x-scenario - spring-boot-3.x-scenario + - struts2.7-scenario - resteasy-6.x-scenario - gateway-4.x-scenario - gateway-4.1.2.x-scenario diff --git a/CHANGES.md b/CHANGES.md index 9f994787ff..48310efdab 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,8 @@ Release Notes. * Fix `plugin.http.include_http_headers` not working on Spring Boot 3.x / Jakarta EE (apache/skywalking#13938). * Unify the Tomcat plugins into a single `tomcat` plugin (Tomcat 7 - 10) and the Jetty server plugins into a single `jetty-server` plugin (Jetty 9 - 11), each supporting both `javax.servlet` and `jakarta.servlet`. Breaking change: plugin names `tomcat-7.x/8.x` and `tomcat-10.x` are replaced by `tomcat`, and `jetty-server-9.x` and `jetty-server-11.x` by `jetty-server`; update `plugin.exclude_plugins` if you reference the old names. +* Add a Jetty 12 server plugin (`jetty-server-12.x`). Jetty 12 removed the `HttpChannel` handle target and moved request handling to the async `Server#handle(Request, Response, Callback)` core API, so it needs a separate plugin from the merged `jetty-server`. +* Add a Struts 7 plugin (`struts2-7.x`) for Jakarta Struts, whose `DefaultActionInvocation` moved to `org.apache.struts2`. * Added support for Lettuce reactive Redis commands. * Add Spring AI 1.x plugin and GenAI layer. * Fix httpclient-5.x plugin injecting sw8 propagation headers into ClickHouse HTTP requests (port 8123), causing HTTP 400. Add `PROPAGATION_EXCLUDE_PORTS` config to skip tracing (including header injection) for specified ports in the classic client interceptor. diff --git a/apm-sniffer/apm-sdk-plugin/CLAUDE.md b/apm-sniffer/apm-sdk-plugin/CLAUDE.md index b839fbe73b..81de9bc670 100644 --- a/apm-sniffer/apm-sdk-plugin/CLAUDE.md +++ b/apm-sniffer/apm-sdk-plugin/CLAUDE.md @@ -251,6 +251,8 @@ histogram.addValue(3); The plugin test framework verifies plugin functionality using Docker containers with real services and a mock OAP backend. +> See `test/plugin/CLAUDE.md` for the testing philosophy: a plugin's scenario (with one-version-per-minor coverage) is the **key** test — it proves the interceptor's cast/fetch-data logic and version compatibility by running the real framework. Do **not** over-engineer with many mock-based unit tests for a plugin. + ### Environment Requirements - MacOS/Linux - JDK 8+ diff --git a/apm-sniffer/apm-sdk-plugin/jetty-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-12.x-plugin/pom.xml similarity index 55% copy from apm-sniffer/apm-sdk-plugin/jetty-plugin/pom.xml copy to apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-12.x-plugin/pom.xml index 1ac21fb14d..dfc04b5933 100644 --- a/apm-sniffer/apm-sdk-plugin/jetty-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-12.x-plugin/pom.xml @@ -1,4 +1,3 @@ -<?xml version="1.0" encoding="UTF-8"?> <!-- ~ Licensed to the Apache Software Foundation (ASF) under one or more ~ contributor license agreements. See the NOTICE file distributed with @@ -18,27 +17,36 @@ --> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <parent> + <artifactId>jetty-plugins</artifactId> <groupId>org.apache.skywalking</groupId> - <artifactId>apm-sdk-plugin</artifactId> <version>9.7.0-SNAPSHOT</version> </parent> + <modelVersion>4.0.0</modelVersion> - <artifactId>jetty-plugins</artifactId> - <modules> - <module>jetty-client-9.x-plugin</module> - <module>jetty-client-9.0-plugin</module> - <module>jetty-server-plugin</module> - <module>jetty-client-11.x-plugin</module> - </modules> - <packaging>pom</packaging> + <artifactId>apm-jetty-server-12.x-plugin</artifactId> + <packaging>jar</packaging> - <name>jetty-plugin</name> + <name>jetty-server-12.x-plugin</name> <url>http://maven.apache.org</url> + <!-- + Jetty 12 removed the concrete org.eclipse.jetty.server.HttpChannel class that the merged + jetty-server plugin enhances, and redesigned request handling around the namespace-neutral + core API org.eclipse.jetty.server.Server#handle(Request, Response, Callback), which is async + (the response status is only known when the Callback completes). Hence a separate plugin that + does not use the servlet-commons wrapper. Covers Jetty 12.0.x and 12.1.x (same signature). + --> <properties> - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <jetty-server.version>12.0.36</jetty-server.version> </properties> + + <dependencies> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-server</artifactId> + <version>${jetty-server.version}</version> + <scope>provided</scope> + </dependency> + </dependencies> </project> diff --git a/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-12.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v12/server/HandleInterceptor.java b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-12.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v12/server/HandleInterceptor.java new file mode 100644 index 0000000000..74e08614dd --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-12.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v12/server/HandleInterceptor.java @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.jetty.v12.server; + +import java.lang.reflect.Method; +import org.apache.skywalking.apm.agent.core.context.CarrierItem; +import org.apache.skywalking.apm.agent.core.context.ContextCarrier; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.tag.Tags; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpURI; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.util.Callback; + +/** + * Enhances the core, namespace-neutral {@code org.eclipse.jetty.server.Server#handle(Request, Response, + * Callback)} — the single top-level entry invoked once per request in Jetty 12. Handling is async, so + * the entry span is prepared for async in beforeMethod, its synchronous segment ends in afterMethod, and + * it is finished (with the response status) when the wrapped {@link SwCallback} completes. + */ +public class HandleInterceptor implements InstanceMethodsAroundInterceptor { + + private static final ThreadLocal<SwCallback> HOLDER = new ThreadLocal<SwCallback>(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + Request request = (Request) allArguments[0]; + Response response = (Response) allArguments[1]; + Callback callback = (Callback) allArguments[2]; + + ContextCarrier contextCarrier = new ContextCarrier(); + HttpFields headers = request.getHeaders(); + CarrierItem next = contextCarrier.items(); + while (next.hasNext()) { + next = next.next(); + next.setHeadValue(headers.get(next.getHeadKey())); + } + + HttpURI uri = request.getHttpURI(); + AbstractSpan span = ContextManager.createEntrySpan(uri.getPath(), contextCarrier); + Tags.URL.set(span, uri.asString()); + Tags.HTTP.METHOD.set(span, request.getMethod()); + span.setComponent(ComponentsDefine.JETTY_SERVER); + SpanLayer.asHttp(span); + span.prepareForAsync(); + + SwCallback swCallback = new SwCallback(callback, response, span); + allArguments[2] = swCallback; + HOLDER.set(swCallback); + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, + Object ret) throws Throwable { + SwCallback swCallback = HOLDER.get(); + HOLDER.remove(); + ContextManager.stopSpan(); + // ret == true: handled; the wrapped callback fires on response completion and finishes the span. + // ret == false: not handled — Jetty writes 404 on the original callback, bypassing ours. + // ret == null: handle() threw (see handleMethodException) — Jetty writes 500. + // For the latter two the wrapped callback never fires and the status is written only after + // handle() returns, so finish here with the status Jetty's contract guarantees. + if (swCallback != null && !Boolean.TRUE.equals(ret)) { + swCallback.finishWithStatus(ret == null ? 500 : 404); + } + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class<?>[] argumentsTypes, Throwable t) { + AbstractSpan span = ContextManager.activeSpan(); + span.log(t); + span.errorOccurred(); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-12.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v12/server/SwCallback.java b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-12.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v12/server/SwCallback.java new file mode 100644 index 0000000000..f5193d7c05 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-12.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v12/server/SwCallback.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.jetty.v12.server; + +import java.util.concurrent.atomic.AtomicBoolean; +import org.apache.skywalking.apm.agent.core.context.tag.Tags; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.thread.Invocable; + +/** + * Wraps the {@link Callback} passed to {@code Server#handle}. Jetty 12 request handling is async — the + * response status is only known when the callback completes on the (possibly different) response thread. + * On completion this reads the status, records it on the entry span and finishes the async span. It + * delegates every method to the original callback so Jetty's threading model is preserved. + */ +public class SwCallback implements Callback { + + private final Callback delegate; + private final Response response; + private final AbstractSpan span; + private final AtomicBoolean finished = new AtomicBoolean(); + + public SwCallback(Callback delegate, Response response, AbstractSpan span) { + this.delegate = delegate; + this.response = response; + this.span = span; + } + + @Override + public void succeeded() { + finishOnce(); + delegate.succeeded(); + } + + @Override + public void failed(Throwable x) { + if (finished.compareAndSet(false, true)) { + span.log(x); + span.errorOccurred(); + Tags.HTTP_RESPONSE_STATUS_CODE.set(span, response.getStatus()); + span.asyncFinish(); + } + delegate.failed(x); + } + + @Override + public Invocable.InvocationType getInvocationType() { + return delegate.getInvocationType(); + } + + /** + * Records the response status and finishes the async span exactly once. Safe to call from either the + * callback completion or the interceptor's afterMethod fallback (not-handled / exception paths). + */ + void finishOnce() { + if (finished.compareAndSet(false, true)) { + int statusCode = response.getStatus(); + Tags.HTTP_RESPONSE_STATUS_CODE.set(span, statusCode); + if (statusCode >= 400) { + span.errorOccurred(); + } + span.asyncFinish(); + } + } + + /** + * Finishes the async span exactly once with an explicit status. Used for the not-handled / exception + * fallback paths where Jetty writes the error status on the original callback after {@code handle()} + * returns — so the wrapped callback never fires and {@link Response#getStatus()} is still 0 (uncommitted). + */ + void finishWithStatus(int statusCode) { + if (finished.compareAndSet(false, true)) { + Tags.HTTP_RESPONSE_STATUS_CODE.set(span, statusCode); + if (statusCode >= 400) { + span.errorOccurred(); + } + span.asyncFinish(); + } + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-12.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v12/server/define/Jetty12ServerInstrumentation.java b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-12.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v12/server/define/Jetty12ServerInstrumentation.java new file mode 100644 index 0000000000..8b4d347af9 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-12.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v12/server/define/Jetty12ServerInstrumentation.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.jetty.v12.server.define; + +import java.util.Collections; +import java.util.List; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.WitnessMethod; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArgument; +import static net.bytebuddy.matcher.ElementMatchers.takesArguments; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +/** + * Enhances {@code org.eclipse.jetty.server.Server#handle(Request, Response, Callback)} by + * {@code HandleInterceptor}. Only Jetty 12+ declares this three-argument, {@code Callback}-terminated + * signature, so the witness method both activates the plugin exclusively on Jetty 12 and keeps it from + * overlapping the merged jetty-server plugin (which enhances the Jetty 9/10/11 {@code HttpChannel}, + * removed in Jetty 12). + */ +public class Jetty12ServerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "org.eclipse.jetty.server.Server"; + private static final String ENHANCE_METHOD = "handle"; + private static final String CALLBACK_CLASS = "org.eclipse.jetty.util.Callback"; + private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.jetty.v12.server.HandleInterceptor"; + + @Override + protected List<WitnessMethod> witnessMethods() { + return Collections.singletonList(new WitnessMethod( + ENHANCE_CLASS, + named(ENHANCE_METHOD).and(takesArgument(2, named(CALLBACK_CLASS))) + )); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher<MethodDescription> getMethodsMatcher() { + return named(ENHANCE_METHOD).and(takesArguments(3)).and(takesArgument(2, named(CALLBACK_CLASS))); + } + + @Override + public String getMethodsInterceptor() { + return INTERCEPT_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return true; + } + } + }; + } + + @Override + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-12.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-12.x-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 0000000000..2c466d5f66 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-12.x-plugin/src/main/resources/skywalking-plugin.def @@ -0,0 +1,18 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +jetty-server-12.x=org.apache.skywalking.apm.plugin.jetty.v12.server.define.Jetty12ServerInstrumentation diff --git a/apm-sniffer/apm-sdk-plugin/jetty-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/jetty-plugin/pom.xml index 1ac21fb14d..671cc92f91 100644 --- a/apm-sniffer/apm-sdk-plugin/jetty-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/jetty-plugin/pom.xml @@ -31,6 +31,7 @@ <module>jetty-client-9.x-plugin</module> <module>jetty-client-9.0-plugin</module> <module>jetty-server-plugin</module> + <module>jetty-server-12.x-plugin</module> <module>jetty-client-11.x-plugin</module> </modules> <packaging>pom</packaging> diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml index 829d63dd84..8bc2e1faaa 100644 --- a/apm-sniffer/apm-sdk-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/pom.xml @@ -44,6 +44,7 @@ <module>okhttp-common</module> <module>spring-plugins</module> <module>struts2-2.x-plugin</module> + <module>struts2-7.x-plugin</module> <module>nutz-plugins</module> <module>jetty-plugin</module> <module>spymemcached-2.x-plugin</module> diff --git a/apm-sniffer/apm-sdk-plugin/jetty-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/struts2-7.x-plugin/pom.xml similarity index 55% copy from apm-sniffer/apm-sdk-plugin/jetty-plugin/pom.xml copy to apm-sniffer/apm-sdk-plugin/struts2-7.x-plugin/pom.xml index 1ac21fb14d..f314ff5fba 100644 --- a/apm-sniffer/apm-sdk-plugin/jetty-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/struts2-7.x-plugin/pom.xml @@ -1,4 +1,3 @@ -<?xml version="1.0" encoding="UTF-8"?> <!-- ~ Licensed to the Apache Software Foundation (ASF) under one or more ~ contributor license agreements. See the NOTICE file distributed with @@ -18,27 +17,40 @@ --> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <parent> <groupId>org.apache.skywalking</groupId> <artifactId>apm-sdk-plugin</artifactId> <version>9.7.0-SNAPSHOT</version> </parent> + <modelVersion>4.0.0</modelVersion> - <artifactId>jetty-plugins</artifactId> - <modules> - <module>jetty-client-9.x-plugin</module> - <module>jetty-client-9.0-plugin</module> - <module>jetty-server-plugin</module> - <module>jetty-client-11.x-plugin</module> - </modules> - <packaging>pom</packaging> + <artifactId>apm-struts2-7.x-plugin</artifactId> + <packaging>jar</packaging> - <name>jetty-plugin</name> - <url>http://maven.apache.org</url> + <name>struts2-7.x-plugin</name> + <!-- + Struts 7.x moved DefaultActionInvocation from com.opensymphony.xwork2 to org.apache.struts2 + and switched to the jakarta.servlet namespace (Jakarta Servlet 6.0, JDK 17), so it needs a + separate plugin from struts2-2.x-plugin (which stays on the old class + javax). + --> <properties> - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <struts.version>7.2.1</struts.version> + <jakarta-servlet-api.version>6.0.0</jakarta-servlet-api.version> </properties> + + <dependencies> + <dependency> + <groupId>org.apache.struts</groupId> + <artifactId>struts2-core</artifactId> + <version>${struts.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>jakarta.servlet</groupId> + <artifactId>jakarta.servlet-api</artifactId> + <version>${jakarta-servlet-api.version}</version> + <scope>provided</scope> + </dependency> + </dependencies> </project> diff --git a/apm-sniffer/apm-sdk-plugin/struts2-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/struts2/v7/Struts2Interceptor.java b/apm-sniffer/apm-sdk-plugin/struts2-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/struts2/v7/Struts2Interceptor.java new file mode 100644 index 0000000000..80a42b2eaa --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/struts2-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/struts2/v7/Struts2Interceptor.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.struts2.v7; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.lang.reflect.Method; +import org.apache.skywalking.apm.agent.core.context.CarrierItem; +import org.apache.skywalking.apm.agent.core.context.ContextCarrier; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.tag.Tags; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; +import org.apache.struts2.ServletActionContext; + +/** + * Enhances {@code org.apache.struts2.DefaultActionInvocation#invokeAction} in Struts 7.x. Struts 7 is + * Jakarta-only (Jakarta Servlet 6.0), so the servlet request/response are referenced through the + * jakarta.servlet namespace directly. + */ +public class Struts2Interceptor implements InstanceMethodsAroundInterceptor { + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + HttpServletRequest request = ServletActionContext.getRequest(); + ContextCarrier contextCarrier = new ContextCarrier(); + + CarrierItem next = contextCarrier.items(); + while (next.hasNext()) { + next = next.next(); + next.setHeadValue(request.getHeader(next.getHeadKey())); + } + + AbstractSpan span = ContextManager.createEntrySpan(request.getRequestURI(), contextCarrier); + Tags.URL.set(span, request.getRequestURL().toString()); + Tags.HTTP.METHOD.set(span, request.getMethod()); + span.setComponent(ComponentsDefine.STRUTS2); + SpanLayer.asHttp(span); + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, + Object ret) throws Throwable { + HttpServletResponse response = ServletActionContext.getResponse(); + + AbstractSpan span = ContextManager.activeSpan(); + int statusCode = response.getStatus(); + Tags.HTTP_RESPONSE_STATUS_CODE.set(span, statusCode); + if (statusCode >= 400) { + span.errorOccurred(); + } + ContextManager.stopSpan(); + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class<?>[] argumentsTypes, Throwable t) { + ContextManager.activeSpan().log(t); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/struts2-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/struts2/v7/define/Struts2Instrumentation.java b/apm-sniffer/apm-sdk-plugin/struts2-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/struts2/v7/define/Struts2Instrumentation.java new file mode 100644 index 0000000000..68302e8c5a --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/struts2-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/struts2/v7/define/Struts2Instrumentation.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.struts2.v7.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +/** + * {@link Struts2Instrumentation} enhances the <code>invokeAction</code> method of Struts 7's + * <code>org.apache.struts2.DefaultActionInvocation</code> (relocated from + * <code>com.opensymphony.xwork2.DefaultActionInvocation</code> in Struts 2.x). The class name is + * unique to Struts 7, so it self-witnesses — no witness class is needed, and there is no overlap + * with the struts2-2.x plugin, which enhances the old XWork class. + */ +public class Struts2Instrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "org.apache.struts2.DefaultActionInvocation"; + private static final String ENHANCE_METHOD = "invokeAction"; + private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.struts2.v7.Struts2Interceptor"; + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher<MethodDescription> getMethodsMatcher() { + return named(ENHANCE_METHOD); + } + + @Override + public String getMethodsInterceptor() { + return INTERCEPT_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/struts2-7.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/struts2-7.x-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 0000000000..a9a45c666b --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/struts2-7.x-plugin/src/main/resources/skywalking-plugin.def @@ -0,0 +1,18 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +struts2-7.x=org.apache.skywalking.apm.plugin.struts2.v7.define.Struts2Instrumentation diff --git a/docs/en/setup/service-agent/java-agent/Plugin-list.md b/docs/en/setup/service-agent/java-agent/Plugin-list.md index 2e5ad78336..ac9ea19eeb 100644 --- a/docs/en/setup/service-agent/java-agent/Plugin-list.md +++ b/docs/en/setup/service-agent/java-agent/Plugin-list.md @@ -56,6 +56,7 @@ - jetty-client-9.0 - jetty-client-9.x - jetty-server +- jetty-server-12.x - kafka-0.11.x/1.x/2.x - kafka-3.7.x - kafka-3.9.x @@ -132,6 +133,7 @@ - spring-webflux-5.x-webclient - spymemcached-2.x - struts2-2.x +- struts2-7.x - thrift - tomcat - toolkit-counter diff --git a/docs/en/setup/service-agent/java-agent/Supported-list.md b/docs/en/setup/service-agent/java-agent/Supported-list.md index ca6f481f06..1416ec3471 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -11,10 +11,10 @@ metrics based on the tracing data. * Spring MVC 3.x, 4.x 5.x with servlet 3.x * Spring MVC 6.x (Optional²) * [Nutz Web Framework](https://github.com/nutzam/nutz) 1.x - * [Struts2 MVC](http://struts.apache.org/) 2.3.x -> 2.5.x + * [Struts2 MVC](http://struts.apache.org/) 2.3.x -> 2.5.x, 7.x (Jakarta, JDK17) * Resin 3 (Optional¹), See [SkySPM Plugin Repository](https://github.com/SkyAPM/java-plugin-extensions) * Resin 4 (Optional¹), See [SkySPM Plugin Repository](https://github.com/SkyAPM/java-plugin-extensions) - * [Jetty Server](http://www.eclipse.org/jetty/) 9.x -> 11.x + * [Jetty Server](http://www.eclipse.org/jetty/) 9.x -> 12.x * [Spring WebFlux](https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html) 5.x (Optional²) -> 6.x (Optional²) * [Undertow](http://undertow.io/) 1.3.0.Final -> 2.3.18.Final * [RESTEasy](https://resteasy.dev/) 3.1.0.Final -> 6.2.4.Final @@ -172,7 +172,7 @@ The meter plugin provides the advanced metrics collections, which are not a part * [Undertow](https://github.com/undertow-io/undertow) 2.1.x -> 2.6.x * [Tomcat](https://github.com/apache/tomcat) 7.0.x -> 10.0.x * [Dubbo](https://github.com/apache/dubbo) 2.5.x -> 2.7.x - * [Jetty](https://github.com/eclipse/jetty.project) 9.1.x -> 11.x + * [Jetty](https://github.com/eclipse/jetty.project) 9.1.x -> 12.x * [Grizzly](https://github.com/eclipse-ee4j/grizzly) 2.3.x -> 4.x * Connection Pool * Supported JDBC drviers diff --git a/javaagent-position.txt b/javaagent-position.txt new file mode 100644 index 0000000000..0c6f667560 --- /dev/null +++ b/javaagent-position.txt @@ -0,0 +1,182 @@ +/Users/wusheng/github/skywalking-java/apm-sniffer/expired-plugins/impala-jdbc-2.6.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-toolkit-activation/apm-toolkit-webflux-activation/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-2.x-activation/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-toolkit-activation/apm-toolkit-meter-activation/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-1.x-activation/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-toolkit-activation/apm-toolkit-logback-1.x-activation/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-toolkit-activation/apm-toolkit-kafka-activation/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/bootstrap-plugins/jdk-http-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/bootstrap-plugins/jdk-virtual-thread-executor-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/bootstrap-plugins/jdk-forkjoinpool-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/bootstrap-plugins/jdk-httpclient-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/bootstrap-plugins/jdk-threading-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/bootstrap-plugins/jdk-threadpool-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/kotlin-coroutine-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/shenyu-2.4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/ehcache-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/mybatis-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/guava-cache-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/zookeeper-3.4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/quartz-scheduler-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/optional-spring-plugins/spring-webflux-5.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/optional-spring-plugins/optional-spring-cloud/gateway-4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/optional-spring-plugins/optional-spring-cloud/gateway-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/optional-spring-plugins/optional-spring-cloud/gateway-2.1.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/optional-spring-plugins/optional-spring-cloud/gateway-2.0.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/optional-spring-plugins/spring-tx-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/optional-spring-plugins/spring-annotation-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/optional-spring-plugins/resttemplate-6.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/optional-spring-plugins/spring-webflux-6.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/optional-spring-plugins/mvc-annotation-6.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/caffeine-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/gson-2.8.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/jackson-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/netty-http-4.1.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/nacos-client-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/optional-plugins/fastjson-1.2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/feign-default-http-9.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/undertow-plugins/undertow-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/cassandra-java-driver-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/mysql-6.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/influxdb-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/struts2-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/mongodb-4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/mongodb-5.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/rocketMQ-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/grpc-1.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/dubbo-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spymemcached-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/play-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/elasticjob-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/cxf-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/apm-armeria-0.84.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/apm-armeria-0.85.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/apm-armeria-1.0.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/asynchttpclient-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/httpclient-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/micronaut-plugins/micronaut-http-client-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/micronaut-plugins/micronaut-http-server-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/kylin-jdbc-2.6.x-3.x-4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/hbase-1.x-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/mariadb-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/thrift-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/activemq-artemis-jakarta-client-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/xmemcached-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/jetty-thread-pool-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/redisson-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/dubbo-2.7.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/httpclient-5.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/dubbo-3.x-conflict-patch/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/websphere-liberty-23.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/finagle-6.25.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-client-11.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-client-9.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-client-9.0-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-12.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/kafka-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/undertow-worker-thread-pool-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/neo4j-4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/netty-socketio-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/pulsar-2.8.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/dubbo-conflict-patch/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/baidu-brpc-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/guava-eventbus-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/rocketMQ-5.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/mongodb-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/rocketMQ-4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/avro-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/light4j-plugins/light4j-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spring-plugins/spring-kafka-1.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spring-plugins/resttemplate-4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spring-plugins/spring-ai-1.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spring-plugins/concurrent-util-4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spring-plugins/spring-webflux-5.x-webclient-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spring-plugins/spring-webflux-6.x-webclient-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spring-plugins/core-patch/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spring-plugins/resttemplate-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spring-plugins/spring-kafka-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spring-plugins/scheduled-annotation-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spring-plugins/spring-rabbitmq-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spring-plugins/spring-cloud/spring-cloud-feign-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/spring-plugins/spring-cloud/netflix-plugins/spring-cloud-feign-1.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/mssql-jtds-1.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/dubbo-2.7.x-conflict-patch/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/xxl-job-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/nutz-plugins/http-1.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/nutz-plugins/mvc-annotation-1.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/okhttp-4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/activemq-5.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/solon-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/nats-2.14.x-2.16.5-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/pulsar-2.2-2.7-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/aerospike-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/shardingsphere-plugins/sharding-sphere-5.0.0-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/shardingsphere-plugins/sharding-sphere-4.0.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/shardingsphere-plugins/sharding-sphere-4.1.0-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/shardingsphere-plugins/sharding-sphere-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/tomcat-thread-pool-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/grizzly-2.3.x-4.x-work-threadpool-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/resteasy-plugin/resteasy-server-4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/resteasy-plugin/resteasy-server-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/resteasy-plugin/resteasy-server-6.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/vertx-plugins/vertx-core-4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/h2-1.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/canal-1.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/dubbo-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/tomcat-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/rabbitmq-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/jsonrpc4j-1.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/graphql-plugin/graphql-16plus-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/graphql-plugin/graphql-12.x-15.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/graphql-plugin/graphql-9.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/graphql-plugin/graphql-8.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/grizzly-2.3.x-4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/mssql-jdbc-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/mysql-8.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/jersey-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/jersey-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/servicecomb-plugin/servicecomb-java-chassis-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/struts2-7.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/hystrix-1.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/quasar-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-2.x-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/hutool-plugins/hutool-http-5.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/okhttp-2.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/sofarpc-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/rocketMQ-client-java-5.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/elasticsearch-6.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/c3p0-0.9.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/elasticsearch-7.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-5.x-6.4.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def +/Users/wusheng/github/skywalking-java/apm-sniffer/apm-sdk-plugin/motan-plugin/src/main/resources/skywalking-plugin.def diff --git a/test/plugin/CLAUDE.md b/test/plugin/CLAUDE.md new file mode 100644 index 0000000000..ab80c42da8 --- /dev/null +++ b/test/plugin/CLAUDE.md @@ -0,0 +1,43 @@ +# CLAUDE.md - Plugin Test Guide + +This file guides AI assistants writing and changing **plugin tests** under `test/plugin/scenarios/`. +For the full test-framework mechanics (scenario layout, `configuration.yml`, `expectedData.yaml`, +containers, running locally) see the **"Plugin Test Framework"** section of +`apm-sniffer/apm-sdk-plugin/CLAUDE.md`, and `docs/.../Plugin-test.md`. + +## Testing philosophy: plugin scenarios are the key test — not unit tests + +For an agent plugin, the **plugin test scenario is the primary and sufficient test**. Do **not** +over-engineer by adding many unit tests for a plugin. + +A plugin's real risk is two things, and a scenario proves both at once by running the **real +framework**: + +1. **Cast / fetch-data logic** — the interceptor casting the intercepted arguments to the framework + types and reading request/response fields off them (headers, method, URI, status, params). Mocks + can't validate that the real framework class actually exposes those methods the way you assumed. +2. **Version compatibility** — the same interceptor must work across the supported version range. + +So: **when adding or changing a plugin, add or extend its scenario**, not a pile of mock-based unit +tests. Reserve unit tests for genuinely logic/namespace-critical **shared** code where a deterministic +in-JVM assertion earns its keep (e.g. `servlet-commons` `wrap()` resolving javax vs jakarta with both +APIs on the test classpath) — never for per-plugin interceptor mocking. + +## Version coverage: one version per minor (latest patch) + +`support-version.list` must cover the framework's supported range, but keep **one version per minor +version — the latest patch**, not every patch. E.g. Jetty `12.0.36` + `12.1.10`; Struts `7.0.3`, +`7.1.1`, `7.2.1`; Spring `6.0.4`, `6.1.1`, `6.2.19`. Verify each version resolves on Maven Central. +This is the compatibility proof; CI runs the scenario against each listed version. + +## Practical notes + +- One scenario per plugin (or per javax/jakarta era). Mirror an existing sibling scenario as a + template and change only what differs (framework version, namespace, deployment model). +- Match `type:` to the deployment: `jvm` (fat-jar started by `bin/startup.sh`, `${agent_opts}` + required) or `tomcat` (WAR on a container). Jakarta/newer frameworks go in a JDK-17 CI group. +- Assert the entry span shape that exercises the plugin's data logic: `componentId`, `spanType: Entry`, + `spanLayer: Http`, and the `url` / `http.method` / `http.status_code` (and `http.params` / + `http.headers` where the plugin collects them) tags, plus cross-process refs. +- Register the scenario in the right `.github/workflows/plugins-*.yaml` matrix (use + `python3 tools/select-group.py` to pick the least-loaded group for its JDK lane). diff --git a/test/plugin/scenarios/jetty-12.x-scenario/bin/startup.sh b/test/plugin/scenarios/jetty-12.x-scenario/bin/startup.sh new file mode 100644 index 0000000000..ea5bec3c39 --- /dev/null +++ b/test/plugin/scenarios/jetty-12.x-scenario/bin/startup.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +home="$(cd "$(dirname $0)"; pwd)" + +java -jar ${agent_opts} ${home}/../libs/jetty-12.x-scenario.jar & diff --git a/test/plugin/scenarios/jetty-12.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/jetty-12.x-scenario/config/expectedData.yaml new file mode 100644 index 0000000000..242dd924cb --- /dev/null +++ b/test/plugin/scenarios/jetty-12.x-scenario/config/expectedData.yaml @@ -0,0 +1,39 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +segmentItems: + - serviceName: jetty-12.x-scenario + segmentSize: ge 1 + segments: + - segmentId: not null + spans: + - operationName: /jetty-12.x-scenario/case/jetty-12.x-scenario + parentSpanId: '-1' + spanId: '0' + spanLayer: Http + startTime: gt 0 + endTime: gt 0 + componentId: '19' + isError: 'false' + spanType: Entry + peer: '' + skipAnalysis: 'false' + tags: + - key: url + value: http://localhost:18080/jetty-12.x-scenario/case/jetty-12.x-scenario + - key: http.method + value: GET + - key: http.status_code + value: '200' diff --git a/test/plugin/scenarios/jetty-12.x-scenario/configuration.yml b/test/plugin/scenarios/jetty-12.x-scenario/configuration.yml new file mode 100644 index 0000000000..2db90d0c99 --- /dev/null +++ b/test/plugin/scenarios/jetty-12.x-scenario/configuration.yml @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +type: jvm +entryService: http://localhost:18080/jetty-12.x-scenario/case/jetty-12.x-scenario +healthCheck: http://localhost:18080/jetty-12.x-scenario/case/healthCheck +startScript: ./bin/startup.sh +environment: +dependencies: diff --git a/test/plugin/scenarios/jetty-12.x-scenario/pom.xml b/test/plugin/scenarios/jetty-12.x-scenario/pom.xml new file mode 100644 index 0000000000..2fd2b2d6c5 --- /dev/null +++ b/test/plugin/scenarios/jetty-12.x-scenario/pom.xml @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <groupId>org.apache.skywalking.apm.testcase</groupId> + <artifactId>jetty-12.x-scenario</artifactId> + <version>1.0.0</version> + <packaging>jar</packaging> + + <modelVersion>4.0.0</modelVersion> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <compiler.version>17</compiler.version> + <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version> + + <test.framework.version>12.0.36</test.framework.version> + + <log4j.version>2.6.2</log4j.version> + </properties> + + <name>skywalking-jetty-12.x-scenario</name> + + <dependencies> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-server</artifactId> + <version>${test.framework.version}</version> + </dependency> + </dependencies> + + + <build> + <finalName>jetty-12.x-scenario</finalName> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <version>3.1.0</version> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + <configuration> + <filters> + <filter> + <artifact>*:*</artifact> + <excludes> + <exclude>META-INF/*.SF</exclude> + <exclude>META-INF/*.DSA</exclude> + <exclude>META-INF/*.RSA</exclude> + </excludes> + </filter> + </filters> + <transformers> + <transformer + implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> + <mainClass> + org.apache.skywalking.apm.testcase.jetty12xserver.Application + </mainClass> + </transformer> + </transformers> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <version>${maven-compiler-plugin.version}</version> + <configuration> + <source>${compiler.version}</source> + <target>${compiler.version}</target> + <encoding>${project.build.sourceEncoding}</encoding> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>assemble</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + <configuration> + <descriptors> + <descriptor>src/main/assembly/assembly.xml</descriptor> + </descriptors> + <outputDirectory>./target/</outputDirectory> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/test/plugin/scenarios/jetty-12.x-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/jetty-12.x-scenario/src/main/assembly/assembly.xml new file mode 100644 index 0000000000..4be83c4cb7 --- /dev/null +++ b/test/plugin/scenarios/jetty-12.x-scenario/src/main/assembly/assembly.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + --> +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"> + <formats> + <format>zip</format> + </formats> + + <fileSets> + <fileSet> + <directory>./bin</directory> + <fileMode>0775</fileMode> + </fileSet> + </fileSets> + + <files> + <file> + <source>${project.build.directory}/jetty-12.x-scenario.jar</source> + <outputDirectory>./libs</outputDirectory> + <fileMode>0775</fileMode> + </file> + </files> +</assembly> diff --git a/test/plugin/scenarios/jetty-12.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jetty12xserver/Application.java b/test/plugin/scenarios/jetty-12.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jetty12xserver/Application.java new file mode 100644 index 0000000000..aecb666125 --- /dev/null +++ b/test/plugin/scenarios/jetty-12.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jetty12xserver/Application.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.testcase.jetty12xserver; + +import org.apache.skywalking.apm.testcase.jetty12xserver.handler.CaseHandler; +import org.eclipse.jetty.server.Server; + +/** + * Embedded Jetty 12 server. Jetty 12 handling routes every request through + * {@code org.eclipse.jetty.server.Server#handle(Request, Response, Callback)} — the method the + * jetty-server-12.x plugin enhances — before delegating to the top-level {@link CaseHandler}. + */ +public class Application { + + public static void main(String[] args) throws Exception { + Server server = new Server(18080); + server.setHandler(new CaseHandler()); + server.start(); + server.join(); + } +} diff --git a/test/plugin/scenarios/jetty-12.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jetty12xserver/handler/CaseHandler.java b/test/plugin/scenarios/jetty-12.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jetty12xserver/handler/CaseHandler.java new file mode 100644 index 0000000000..3d84eef93d --- /dev/null +++ b/test/plugin/scenarios/jetty-12.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jetty12xserver/handler/CaseHandler.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.testcase.jetty12xserver.handler; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.util.Callback; + +/** + * Top-level Jetty 12 core handler. Serves both the entry service + * {@code /jetty-12.x-scenario/case/jetty-12.x-scenario} and the health check + * {@code /jetty-12.x-scenario/case/healthCheck} with a 200 response, completing the supplied + * {@link Callback} so the async entry span created by the plugin is finished with the response status. + */ +public class CaseHandler extends Handler.Abstract { + + @Override + public boolean handle(Request request, Response response, Callback callback) throws Exception { + response.setStatus(200); + ByteBuffer body = ByteBuffer.wrap("hello".getBytes(StandardCharsets.UTF_8)); + response.write(true, body, callback); + return true; + } +} diff --git a/test/plugin/scenarios/jetty-12.x-scenario/src/main/resources/log4j2.xml b/test/plugin/scenarios/jetty-12.x-scenario/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..b5cda5ae8a --- /dev/null +++ b/test/plugin/scenarios/jetty-12.x-scenario/src/main/resources/log4j2.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + --> +<Configuration status="WARN"> + <Appenders> + <Console name="Console" target="SYSTEM_ERR"> + <PatternLayout charset="UTF-8" pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/> + </Console> + </Appenders> + <Loggers> + <Root level="WARN"> + <AppenderRef ref="Console"/> + </Root> + </Loggers> +</Configuration> diff --git a/test/plugin/scenarios/jetty-12.x-scenario/support-version.list b/test/plugin/scenarios/jetty-12.x-scenario/support-version.list new file mode 100644 index 0000000000..6c62f269a7 --- /dev/null +++ b/test/plugin/scenarios/jetty-12.x-scenario/support-version.list @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +12.0.36 +12.1.10 diff --git a/test/plugin/scenarios/struts2.7-scenario/config/expectedData.yaml b/test/plugin/scenarios/struts2.7-scenario/config/expectedData.yaml new file mode 100644 index 0000000000..02d7206ab2 --- /dev/null +++ b/test/plugin/scenarios/struts2.7-scenario/config/expectedData.yaml @@ -0,0 +1,72 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +segmentItems: +- serviceName: struts2.7-scenario + segmentSize: gt 2 + segments: + - segmentId: not null + spans: + - operationName: /struts2.7-scenario/case/case1.action + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: gt 0 + endTime: gt 0 + componentId: 15 + isError: false + spanType: Entry + peer: '' + tags: + - {key: url, value: 'http://localhost:8080/struts2.7-scenario/case/case1.action'} + - {key: http.method, value: GET} + - {key: http.status_code, value: '200'} + refs: + - {parentEndpoint: /struts2.7-scenario/case/case.action, networkAddress: 'localhost:8080', + refType: CrossProcess, parentSpanId: 1, parentTraceSegmentId: not null, parentServiceInstance: not + null, parentService: struts2.7-scenario, traceId: not null} + skipAnalysis: 'false' + - segmentId: not null + spans: + - operationName: /struts2.7-scenario/case/case1.action + parentSpanId: 0 + spanId: 1 + spanLayer: Http + startTime: gt 0 + endTime: gt 0 + componentId: 2 + isError: false + spanType: Exit + peer: localhost:8080 + tags: + - {key: url, value: 'http://localhost:8080/struts2.7-scenario/case/case1.action'} + - {key: http.method, value: GET} + - {key: http.status_code, value: '200'} + skipAnalysis: 'false' + - operationName: /struts2.7-scenario/case/case.action + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: gt 0 + endTime: gt 0 + componentId: 15 + isError: false + spanType: Entry + peer: '' + tags: + - {key: url, value: 'http://localhost:8080/struts2.7-scenario/case/case.action'} + - {key: http.method, value: GET} + - {key: http.status_code, value: '200'} + skipAnalysis: 'false' diff --git a/test/plugin/scenarios/struts2.7-scenario/configuration.yml b/test/plugin/scenarios/struts2.7-scenario/configuration.yml new file mode 100644 index 0000000000..b16e56768e --- /dev/null +++ b/test/plugin/scenarios/struts2.7-scenario/configuration.yml @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +type: tomcat +entryService: http://localhost:8080/struts2.7-scenario/case/case.action +healthCheck: http://localhost:8080/struts2.7-scenario/healthCheck +environment: +dependencies: diff --git a/test/plugin/scenarios/struts2.7-scenario/pom.xml b/test/plugin/scenarios/struts2.7-scenario/pom.xml new file mode 100644 index 0000000000..beede09526 --- /dev/null +++ b/test/plugin/scenarios/struts2.7-scenario/pom.xml @@ -0,0 +1,96 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <groupId>org.apache.skywalking.apm.testcase</groupId> + <artifactId>struts2.7-scenario</artifactId> + <version>1.0.0</version> + <packaging>war</packaging> + + <modelVersion>4.0.0</modelVersion> + + <name>skywalking-struts2.7-scenario</name> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <!-- Struts 7 is Jakarta-only (Jakarta Servlet 6.0) and requires JDK 17+. --> + <compiler.version>17</compiler.version> + <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version> + <test.framework.version>7.2.1</test.framework.version> + <jakarta-servlet-api.version>6.0.0</jakarta-servlet-api.version> + <lombok.version>1.18.42</lombok.version> + </properties> + + <dependencies> + <dependency> + <groupId>jakarta.servlet</groupId> + <artifactId>jakarta.servlet-api</artifactId> + <version>${jakarta-servlet-api.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-api</artifactId> + <version>2.8.1</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <version>2.8.1</version> + </dependency> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <version>${lombok.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.struts</groupId> + <artifactId>struts2-core</artifactId> + <version>${test.framework.version}</version> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>4.3</version> + </dependency> + </dependencies> + + <build> + <finalName>struts2.7-scenario</finalName> + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <version>${maven-compiler-plugin.version}</version> + <configuration> + <source>${compiler.version}</source> + <target>${compiler.version}</target> + <encoding>${project.build.sourceEncoding}</encoding> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-war-plugin</artifactId> + <version>3.3.1</version> + </plugin> + </plugins> + </build> +</project> diff --git a/test/plugin/scenarios/struts2.7-scenario/src/main/java/org/apache/skywalking/apm/testcase/struts/Case1Action.java b/test/plugin/scenarios/struts2.7-scenario/src/main/java/org/apache/skywalking/apm/testcase/struts/Case1Action.java new file mode 100644 index 0000000000..9f40d9c99f --- /dev/null +++ b/test/plugin/scenarios/struts2.7-scenario/src/main/java/org/apache/skywalking/apm/testcase/struts/Case1Action.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.testcase.struts; + +import java.io.IOException; + +public class Case1Action { + + public String execute() throws IOException { + return "SUCCESS"; + } +} diff --git a/test/plugin/scenarios/struts2.7-scenario/src/main/java/org/apache/skywalking/apm/testcase/struts/CaseAction.java b/test/plugin/scenarios/struts2.7-scenario/src/main/java/org/apache/skywalking/apm/testcase/struts/CaseAction.java new file mode 100644 index 0000000000..89a4c70e36 --- /dev/null +++ b/test/plugin/scenarios/struts2.7-scenario/src/main/java/org/apache/skywalking/apm/testcase/struts/CaseAction.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.testcase.struts; + +import org.apache.http.HttpEntity; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; + +public class CaseAction { + + public String execute() throws IOException { + visit(); + return "SUCCESS"; + } + + private static void visit() throws IOException { + try (CloseableHttpClient httpClient = HttpClients.createDefault()) { + HttpGet httpget = new HttpGet("http://localhost:8080/struts2.7-scenario/case/case1.action"); + ResponseHandler<String> responseHandler = response -> { + HttpEntity entity = response.getEntity(); + return entity != null ? EntityUtils.toString(entity) : null; + }; + httpClient.execute(httpget, responseHandler); + } + } +} diff --git a/test/plugin/scenarios/struts2.7-scenario/src/main/java/org/apache/skywalking/apm/testcase/struts/HealthCheckServlet.java b/test/plugin/scenarios/struts2.7-scenario/src/main/java/org/apache/skywalking/apm/testcase/struts/HealthCheckServlet.java new file mode 100644 index 0000000000..31458cea43 --- /dev/null +++ b/test/plugin/scenarios/struts2.7-scenario/src/main/java/org/apache/skywalking/apm/testcase/struts/HealthCheckServlet.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.skywalking.apm.testcase.struts; + +import java.io.IOException; +import java.io.PrintWriter; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +public class HealthCheckServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + // your codes + PrintWriter writer = resp.getWriter(); + writer.write("Success"); + writer.flush(); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + doGet(req, resp); + } +} diff --git a/test/plugin/scenarios/struts2.7-scenario/src/main/resources/log4j2.xml b/test/plugin/scenarios/struts2.7-scenario/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..b5cda5ae8a --- /dev/null +++ b/test/plugin/scenarios/struts2.7-scenario/src/main/resources/log4j2.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + --> +<Configuration status="WARN"> + <Appenders> + <Console name="Console" target="SYSTEM_ERR"> + <PatternLayout charset="UTF-8" pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/> + </Console> + </Appenders> + <Loggers> + <Root level="WARN"> + <AppenderRef ref="Console"/> + </Root> + </Loggers> +</Configuration> diff --git a/test/plugin/scenarios/struts2.7-scenario/src/main/resources/struts.xml b/test/plugin/scenarios/struts2.7-scenario/src/main/resources/struts.xml new file mode 100644 index 0000000000..109aadbf11 --- /dev/null +++ b/test/plugin/scenarios/struts2.7-scenario/src/main/resources/struts.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + --> +<!DOCTYPE struts PUBLIC + "-//Apache Software Foundation//DTD Struts Configuration 6.5//EN" + "https://struts.apache.org/dtds/struts-6.5.dtd"> + +<struts> + <package name="case" namespace="/case" extends="struts-default"> + <action name="case" class="org.apache.skywalking.apm.testcase.struts.CaseAction"> + <result name="SUCCESS">/jsp/success.jsp</result> + </action> + <action name="case1" class="org.apache.skywalking.apm.testcase.struts.Case1Action"> + <result name="SUCCESS">/jsp/success.jsp</result> + </action> + </package> +</struts> diff --git a/test/plugin/scenarios/struts2.7-scenario/src/main/webapp/WEB-INF/web.xml b/test/plugin/scenarios/struts2.7-scenario/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..a43b33cc55 --- /dev/null +++ b/test/plugin/scenarios/struts2.7-scenario/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,44 @@ +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + --> +<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee + https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd" + version="6.0"> + <display-name>skywalking-struts2.7-scenario</display-name> + + <filter> + <filter-name>struts2</filter-name> + <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> + </filter> + + <filter-mapping> + <filter-name>struts2</filter-name> + <url-pattern>/case/*</url-pattern> + </filter-mapping> + + <servlet> + <servlet-name>healthCheck</servlet-name> + <servlet-class>org.apache.skywalking.apm.testcase.struts.HealthCheckServlet</servlet-class> + </servlet> + + <servlet-mapping> + <servlet-name>healthCheck</servlet-name> + <url-pattern>/healthCheck</url-pattern> + </servlet-mapping> +</web-app> diff --git a/test/plugin/scenarios/struts2.7-scenario/src/main/webapp/jsp/success.jsp b/test/plugin/scenarios/struts2.7-scenario/src/main/webapp/jsp/success.jsp new file mode 100644 index 0000000000..82c72c0efe --- /dev/null +++ b/test/plugin/scenarios/struts2.7-scenario/src/main/webapp/jsp/success.jsp @@ -0,0 +1,25 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--%> +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<html> +<head> + <title>Title</title> +</head> +<body> +Success +</body> +</html> diff --git a/test/plugin/scenarios/struts2.7-scenario/support-version.list b/test/plugin/scenarios/struts2.7-scenario/support-version.list new file mode 100644 index 0000000000..5fcb5f103f --- /dev/null +++ b/test/plugin/scenarios/struts2.7-scenario/support-version.list @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +7.0.3 +7.1.1 +7.2.1 diff --git a/tools/plugin/genernate-javaagent-plugin-list.txt b/tools/plugin/genernate-javaagent-plugin-list.txt new file mode 100644 index 0000000000..82a9e1f733 --- /dev/null +++ b/tools/plugin/genernate-javaagent-plugin-list.txt @@ -0,0 +1,191 @@ +activemq-5.x +activemq-artemis-jakarta-client-2.x +aerospike +apache-cxf-3.x +armeria-063-084 +armeria-085 +armeria-086 +armeria-098 +armeria-100 +async-http-client-2.x +avro-1.x +brpc-java +brpc-java-3.x +c3p0-0.9.x +caffeine-3.x +canal-1.x +cassandra-java-driver-3.x +clickhouse-0.3.1 +clickhouse-0.3.2.x +dbcp-2.x +druid-1.x +dubbo +dubbo-2.7.x +dubbo-3.x +dubbo-threadpool +dubbo-threadpool-2.7.x +ehcache-2.x +elastic-job-2.x +elasticjob-3.x +elasticsearch-5.x +elasticsearch-6.x +elasticsearch-7.x +elasticsearch-java +fastjson-1.2.x +feign-default-http-9.x +feign-pathvar-9.x +finagle +graphql-12.x-15.x +graphql-16plus +graphql-8.x +graphql-9.x +grizzly-2.3.x-4.x +grizzly-2.3.x-4.x-threadpool +grpc-1.x +gson-2.8.x +guava-cache +guava-eventbus +h2-1.x +hbase-1.x/2.x +hikaricp-3.x/4.x +httpasyncclient-4.x +httpclient-3.x +httpclient-4.x +httpclient-5.x +hutool-http-5.x +hystrix-1.x +impala-jdbc-2.6.x +influxdb-2.x +jackson-2.x +jdk-forkjoinpool-plugin +jdk-http-plugin +jdk-httpclient-plugin +jdk-threading-plugin +jdk-threadpool-plugin +jdk-virtual-thread-executor-plugin +jedis-2.x-3.x +jedis-4.x +jersey-2.x +jersey-3.x +jetty-client-11.x +jetty-client-9.0 +jetty-client-9.x +jetty-server +jetty-server-12.x +jetty-thread-pool +jsonrpc4j +kafka-0.11.x/1.x/2.x +kafka-3.7.x +kafka-3.9.x +kotlin-coroutine +kylin-jdbc-2.6.x-3.x-4.x +lettuce-5.x-6.4.x +lettuce-6.5.x +lettuce-common +light4j +mariadb-2.x +mariadb-3.x +memcache-2.x +micrometer-1.10.x +micronaut-http-client-3.2.x-3.6.x +micronaut-http-server-3.2.x-3.6.x +mongodb-2.x +mongodb-3.x +mongodb-4.x +mongodb-5.x +motan-0.x +mssql-jdbc +mssql-jtds-1.x +mybatis-3.x +mysql-5.x +mysql-6.x +mysql-8.x +nacos-client-2.x +nats-client-2.14.x-2.16.5 +neo4j-4.x +netty-http-4.1.x +netty-socketio +nutz-http-1.x +nutz-mvc-annotation-1.x +okhttp-2.x +okhttp-3.x +okhttp-4.x +play-2.x +postgresql-8.x +pulsar-2.2-2.7 +pulsar-2.8.x +quartz-scheduler-2.x +quasar +rabbitmq +redisson-3.x +resteasy-server-3.x +resteasy-server-4.x +resteasy-server-6.x +rocketMQ-3.x +rocketMQ-4.x +rocketMQ-5.x +rocketMQ-client-java-5.x +sentinel-1.x +servicecomb-2.x +sharding-sphere-3.x +sharding-sphere-4.0.0 +sharding-sphere-4.1.0 +sharding-sphere-5.0.0 +shenyu-2.4.x +sofarpc +solon-2.x +solrj-7.x +spring-ai-1.x +spring-annotation +spring-async-annotation-5.x +spring-cloud-feign-1.x +spring-cloud-feign-2.x +spring-cloud-gateway-2.0.x +spring-cloud-gateway-2.1.x +spring-cloud-gateway-3.x +spring-cloud-gateway-4.x +spring-concurrent-util-4.x +spring-core-patch +spring-kafka-1.x +spring-kafka-2.x +spring-mvc-annotation +spring-mvc-annotation-3.x +spring-mvc-annotation-4.x +spring-mvc-annotation-5.x +spring-mvc-annotation-6.x +spring-rabbitmq +spring-resttemplate-3.x +spring-resttemplate-4.x +spring-resttemplate-6.x +spring-scheduled-annotation +spring-tx +spring-webflux-5.x +spring-webflux-5.x-webclient +spring-webflux-6.x +spring-webflux-6.x-webclient +spymemcached-2.x +struts2-2.x +struts2-7.x +thrift +tomcat +tomcat-thread-pool +toolkit-counter +toolkit-exception +toolkit-gauge +toolkit-histogram +toolkit-kafka +toolkit-log4j +toolkit-log4j2 +toolkit-logback +toolkit-opentracing +toolkit-tag +toolkit-trace +toolkit-tracer +toolkit-webflux +undertow-2.x-plugin +undertow-worker-thread-pool +vertx-core-3.x +vertx-core-4.x +websphere-liberty-23.x +xxl-job-2.x +zookeeper-3.4.x diff --git a/tools/plugin/md-javaagent-plugin-list.txt b/tools/plugin/md-javaagent-plugin-list.txt new file mode 100644 index 0000000000..82a9e1f733 --- /dev/null +++ b/tools/plugin/md-javaagent-plugin-list.txt @@ -0,0 +1,191 @@ +activemq-5.x +activemq-artemis-jakarta-client-2.x +aerospike +apache-cxf-3.x +armeria-063-084 +armeria-085 +armeria-086 +armeria-098 +armeria-100 +async-http-client-2.x +avro-1.x +brpc-java +brpc-java-3.x +c3p0-0.9.x +caffeine-3.x +canal-1.x +cassandra-java-driver-3.x +clickhouse-0.3.1 +clickhouse-0.3.2.x +dbcp-2.x +druid-1.x +dubbo +dubbo-2.7.x +dubbo-3.x +dubbo-threadpool +dubbo-threadpool-2.7.x +ehcache-2.x +elastic-job-2.x +elasticjob-3.x +elasticsearch-5.x +elasticsearch-6.x +elasticsearch-7.x +elasticsearch-java +fastjson-1.2.x +feign-default-http-9.x +feign-pathvar-9.x +finagle +graphql-12.x-15.x +graphql-16plus +graphql-8.x +graphql-9.x +grizzly-2.3.x-4.x +grizzly-2.3.x-4.x-threadpool +grpc-1.x +gson-2.8.x +guava-cache +guava-eventbus +h2-1.x +hbase-1.x/2.x +hikaricp-3.x/4.x +httpasyncclient-4.x +httpclient-3.x +httpclient-4.x +httpclient-5.x +hutool-http-5.x +hystrix-1.x +impala-jdbc-2.6.x +influxdb-2.x +jackson-2.x +jdk-forkjoinpool-plugin +jdk-http-plugin +jdk-httpclient-plugin +jdk-threading-plugin +jdk-threadpool-plugin +jdk-virtual-thread-executor-plugin +jedis-2.x-3.x +jedis-4.x +jersey-2.x +jersey-3.x +jetty-client-11.x +jetty-client-9.0 +jetty-client-9.x +jetty-server +jetty-server-12.x +jetty-thread-pool +jsonrpc4j +kafka-0.11.x/1.x/2.x +kafka-3.7.x +kafka-3.9.x +kotlin-coroutine +kylin-jdbc-2.6.x-3.x-4.x +lettuce-5.x-6.4.x +lettuce-6.5.x +lettuce-common +light4j +mariadb-2.x +mariadb-3.x +memcache-2.x +micrometer-1.10.x +micronaut-http-client-3.2.x-3.6.x +micronaut-http-server-3.2.x-3.6.x +mongodb-2.x +mongodb-3.x +mongodb-4.x +mongodb-5.x +motan-0.x +mssql-jdbc +mssql-jtds-1.x +mybatis-3.x +mysql-5.x +mysql-6.x +mysql-8.x +nacos-client-2.x +nats-client-2.14.x-2.16.5 +neo4j-4.x +netty-http-4.1.x +netty-socketio +nutz-http-1.x +nutz-mvc-annotation-1.x +okhttp-2.x +okhttp-3.x +okhttp-4.x +play-2.x +postgresql-8.x +pulsar-2.2-2.7 +pulsar-2.8.x +quartz-scheduler-2.x +quasar +rabbitmq +redisson-3.x +resteasy-server-3.x +resteasy-server-4.x +resteasy-server-6.x +rocketMQ-3.x +rocketMQ-4.x +rocketMQ-5.x +rocketMQ-client-java-5.x +sentinel-1.x +servicecomb-2.x +sharding-sphere-3.x +sharding-sphere-4.0.0 +sharding-sphere-4.1.0 +sharding-sphere-5.0.0 +shenyu-2.4.x +sofarpc +solon-2.x +solrj-7.x +spring-ai-1.x +spring-annotation +spring-async-annotation-5.x +spring-cloud-feign-1.x +spring-cloud-feign-2.x +spring-cloud-gateway-2.0.x +spring-cloud-gateway-2.1.x +spring-cloud-gateway-3.x +spring-cloud-gateway-4.x +spring-concurrent-util-4.x +spring-core-patch +spring-kafka-1.x +spring-kafka-2.x +spring-mvc-annotation +spring-mvc-annotation-3.x +spring-mvc-annotation-4.x +spring-mvc-annotation-5.x +spring-mvc-annotation-6.x +spring-rabbitmq +spring-resttemplate-3.x +spring-resttemplate-4.x +spring-resttemplate-6.x +spring-scheduled-annotation +spring-tx +spring-webflux-5.x +spring-webflux-5.x-webclient +spring-webflux-6.x +spring-webflux-6.x-webclient +spymemcached-2.x +struts2-2.x +struts2-7.x +thrift +tomcat +tomcat-thread-pool +toolkit-counter +toolkit-exception +toolkit-gauge +toolkit-histogram +toolkit-kafka +toolkit-log4j +toolkit-log4j2 +toolkit-logback +toolkit-opentracing +toolkit-tag +toolkit-trace +toolkit-tracer +toolkit-webflux +undertow-2.x-plugin +undertow-worker-thread-pool +vertx-core-3.x +vertx-core-4.x +websphere-liberty-23.x +xxl-job-2.x +zookeeper-3.4.x
