Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c4f091a
Update docs and changelog for JDK 25 support
Siman-hub Jan 16, 2026
0393f23
Upgrade build system and CI for JDK 25 support
Siman-hub Jan 16, 2026
8dee778
Revert compiler source to 11 to maintain backward compatibility
Siman-hub Jan 16, 2026
3e8477c
Merge branch 'master' into jdk-25-support
Siman-hub Jan 16, 2026
dc065cf
Upgrade Mockito to 5.11.0 and ByteBuddy to 1.17.0 for JDK 25 support
Siman-hub Jan 16, 2026
8eb19c9
Fix: Enable JDK 25 support by upgrading Groovy and isolating Mockito …
Siman-hub Jan 16, 2026
8d72c3c
Refactor: Centralize Mockito 5 dependencies in Root POM and fix Analy…
Siman-hub Jan 17, 2026
78fbec2
Doc: Update LICENSE file for ByteBuddy 1.17.0
Siman-hub Jan 17, 2026
1e7e24b
Doc: Align LICENSE with distribution artifacts after dependency updates
Siman-hub Jan 17, 2026
c8a1da6
Test: Fix Mockito 5 compatibility issues in MeterProcessorTest and Te…
Siman-hub Jan 17, 2026
a6d29af
Build: Fix E2E Java service compilation on JDK 25 by enabling Lombok …
Siman-hub Jan 18, 2026
472dafe
Merge branch 'master' into jdk-25-support
wu-sheng Jan 18, 2026
f903c40
Skip MeterProcessorTest on JDK 25+ due to Groovy incompatibility
Siman-hub Jan 18, 2026
b341153
Merge branch 'master' into jdk-25-support
Siman-hub Jan 22, 2026
7374f25
Enable MeterProcessorTest on JDK 25 (Groovy 5 support confirmed)
Siman-hub Jan 22, 2026
ab544f7
Update oap-server/analyzer/meter-analyzer/pom.xml
Siman-hub Jan 23, 2026
48eb536
Enable JDK 25 support for E2E Java services
Siman-hub Jan 23, 2026
095bea1
Restore ASF license header in E2E parent POM
Siman-hub Jan 23, 2026
a2df108
reverting unneccary residual changes
Siman-hub Jan 23, 2026
11a1dc5
Align Java agent image with JDK 25 support
Siman-hub Jan 25, 2026
fc9ad39
Apply suggestions from code review
wankai123 Jan 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/publish-docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 5 additions & 3 deletions .github/workflows/skywalking.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions docs/en/changes/changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
2 changes: 1 addition & 1 deletion docs/en/guides/How-to-build.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;
Expand All @@ -44,14 +48,9 @@
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;
Expand Down Expand Up @@ -83,10 +82,13 @@ public void setup() throws StorageException, ModuleStartException {
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);
Expand All @@ -103,15 +105,15 @@ public void testProcess() {
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();

Expand All @@ -129,4 +131,4 @@ public void testProcess() {
Assertions.assertEquals(count, func.getCount());
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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());

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -87,27 +87,33 @@ public void setupMetrics() throws Throwable {
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);

Expand Down Expand Up @@ -482,4 +488,4 @@ public void testWrongSampleNumbersOfSampleFamilyWithSameTimestamp() {
"Expected AssertionError to throw, but it didn't.");
}

}
}
31 changes: 17 additions & 14 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -374,6 +363,20 @@
<build>
<pluginManagement>
<plugins>
<plugin>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this added?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is added to enable Lombok annotation processing explicitly. Without it, the E2E Java test service fails to compile under JDK 25 (missing Lombok-generated methods like builder()), while older JDKs work implicitly. This keeps the behavior consistent across JDK versions.

<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>
Expand Down
Loading
Loading