diff --git a/.claude/skills/new-plugin/SKILL.md b/.claude/skills/new-plugin/SKILL.md
index d960d07058..14008fdf35 100644
--- a/.claude/skills/new-plugin/SKILL.md
+++ b/.claude/skills/new-plugin/SKILL.md
@@ -249,6 +249,11 @@ apm-sniffer/optional-plugins/{name}-plugin/
- Never bundle target library classes into the plugin JAR
- If the plugin needs a 3rd-party utility not already in agent-core, discuss with maintainers first
+**CRITICAL compiler level rule:**
+- Do NOT set `maven.compiler.release` or `maven.compiler.source/target` unless the plugin source code itself uses JDK 9+ language features (e.g., `var`, records, sealed classes, `java.net.http.HttpClient`).
+- A `provided`-scope dependency targeting a higher JDK (e.g., Spring AI requires JDK 17+) does NOT require raising the compiler level — the plugin only references the library's API at compile time.
+- Bootstrap plugins like `jdk-httpclient-plugin` (which uses JDK 11 `HttpClient` API directly in plugin source code) legitimately need a higher compiler target. SDK plugins and optional plugins generally should not.
+
### Register in Parent POM
Add the new module to the parent `pom.xml`:
@@ -1052,6 +1057,7 @@ Before submitting:
- [ ] Types in `PascalCase`, variables in `camelCase`
- [ ] Imports only from `java.*`, `org.apache.skywalking.*`, `net.bytebuddy.*` (in instrumentation files)
- [ ] Target library dependencies in `provided` scope
+- [ ] No unnecessary `maven.compiler.release` or `maven.compiler.source/target` (only set if plugin source uses JDK 9+ language features)
- [ ] Using V2 API for new plugins
- [ ] String literals (not `.class` references) in instrumentation definitions
- [ ] `skywalking-plugin.def` registered
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 0bc7a9c0e9..e8a4a2bfb1 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -73,6 +73,8 @@ jobs:
java-version: ${{ matrix.java-version }}
- name: Check Javaagent Plugin List
run: tools/plugin/check-javaagent-plugin-list.sh
+ - name: Check Plugin Compiler Overrides
+ run: tools/plugin/check-compiler-overrides.sh
- name: Install and Test
run: ./mvnw -q --batch-mode clean verify install javadoc:javadoc
diff --git a/CLAUDE.md b/CLAUDE.md
index 02c69c17e3..ab26fb02eb 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -292,5 +292,5 @@ GitHub Actions workflows:
3. **Respect checkstyle**: No System.out, no @author, no Chinese characters
4. **Use Lombok**: Prefer annotations over boilerplate code
5. **Test both unit and E2E**: Different test patterns for different scopes
-6. **Java version compatibility**: Agent core must maintain Java 8 compatibility, but individual plugins may target higher JDK versions (e.g., jdk-httpclient-plugin for JDK 11+, virtual-thread plugins for JDK 21+)
+6. **Java version compatibility**: Agent core must maintain Java 8 compatibility, but individual plugins may target higher JDK versions (e.g., jdk-httpclient-plugin for JDK 11+, virtual-thread plugins for JDK 21+). **Do NOT set `maven.compiler.release` or `maven.compiler.source/target` in a plugin pom.xml unless the plugin source code itself uses JDK 9+ language features.** A `provided`-scope dependency targeting a higher JDK does not require raising the compiler level — the plugin code only references the library's API at compile time and does not need to match the library's runtime JDK requirement.
7. **For plugin development**: See `apm-sniffer/apm-sdk-plugin/CLAUDE.md` and `apm-sniffer/bootstrap-plugins/CLAUDE.md`
diff --git a/apm-sniffer/apm-sdk-plugin/aerospike-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/aerospike-plugin/pom.xml
index f2c5ac64f4..be9a30a3a3 100644
--- a/apm-sniffer/apm-sdk-plugin/aerospike-plugin/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/aerospike-plugin/pom.xml
@@ -38,9 +38,5 @@
provided
-
- 8
- 8
-
diff --git a/apm-sniffer/apm-sdk-plugin/jedis-plugins/pom.xml b/apm-sniffer/apm-sdk-plugin/jedis-plugins/pom.xml
index a337f0c2f8..440d8a3232 100644
--- a/apm-sniffer/apm-sdk-plugin/jedis-plugins/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/jedis-plugins/pom.xml
@@ -24,8 +24,6 @@
- 8
- 8
UTF-8
diff --git a/apm-sniffer/apm-sdk-plugin/micronaut-plugins/micronaut-http-client-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/micronaut-plugins/micronaut-http-client-plugin/pom.xml
index a0955c19d2..0dbafa710d 100644
--- a/apm-sniffer/apm-sdk-plugin/micronaut-plugins/micronaut-http-client-plugin/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/micronaut-plugins/micronaut-http-client-plugin/pom.xml
@@ -27,11 +27,6 @@
micronaut-http-client-plugin
-
- 8
- 8
-
-
io.projectreactor
diff --git a/apm-sniffer/apm-sdk-plugin/micronaut-plugins/micronaut-http-server-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/micronaut-plugins/micronaut-http-server-plugin/pom.xml
index a8fd47deac..df12088c75 100644
--- a/apm-sniffer/apm-sdk-plugin/micronaut-plugins/micronaut-http-server-plugin/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/micronaut-plugins/micronaut-http-server-plugin/pom.xml
@@ -28,11 +28,6 @@
micronaut-http-server-plugin
jar
-
- 8
- 8
-
-
io.micronaut
diff --git a/apm-sniffer/apm-sdk-plugin/nats-2.14.x-2.16.5-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/nats-2.14.x-2.16.5-plugin/pom.xml
index 60bba313b0..6e115d8ade 100644
--- a/apm-sniffer/apm-sdk-plugin/nats-2.14.x-2.16.5-plugin/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/nats-2.14.x-2.16.5-plugin/pom.xml
@@ -29,11 +29,6 @@
nats-2.14.x-2.16.5-plugin
jar
-
- 8
- 8
-
-
io.nats
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/spring-ai-1.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/spring-plugins/spring-ai-1.x-plugin/pom.xml
index b6ea5c9863..295cf9d8ed 100644
--- a/apm-sniffer/apm-sdk-plugin/spring-plugins/spring-ai-1.x-plugin/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/spring-ai-1.x-plugin/pom.xml
@@ -32,7 +32,10 @@
http://maven.apache.org
- 17
+
+
@@ -44,4 +47,16 @@
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+ false
+
+
+
+
\ No newline at end of file
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/spring-ai-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/ai/v1/messages/InputMessages.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/spring-ai-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/ai/v1/messages/InputMessages.java
index 794748bc49..9a1b10ae8c 100644
--- a/apm-sniffer/apm-sdk-plugin/spring-plugins/spring-ai-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/ai/v1/messages/InputMessages.java
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/spring-ai-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/ai/v1/messages/InputMessages.java
@@ -93,7 +93,10 @@ public TextPart(String content) {
@Override
public Map toMap() {
- return Map.of("type", "text", "content", content != null ? content : "");
+ Map map = new LinkedHashMap<>();
+ map.put("type", "text");
+ map.put("content", content != null ? content : "");
+ return map;
}
}
@@ -268,4 +271,5 @@ private static List toolMessageParts(Message message) {
return parts;
}
+
}
diff --git a/apm-sniffer/apm-sdk-plugin/tomcat-10x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/tomcat-10x-plugin/pom.xml
index 62896f4b61..7c54849e28 100644
--- a/apm-sniffer/apm-sdk-plugin/tomcat-10x-plugin/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/tomcat-10x-plugin/pom.xml
@@ -28,8 +28,6 @@
tomcat-10x-plugin
- 8
- 8
10.0.22
diff --git a/tools/plugin/check-compiler-overrides.sh b/tools/plugin/check-compiler-overrides.sh
new file mode 100755
index 0000000000..601bcfe4d8
--- /dev/null
+++ b/tools/plugin/check-compiler-overrides.sh
@@ -0,0 +1,80 @@
+#!/usr/bin/env 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.
+#
+
+# Check that plugin pom.xml files do not set maven.compiler.release,
+# maven.compiler.source, or maven.compiler.target unless they are on
+# the allowlist. A provided-scope dependency targeting a higher JDK
+# does NOT justify raising the compiler level — only plugin source code
+# that uses JDK 9+ language features does.
+
+WORK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd ../.. && pwd)"
+
+# Plugins that override maven.compiler.release. Two categories:
+#
+# 1. JDK 11/17+ required: plugin source code uses higher-JDK APIs directly
+# (e.g., java.net.http.HttpClient). Sets maven.compiler.release=11/17/etc.
+#
+# 2. API visibility only: plugin source code is JDK 8 compatible, but provided
+# dependencies use java.lang.Record or other JDK 9+ types. Sets
+# (blank) to cancel the parent's --release 8
+# restriction, so the compiler can resolve those types. Bytecode remains
+# JDK 8 compatible.
+ALLOWLIST=(
+ # Category 1: JDK 11+ required
+ "bootstrap-plugins/jdk-httpclient-plugin"
+ # Category 2: API visibility only
+ "bootstrap-plugins/jdk-http-plugin"
+ "spring-plugins/spring-ai-1.x-plugin"
+)
+
+EXIT_CODE=0
+
+while IFS= read -r pom; do
+ # Check if this pom is on the allowlist
+ allowed=false
+ for entry in "${ALLOWLIST[@]}"; do
+ if [[ "${pom}" == *"${entry}"* ]]; then
+ allowed=true
+ break
+ fi
+ done
+
+ if [ "${allowed}" = true ]; then
+ continue
+ fi
+
+ # Report the violation
+ echo "ERROR: ${pom} sets a compiler level override but is not on the allowlist."
+ echo " If the plugin source code uses JDK 9+ language features, add it to the"
+ echo " allowlist in tools/plugin/check-compiler-overrides.sh."
+ echo " Otherwise, remove the compiler override from the pom.xml."
+ echo ""
+ EXIT_CODE=1
+done < <(grep -rl "maven\.compiler\.\(release\|source\|target\)" \
+ "${WORK_DIR}/apm-sniffer/apm-sdk-plugin" \
+ "${WORK_DIR}/apm-sniffer/bootstrap-plugins" \
+ "${WORK_DIR}/apm-sniffer/optional-plugins" \
+ "${WORK_DIR}/apm-sniffer/optional-reporter-plugins" \
+ --include="pom.xml")
+
+if [ ${EXIT_CODE} -eq 0 ]; then
+ echo "Compiler override check passed."
+fi
+
+exit ${EXIT_CODE}