Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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.

#### OAP Server
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 @@ -39,19 +43,15 @@
import org.apache.skywalking.oap.server.library.module.ModuleServiceHolder;
import org.apache.skywalking.oap.server.library.module.ModuleStartException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.BeforeAll;
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;
Expand Down Expand Up @@ -79,14 +79,22 @@ public static void init() {

@BeforeEach
public void setup() throws StorageException, ModuleStartException {
Assumptions.assumeTrue(
Double.parseDouble(System.getProperty("java.specification.version")) < 25,
"Skip MeterProcessorTest on JDK 25+ due to Groovy incompatibility"
);

meterSystem = spy(new MeterSystem(moduleManager));
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 +111,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 +137,4 @@ public void testProcess() {
Assertions.assertEquals(count, func.getCount());
}

}
}
1 change: 1 addition & 0 deletions oap-server/analyzer/meter-analyzer/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<dependency>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy</artifactId>
<version>4.0.29</version>
</dependency>
<dependency>
<groupId>io.vavr</groupId>
Expand Down
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
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
8 changes: 8 additions & 0 deletions test/e2e-v2/java-test-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>

<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
Expand Down
Loading