This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking.git


The following commit(s) were added to refs/heads/master by this push:
     new 5e3b3853f5 Support Java 25 for build, test, and Docker publishing 
(#13671)
5e3b3853f5 is described below

commit 5e3b3853f5742f906655f3e332459c74b58cfb43
Author: Siman-hub <[email protected]>
AuthorDate: Mon Jan 26 09:32:24 2026 +0530

    Support Java 25 for build, test, and Docker publishing (#13671)
---
 .github/workflows/publish-docker.yaml              |  5 ++
 .github/workflows/skywalking.yaml                  |  8 +-
 docs/en/changes/changes.md                         |  1 +
 docs/en/guides/How-to-build.md                     |  2 +-
 .../provider/meter/process/MeterProcessorTest.java | 40 +++++-----
 .../oap/meter/analyzer/dsl/AnalyzerTest.java       |  8 +-
 .../receiver/telegraf/TelegrafMetricsTest.java     | 40 ++++++----
 pom.xml                                            | 31 ++++----
 test/e2e-v2/java-test-service/pom.xml              | 92 ++++++++++++++++++----
 test/e2e-v2/script/env                             |  2 +-
 10 files changed, 157 insertions(+), 72 deletions(-)

diff --git a/.github/workflows/publish-docker.yaml 
b/.github/workflows/publish-docker.yaml
index c5bf734e54..de78893219 100644
--- a/.github/workflows/publish-docker.yaml
+++ b/.github/workflows/publish-docker.yaml
@@ -85,6 +85,11 @@ jobs:
           SW_OAP_BASE_IMAGE: eclipse-temurin:21-jre
           TAG: ${{ env.TAG }}-java21
         run: make build.all docker.push
+      - name: Build and push docker images based on Java 25
+        env:
+          SW_OAP_BASE_IMAGE: eclipse-temurin:25-jre
+          TAG: ${{ env.TAG }}-java25
+        run: make build.all docker.push
       - name: Build and push docker images
         run: make build.all docker.push
       - name: Build and push data-generator image
diff --git a/.github/workflows/skywalking.yaml 
b/.github/workflows/skywalking.yaml
index c0e3b12aa9..695b18f50b 100644
--- a/.github/workflows/skywalking.yaml
+++ b/.github/workflows/skywalking.yaml
@@ -198,7 +198,7 @@ jobs:
     timeout-minutes: 30
     strategy:
       matrix:
-        java-version: [11, 17]
+        java-version: [11, 17, 25]
     steps:
       - uses: actions/checkout@v4
         with:
@@ -244,6 +244,8 @@ jobs:
             java-version: 17
           - os: ubuntu-latest
             java-version: 21
+          - os: ubuntu-latest
+            java-version: 25
     steps:
       - uses: actions/checkout@v4
         with:
@@ -272,7 +274,7 @@ jobs:
     timeout-minutes: 60
     strategy:
       matrix:
-        java-version: [11, 17, 21]
+        java-version: [11, 17, 21, 25]
     steps:
       - uses: actions/checkout@v4
         with:
@@ -932,7 +934,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        java-version: [11, 17]
+        java-version: [11, 17, 25]
     steps:
       - uses: actions/checkout@v4
         with:
diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md
index 72d853451a..3456dcfc65 100644
--- a/docs/en/changes/changes.md
+++ b/docs/en/changes/changes.md
@@ -2,6 +2,7 @@
 
 #### Project
 * Fix E2E test metrics verify: make it failure if the metric values all null.
+* Support building, testing, and publishing with Java 25.
 * Add `CLAUDE.md` as AI assistant guide for the project.
 * Upgrade Groovy to 5.0.3 in OAP backend.
 
diff --git a/docs/en/guides/How-to-build.md b/docs/en/guides/How-to-build.md
index ed2200193f..2748d40897 100644
--- a/docs/en/guides/How-to-build.md
+++ b/docs/en/guides/How-to-build.md
@@ -16,7 +16,7 @@ If you need to execute build behind the proxy, edit the 
*.mvn/jvm.config* and se
 ```
 
 ### Building from GitHub
-1. Prepare git, JDK 11, 17, 21 (LTS versions), and Maven 3.6+.
+1. Prepare git, JDK 11, 17, 21, 25 (LTS versions), and Maven 3.6+.
 1. Clone the project.
 
     If you want to build a release from source codes, set a `tag name` by 
using `git clone -b [tag_name] ...` while cloning.
diff --git 
a/oap-server/analyzer/agent-analyzer/src/test/java/org/apache/skywalking/oap/server/analyzer/provider/meter/process/MeterProcessorTest.java
 
b/oap-server/analyzer/agent-analyzer/src/test/java/org/apache/skywalking/oap/server/analyzer/provider/meter/process/MeterProcessorTest.java
index 01ed4c4082..6898f4e453 100644
--- 
a/oap-server/analyzer/agent-analyzer/src/test/java/org/apache/skywalking/oap/server/analyzer/provider/meter/process/MeterProcessorTest.java
+++ 
b/oap-server/analyzer/agent-analyzer/src/test/java/org/apache/skywalking/oap/server/analyzer/provider/meter/process/MeterProcessorTest.java
@@ -6,7 +6,7 @@
  * (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
+ * 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,
@@ -18,6 +18,10 @@
 
 package org.apache.skywalking.oap.server.analyzer.provider.meter.process;
 
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
 import org.apache.skywalking.apm.network.language.agent.v3.MeterBucketValue;
 import org.apache.skywalking.apm.network.language.agent.v3.MeterData;
 import org.apache.skywalking.apm.network.language.agent.v3.MeterHistogram;
@@ -44,14 +48,9 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.powermock.reflect.Whitebox;
 
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
-
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doAnswer;
@@ -83,10 +82,13 @@ public class MeterProcessorTest {
         
when(moduleManager.find(anyString())).thenReturn(mock(ModuleProviderHolder.class));
         
when(moduleManager.find(CoreModule.NAME).provider()).thenReturn(mock(ModuleServiceHolder.class));
         
when(moduleManager.find(CoreModule.NAME).provider().getService(MeterSystem.class)).thenReturn(meterSystem);
-        Whitebox.setInternalState(MetricsStreamProcessor.class, "PROCESSOR",
-                Mockito.spy(MetricsStreamProcessor.getInstance())
+        MetricsStreamProcessor mockProcessor = 
mock(MetricsStreamProcessor.class);
+        Whitebox.setInternalState(
+                MetricsStreamProcessor.class,
+                "PROCESSOR",
+                mockProcessor
         );
-        doNothing().when(MetricsStreamProcessor.getInstance()).create(any(), 
(StreamDefinition) any(), any());
+        doNothing().when(mockProcessor).create(any(), (StreamDefinition) 
any(), any());
         final MeterProcessService processService = new 
MeterProcessService(moduleManager);
         List<MeterConfig> config = 
MeterConfigs.loadConfig("meter-analyzer-config", Arrays.asList("config"));
         processService.start(config);
@@ -103,15 +105,15 @@ public class MeterProcessorTest {
             return null;
         }).when(meterSystem).doStreamingCalculation(any());
         processor.read(MeterData.newBuilder()
-                        .setService(service)
-                        .setServiceInstance(serviceInstance)
-                        .setTimestamp(System.currentTimeMillis())
-                        .setHistogram(MeterHistogram.newBuilder()
-                                .setName("test_histogram")
-                                
.addValues(MeterBucketValue.newBuilder().setIsNegativeInfinity(true).setCount(10).build())
-                                
.addValues(MeterBucketValue.newBuilder().setBucket(0).setCount(20).build())
-                                
.addValues(MeterBucketValue.newBuilder().setBucket(10).setCount(10).build())
-                                .build())
+                .setService(service)
+                .setServiceInstance(serviceInstance)
+                .setTimestamp(System.currentTimeMillis())
+                .setHistogram(MeterHistogram.newBuilder()
+                        .setName("test_histogram")
+                        
.addValues(MeterBucketValue.newBuilder().setIsNegativeInfinity(true).setCount(10).build())
+                        
.addValues(MeterBucketValue.newBuilder().setBucket(0).setCount(20).build())
+                        
.addValues(MeterBucketValue.newBuilder().setBucket(10).setCount(10).build())
+                        .build())
                 .build());
         processor.process();
 
@@ -129,4 +131,4 @@ public class MeterProcessorTest {
         Assertions.assertEquals(count, func.getCount());
     }
 
-}
+}
\ No newline at end of file
diff --git 
a/oap-server/analyzer/meter-analyzer/src/test/java/org/apache/skywalking/oap/meter/analyzer/dsl/AnalyzerTest.java
 
b/oap-server/analyzer/meter-analyzer/src/test/java/org/apache/skywalking/oap/meter/analyzer/dsl/AnalyzerTest.java
index be3b27bdfe..52d1467db3 100644
--- 
a/oap-server/analyzer/meter-analyzer/src/test/java/org/apache/skywalking/oap/meter/analyzer/dsl/AnalyzerTest.java
+++ 
b/oap-server/analyzer/meter-analyzer/src/test/java/org/apache/skywalking/oap/meter/analyzer/dsl/AnalyzerTest.java
@@ -66,9 +66,11 @@ public class AnalyzerTest {
     @BeforeEach
     public void setup() throws StorageException {
         meterSystem = spy(new MeterSystem(moduleManager));
-        Whitebox.setInternalState(MetricsStreamProcessor.class, "PROCESSOR",
-                                  
Mockito.spy(MetricsStreamProcessor.getInstance())
-        );
+        // Fix for JDK 25 / Mockito 5: Prevent double-spying on the singleton
+        MetricsStreamProcessor instance = MetricsStreamProcessor.getInstance();
+        if (!Mockito.mockingDetails(instance).isMock()) {
+            Whitebox.setInternalState(MetricsStreamProcessor.class, 
"PROCESSOR", Mockito.spy(instance));
+        }
         doNothing().when(MetricsStreamProcessor.getInstance()).create(any(), 
(StreamDefinition) any(), any());
 
     }
diff --git 
a/oap-server/server-receiver-plugin/skywalking-telegraf-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/telegraf/TelegrafMetricsTest.java
 
b/oap-server/server-receiver-plugin/skywalking-telegraf-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/telegraf/TelegrafMetricsTest.java
index dc658436ff..4a5e151348 100644
--- 
a/oap-server/server-receiver-plugin/skywalking-telegraf-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/telegraf/TelegrafMetricsTest.java
+++ 
b/oap-server/server-receiver-plugin/skywalking-telegraf-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/telegraf/TelegrafMetricsTest.java
@@ -6,7 +6,7 @@
  * (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
+ * 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,
@@ -87,27 +87,33 @@ public class TelegrafMetricsTest {
         moduleManager = new MockModuleManager() {
             @Override
             protected void init() {
-            register(CoreModule.NAME, () -> new MockModuleProvider() {
-                @Override
-                protected void register() {
-                    registerServiceImplementation(NamingControl.class, new 
NamingControl(
-                            512, 512, 512, new EndpointNameGrouping()));
-                }
-            });
-            register(TelemetryModule.NAME, () -> new MockModuleProvider() {
-                @Override
-                protected void register() {
-                    registerServiceImplementation(MetricsCreator.class, new 
MetricsCreatorNoop());
-                }
-            });
+                register(CoreModule.NAME, () -> new MockModuleProvider() {
+                    @Override
+                    protected void register() {
+                        registerServiceImplementation(NamingControl.class, new 
NamingControl(
+                                512, 512, 512, new EndpointNameGrouping()));
+                    }
+                });
+                register(TelemetryModule.NAME, () -> new MockModuleProvider() {
+                    @Override
+                    protected void register() {
+                        registerServiceImplementation(MetricsCreator.class, 
new MetricsCreatorNoop());
+                    }
+                });
             }
         };
 
         // prepare the context
         meterSystem = Mockito.mock(MeterSystem.class);
+
+        // FIX 1: Removed spy() wrapper.
+        // We use the instance directly. If it is a Mock (from other tests), 
using it directly is fine.
         Whitebox.setInternalState(MetricsStreamProcessor.class, "PROCESSOR",
-                Mockito.spy(MetricsStreamProcessor.getInstance()));
-        CoreModule coreModule = Mockito.spy(CoreModule.class);
+                MetricsStreamProcessor.getInstance());
+
+        // FIX 2: Changed spy(CoreModule.class) to mock(CoreModule.class)
+        // Spying on a Class literal is invalid in modern Mockito.
+        CoreModule coreModule = Mockito.mock(CoreModule.class);
 
         Whitebox.setInternalState(coreModule, "loadedProvider", 
moduleProvider);
 
@@ -482,4 +488,4 @@ public class TelegrafMetricsTest {
                 "Expected AssertionError to throw, but it didn't.");
     }
 
-}
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index b75ae2c9b4..6e5575ea89 100755
--- a/pom.xml
+++ b/pom.xml
@@ -159,10 +159,10 @@
         <powermock.version>2.0.9</powermock.version>
         <checkstyle.version>6.18</checkstyle.version>
         <junit.version>5.9.2</junit.version>
-        <mockito-core.version>4.11.0</mockito-core.version>
+        <mockito-core.version>5.11.0</mockito-core.version>
         <system-stubs.version>2.1.4</system-stubs.version>
-        <lombok.version>1.18.30</lombok.version>
-        <byte-buddy.version>1.14.9</byte-buddy.version>
+        <lombok.version>1.18.40</lombok.version>
+        <byte-buddy.version>1.17.0</byte-buddy.version>
 
         <!-- core lib dependency -->
         <grpc.version>1.70.0</grpc.version>
@@ -221,11 +221,6 @@
             <artifactId>mockito-core</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>org.mockito</groupId>
-            <artifactId>mockito-inline</artifactId>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-junit-jupiter</artifactId>
@@ -279,12 +274,6 @@
                 <version>${mockito-core.version}</version>
                 <scope>test</scope>
             </dependency>
-            <dependency>
-                <groupId>org.mockito</groupId>
-                <artifactId>mockito-inline</artifactId>
-                <version>${mockito-core.version}</version>
-                <scope>test</scope>
-            </dependency>
             <dependency>
                 <groupId>org.mockito</groupId>
                 <artifactId>mockito-junit-jupiter</artifactId>
@@ -374,6 +363,20 @@
     <build>
         <pluginManagement>
             <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>3.13.0</version>
+                    <configuration>
+                        <annotationProcessorPaths>
+                            <path>
+                                <groupId>org.projectlombok</groupId>
+                                <artifactId>lombok</artifactId>
+                                <version>${lombok.version}</version>
+                            </path>
+                        </annotationProcessorPaths>
+                    </configuration>
+                </plugin>
                 <plugin>
                     <groupId>org.apache.maven.plugins</groupId>
                     <artifactId>maven-failsafe-plugin</artifactId>
diff --git a/test/e2e-v2/java-test-service/pom.xml 
b/test/e2e-v2/java-test-service/pom.xml
index 3c4ef358b8..f7206b423a 100644
--- a/test/e2e-v2/java-test-service/pom.xml
+++ b/test/e2e-v2/java-test-service/pom.xml
@@ -53,26 +53,28 @@
         <guava.version>30.1.1-jre</guava.version>
         <h2.version>2.1.210</h2.version>
         <mysql.version>8.0.13</mysql.version>
-        <lombok.version>1.18.30</lombok.version>
+        <lombok.version>1.18.40</lombok.version>
         <kafka-clients.version>2.4.1</kafka-clients.version>
 
         <maven-failsafe-plugin.version>2.22.0</maven-failsafe-plugin.version>
-        <maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version>
+        <maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
         
<maven-checkstyle-plugin.version>3.1.0</maven-checkstyle-plugin.version>
+
+        <main.source.dir>src/main/java</main.source.dir>
     </properties>
 
     <repositories>
-       <repository>
-           <id>apache.snapshots</id>
-           <name>Apache Development Snapshot Repository</name>
-           <url>https://repository.apache.org/content/groups/snapshots/</url>
-           <releases>
-               <enabled>false</enabled>
-           </releases>
-           <snapshots>
-               <enabled>true</enabled>
-           </snapshots>
-       </repository>
+        <repository>
+            <id>apache.snapshots</id>
+            <name>Apache Development Snapshot Repository</name>
+            <url>https://repository.apache.org/content/groups/snapshots/</url>
+            <releases>
+                <enabled>false</enabled>
+            </releases>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </repository>
     </repositories>
 
     <dependencyManagement>
@@ -124,6 +126,8 @@
     </dependencies>
 
     <build>
+        <sourceDirectory>${main.source.dir}</sourceDirectory>
+
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
@@ -173,4 +177,64 @@
         </plugins>
     </build>
 
-</project>
+    <profiles>
+        <profile>
+            <id>jdk-25</id>
+            <activation>
+                <jdk>[25,)</jdk>
+            </activation>
+            <properties>
+                
<main.source.dir>${project.build.directory}/delombok</main.source.dir>
+            </properties>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.projectlombok</groupId>
+                        <artifactId>lombok-maven-plugin</artifactId>
+                        <version>1.18.20.0</version>
+                        <executions>
+                            <execution>
+                                <phase>generate-sources</phase>
+                                <goals>
+                                    <goal>delombok</goal>
+                                </goals>
+                                <configuration>
+                                    <encoding>UTF-8</encoding>
+                                    
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
+                                    
<addOutputDirectory>false</addOutputDirectory>
+                                    
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
+                                </configuration>
+                            </execution>
+                        </executions>
+                        <dependencies>
+                            <dependency>
+                                <groupId>org.projectlombok</groupId>
+                                <artifactId>lombok</artifactId>
+                                <version>1.18.40</version>
+                            </dependency>
+                        </dependencies>
+                    </plugin>
+
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-compiler-plugin</artifactId>
+                        <configuration>
+                            <compilerArgs>
+                                <arg>-proc:none</arg>
+                            </compilerArgs>
+                        </configuration>
+                    </plugin>
+
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-checkstyle-plugin</artifactId>
+                        <configuration>
+                            <skip>true</skip>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+</project>
\ No newline at end of file
diff --git a/test/e2e-v2/script/env b/test/e2e-v2/script/env
index 4b6b9432fc..2facf48972 100644
--- a/test/e2e-v2/script/env
+++ b/test/e2e-v2/script/env
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_AGENT_JAVA_COMMIT=f0245864e4388a388fe7445b56b6ce7cedc94aaf
+SW_AGENT_JAVA_COMMIT=2a61027e5eb74ed1258c764ae2ffeabd499416a6
 SW_AGENT_SATELLITE_COMMIT=ea27a3f4e126a24775fe12e2aa2695bcb23d99c3
 SW_AGENT_NGINX_LUA_COMMIT=c3cee4841798a147d83b96a10914d4ac0e11d0aa
 SW_AGENT_NODEJS_COMMIT=4f9a91dad3dfd8cfe5ba8f7bd06b39e11eb5e65e

Reply via email to