Skip to content

Commit

Permalink
Rmi instrumentation on jdk17 (open-telemetry#4577)
Browse files Browse the repository at this point in the history
* Rmi instrumentation on jdk17

* address review comment, make muzzle happy

* Update instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/jpms/ExposeRmiModuleInstrumentation.java

Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>

* review comment

Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
  • Loading branch information
2 people authored and RashmiRam committed May 23, 2022
1 parent 911f6d0 commit ccc3b36
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.rmi.context.jpms;

import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;

import io.opentelemetry.instrumentation.api.InstrumentationVersion;
import io.opentelemetry.javaagent.bootstrap.InstrumentationHolder;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicBoolean;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.loading.ClassInjector;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.utility.JavaModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ExposeRmiModuleInstrumentation implements TypeInstrumentation {
private static final Logger logger =
LoggerFactory.getLogger(ExposeRmiModuleInstrumentation.class);

private final AtomicBoolean instrumented = new AtomicBoolean();

@Override
public ElementMatcher<TypeDescription> typeMatcher() {
ElementMatcher.Junction<TypeDescription> notInstrumented =
new ElementMatcher.Junction.AbstractBase<TypeDescription>() {

@Override
public boolean matches(TypeDescription target) {
return !instrumented.get();
}
};

return notInstrumented.and(nameStartsWith("sun.rmi"));
}

@Override
public ElementMatcher<ClassLoader> classLoaderOptimization() {
return new ElementMatcher.Junction.AbstractBase<ClassLoader>() {

@Override
public boolean matches(ClassLoader target) {
// runs only in bootstrap class loader
return JavaModule.isSupported() && target == null;
}
};
}

@Override
public void transform(TypeTransformer transformer) {
transformer.applyTransformer(
(builder, typeDescription, classLoader, module) -> {
if (module != null && module.isNamed()) {
// using InstrumentationVersion because it's in the unnamed module in the bootstrap
// loader, and that's where the rmi instrumentation helper classes will end up
JavaModule helperModule = JavaModule.ofType(InstrumentationVersion.class);
// expose sun.rmi.server package to unnamed module
ClassInjector.UsingInstrumentation.redefineModule(
InstrumentationHolder.getInstrumentation(),
module,
Collections.emptySet(),
Collections.singletonMap("sun.rmi.server", Collections.singleton(helperModule)),
Collections.emptyMap(),
Collections.emptySet(),
Collections.emptyMap());

instrumented.set(true);
logger.debug(
"Exposed package \"sun.rmi.server\" in module {} to unnamed module", module);
}
return builder;
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.rmi.context.jpms;

import static java.util.Collections.singletonList;

import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.instrumentation.rmi.context.server.ContextDispatcher;
import java.util.List;

/**
* RMI server instrumentation class {@link ContextDispatcher} implements an internal interface that
* is not exported by java module system. This is not allowed on jdk17. This instrumentation module
* exposes JDK internal classes for RMI server instrumentation.
*/
@AutoService(InstrumentationModule.class)
public class RmiJpmsInstrumentationModule extends InstrumentationModule {

public RmiJpmsInstrumentationModule() {
super("rmi", "rmi-jpms");
}

@Override
public List<TypeInstrumentation> typeInstrumentations() {
return singletonList(new ExposeRmiModuleInstrumentation());
}
}

0 comments on commit ccc3b36

Please sign in to comment.