Skip to content
Merged
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
9 changes: 7 additions & 2 deletions .github/workflows/build-common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,8 @@ jobs:
- 17
- 21
- 23
- 24-ea
- 24
- 25-ea
vm:
- hotspot
- openj9
Expand All @@ -256,7 +257,11 @@ jobs:
- true
exclude:
- vm: ${{ inputs.skip-openj9-tests && 'openj9' || '' }}
- test-java-version: 24-ea
- test-java-version: 23
vm: hotspot
- test-java-version: 24
vm: openj9
- test-java-version: 25-ea
vm: openj9
fail-fast: false
steps:
Expand Down
2 changes: 2 additions & 0 deletions custom-checks/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ dependencies {

otelJava {
minJavaVersionSupported.set(JavaVersion.VERSION_17)
// OtelInternalJavadocTest fails with 25-ea
maxJavaVersionForTests.set(JavaVersion.VERSION_24)
}

// We cannot use "--release" javac option here because that will forbid exporting com.sun.tools package.
Expand Down
2 changes: 1 addition & 1 deletion docs/supported-libraries.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ These are the JVMs and operating systems that the integration tests are run agai

| JVM | Versions | OS |
|-------------------------------------------------------------------------------------------|-------------------|-------------------|
| [OpenJDK (Eclipse Temurin)](https://adoptium.net/) | 8, 11, 17, 21, 23 | [`ubuntu-latest`] |
| [OpenJDK (Eclipse Temurin)](https://adoptium.net/) | 8, 11, 17, 21, 24 | [`ubuntu-latest`] |
| [OpenJ9 (IBM Semeru Runtimes)](https://developer.ibm.com/languages/java/semeru-runtimes/) | 8, 11, 17, 21, 23 | [`ubuntu-latest`] |

## Disabled instrumentations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ void shouldHaveDefaultMetrics() {

testing.waitAndAssertMetrics(
"io.opentelemetry.runtime-telemetry-java17",
metric -> metric.hasName("jvm.cpu.longlock"),
metric -> metric.hasName("jvm.cpu.limit"),
metric -> metric.hasName("jvm.cpu.context_switch"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ muzzle {
}
}

otelJava {
// groovy does not support 25-ea
maxJavaVersionForTests.set(JavaVersion.VERSION_24)
}

dependencies {
library("com.xuxueli:xxl-job-core:1.9.2") {
exclude("org.codehaus.groovy", "groovy")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ muzzle {
}
}

otelJava {
// groovy does not support 25-ea
maxJavaVersionForTests.set(JavaVersion.VERSION_24)
}

dependencies {
library("com.xuxueli:xxl-job-core:2.1.2") {
exclude("org.codehaus.groovy", "groovy")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ muzzle {
}
}

otelJava {
// groovy does not support 25-ea
maxJavaVersionForTests.set(JavaVersion.VERSION_24)
}

dependencies {
library("com.xuxueli:xxl-job-core:2.3.0") {
exclude("org.codehaus.groovy", "groovy")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
import static org.objectweb.asm.Opcodes.IRETURN;
import static org.objectweb.asm.Opcodes.L2I;
import static org.objectweb.asm.Opcodes.NEW;
import static org.objectweb.asm.Opcodes.PUTSTATIC;
import static org.objectweb.asm.Opcodes.RETURN;
Expand Down Expand Up @@ -82,21 +83,28 @@ private void addFields() {
addField("ADDRESS_SIZE", int.class);
}

private boolean hasSuitableField(String name, Class<?> type) {
private Field findSourceField(String name) {
try {
Field field = internalUnsafeClass.getDeclaredField(name);
return Modifier.isPublic(field.getModifiers()) && field.getType() == type;
return internalUnsafeClass.getDeclaredField(name);
} catch (NoSuchFieldException exception) {
return false;
return null;
}
}

private boolean isSuitableField(Field field, Class<?> type) {
// jdk25 changes field type from int to long for offsets
Copy link
Member

Choose a reason for hiding this comment

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

👍

return field != null
&& Modifier.isPublic(field.getModifiers())
&& (field.getType() == type || (field.getType() == long.class && type == int.class));
}

private void addField(String name, Class<?> type) {
if (!hasSuitableField(name, type)) {
Field field = findSourceField(name);
if (!isSuitableField(field, type)) {
throw new IllegalStateException(
"Could not find suitable field for " + name + " " + Type.getDescriptor(type));
}
fields.add(new FieldDescriptor(name, type));
fields.add(new FieldDescriptor(name, type, field.getType()));
}

private void addMethods() {
Expand Down Expand Up @@ -231,14 +239,15 @@ private void addMethod(
List<String> targetNameCandidates,
Class<?> returnType,
Class<?>... parameterTypes) {
String targetName = null;
Method target = null;
for (String candidate : targetNameCandidates) {
if (hasSuitableMethod(candidate, returnType, parameterTypes)) {
targetName = candidate;
Method method = findSourceMethod(candidate, parameterTypes);
if (isSuitableMethod(method, returnType)) {
target = method;
break;
}
}
if (targetName == null) {
if (target == null) {
if (optional) {
return;
}
Expand All @@ -248,18 +257,27 @@ private void addMethod(
+ " "
+ Type.getMethodDescriptor(Type.getType(returnType), toTypes(parameterTypes)));
}
methods.add(new MethodDescriptor(name, targetName, returnType, parameterTypes));
methods.add(
new MethodDescriptor(
name, target.getName(), returnType, target.getReturnType(), parameterTypes));
}

private boolean hasSuitableMethod(String name, Class<?> returnType, Class<?>... parameterTypes) {
private Method findSourceMethod(String name, Class<?>... parameterTypes) {
try {
Method method = internalUnsafeClass.getDeclaredMethod(name, parameterTypes);
return Modifier.isPublic(method.getModifiers()) && method.getReturnType() == returnType;
} catch (NoSuchMethodException e) {
return false;
return internalUnsafeClass.getDeclaredMethod(name, parameterTypes);
} catch (NoSuchMethodException exception) {
return null;
}
}

private boolean isSuitableMethod(Method method, Class<?> returnType) {
// jdk25 changes method return type from int to long for methods returning fields offsets
return method != null
&& Modifier.isPublic(method.getModifiers())
&& (method.getReturnType() == returnType
|| (method.getReturnType() == long.class && returnType == int.class));
}

private static Type[] toTypes(Class<?>... classes) {
Type[] result = new Type[classes.length];
for (int i = 0; i < classes.length; i++) {
Expand All @@ -270,25 +288,33 @@ private static Type[] toTypes(Class<?>... classes) {

private static class FieldDescriptor {
final String name;
final Class<?> type;
final Class<?> targetType;
final Class<?> sourceType;

FieldDescriptor(String name, Class<?> type) {
FieldDescriptor(String name, Class<?> targetType, Class<?> sourceType) {
this.name = name;
this.type = type;
this.targetType = targetType;
this.sourceType = sourceType;
}
}

private static class MethodDescriptor {
final String name;
final String targetName;
final Class<?> returnType;
final Class<?> targetReturnType;
final Class<?> sourceReturnType;
final Class<?>[] parameterTypes;

MethodDescriptor(
String name, String targetName, Class<?> returnType, Class<?>[] parameterTypes) {
String name,
String targetName,
Class<?> targetReturnType,
Class<?> sourceReturnType,
Class<?>[] parameterTypes) {
this.name = name;
this.targetName = targetName;
this.returnType = returnType;
this.targetReturnType = targetReturnType;
this.sourceReturnType = sourceReturnType;
this.parameterTypes = parameterTypes;
}
}
Expand Down Expand Up @@ -329,16 +355,18 @@ private byte[] getBytes() {
cv.visitField(
ACC_PUBLIC | ACC_STATIC | ACC_FINAL,
field.name,
Type.getDescriptor(field.type),
Type.getDescriptor(field.targetType),
null,
null);
fv.visitEnd();
}

for (MethodDescriptor method : methods) {
Type[] parameters = toTypes(method.parameterTypes);
Type returnType = Type.getType(method.returnType);
Type returnType = Type.getType(method.targetReturnType);
String descriptor = Type.getMethodDescriptor(returnType, parameters);
String sourceDescriptor =
Type.getMethodDescriptor(Type.getType(method.sourceReturnType), parameters);
MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, method.name, descriptor, null, null);
mv.visitCode();
mv.visitFieldInsn(
Expand All @@ -352,8 +380,13 @@ private byte[] getBytes() {
INVOKEVIRTUAL,
Type.getInternalName(internalUnsafeClass),
method.targetName,
descriptor,
sourceDescriptor,
false);
if (method.targetReturnType != method.sourceReturnType
&& method.targetReturnType == int.class
&& method.sourceReturnType == long.class) {
mv.visitInsn(L2I);
}
mv.visitInsn(returnType.getOpcode(IRETURN));
mv.visitMaxs(0, 0);
mv.visitEnd();
Expand Down Expand Up @@ -385,8 +418,13 @@ private byte[] getBytes() {
GETSTATIC,
Type.getInternalName(internalUnsafeClass),
field.name,
Type.getDescriptor(field.type));
mv.visitFieldInsn(PUTSTATIC, UNSAFE_NAME, field.name, Type.getDescriptor(field.type));
Type.getDescriptor(field.sourceType));
if (field.sourceType != field.targetType
&& field.targetType == int.class
&& field.sourceType == long.class) {
mv.visitInsn(L2I);
}
mv.visitFieldInsn(PUTSTATIC, UNSAFE_NAME, field.name, Type.getDescriptor(field.targetType));
}

mv.visitInsn(RETURN);
Expand Down
Loading