下面列出了java.lang.instrument.UnmodifiableClassException#java.lang.instrument.Instrumentation 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public static void premain(String agentArgument, Instrumentation instrumentation) {
instrumentation.addTransformer(new ClassFileTransformer() {
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
if (loader == null) {
/*
* Leave the class alone, if it is being loaded by the Bootstrap classloader,
* as we don't want to do anything with JDK libs. See Issue #22.
*/
return classfileBuffer;
} else {
try {
return new ScottClassTransformer().transform(classfileBuffer, ScottConfigurer.getConfiguration());
} catch (Exception e) {
System.err.println("Scott: test instrumentation failed for " + className + "!");
e.printStackTrace();
throw e;
}
}
}
});
}
public static void retransformClasses(Instrumentation inst, ClassFileTransformer transformer,
Set<Class<?>> classes) {
try {
inst.addTransformer(transformer, true);
for (Class<?> clazz : classes) {
try {
inst.retransformClasses(clazz);
} catch (Throwable e) {
String errorMsg = "retransformClasses class error, name: " + clazz.getName();
if (ClassUtils.isLambdaClass(clazz) && e instanceof VerifyError) {
errorMsg += ", Please ignore lambda class VerifyError: https://github.com/alibaba/arthas/issues/675";
}
logger.error(errorMsg, e);
}
}
} finally {
inst.removeTransformer(transformer);
}
}
@Test
@JavaVersionRule.Enforce(value = 8, j9 = false)
@AgentAttachmentRule.Enforce
@IntegrationRule.Enforce
public void testNonCapturingLambda() throws Exception {
assertThat(ByteBuddyAgent.install(), instanceOf(Instrumentation.class));
ClassLoader classLoader = lambdaSamples();
ClassFileTransformer classFileTransformer = new AgentBuilder.Default()
.with(poolStrategy)
.ignore(none())
.with(AgentBuilder.LambdaInstrumentationStrategy.ENABLED)
.type(isSubTypeOf(Callable.class)).transform(new SingleMethodReplacer("call"))
.installOn(ByteBuddyAgent.getInstrumentation());
try {
Class<?> sampleFactory = classLoader.loadClass(LAMBDA_SAMPLE_FACTORY);
@SuppressWarnings("unchecked")
Callable<String> instance = (Callable<String>) sampleFactory.getDeclaredMethod("nonCapturing").invoke(sampleFactory.getDeclaredConstructor().newInstance());
assertThat(instance.call(), is(BAR));
} finally {
assertThat(ByteBuddyAgent.getInstrumentation().removeTransformer(classFileTransformer), is(true));
AgentBuilder.LambdaInstrumentationStrategy.release(classFileTransformer, ByteBuddyAgent.getInstrumentation());
}
}
public static void agentmain(String agentArgs, Instrumentation inst)
throws ClassNotFoundException, UnmodifiableClassException,
InterruptedException {
final ColaTransformer transformer = new ColaTransformer(convert(agentArgs));
if(!isLock(transformer)){
return;
}
try {
inst.addTransformer(transformer, true);
Set<Class<?>> oriClassSet = searchClass(inst, transformer.getArgs().getClassName(), 1000);
final Class<?>[] classArray = new Class<?>[oriClassSet.size()];
System.arraycopy(oriClassSet.toArray(), 0, classArray, 0, oriClassSet.size());
inst.retransformClasses(classArray);
}finally {
inst.removeTransformer(transformer);
}
System.out.println("agentmain DONE");
}
public static void main(String args[]) throws IOException {
JarFile bootclasses = new JarFile("BootSupport.jar");
JarFile agentclasses = new JarFile("AgentSupport.jar");
Instrumentation ins = Agent.getInstrumentation();
// Test 1: Add BootSupport.jar to boot class path and check that
// BootSupport is loaded by the bootstrap class loader
ins.appendToBootstrapClassLoaderSearch(bootclasses);
checkLoadedByLoader("BootSupport", null);
// Test 2: Add AgentSupport.jar to the system class path and check that
// AgentSupport is loaded by the system class loader.
try {
ins.appendToSystemClassLoaderSearch(agentclasses);
checkLoadedByLoader("AgentSupport", ClassLoader.getSystemClassLoader());
} catch (UnsupportedOperationException x) {
System.out.println("System class loader does not support adding to class path");
}
// throw exception if a test failed
if (failures > 0) {
throw new RuntimeException(failures + " test(s) failed.");
}
}
public static void agentmain(String agentArgs, Instrumentation ins) {
if (!ins.isRedefineClassesSupported()) {
JOptionPane.showMessageDialog(null, "Class redefinition is disabled, cannot attach!");
return;
}
agentInstrumentation = ins;
workingDir = new File(agentArgs);
initialize();
if (!lafInit) {
LookUtils.setLAF();
lafInit = true;
}
JByteMod.file = new RuntimeJarArchive(ins);
JByteMod frame = new JByteMod(true);
frame.setTitleSuffix("Agent");
instance = frame;
frame.setVisible(true);
}
public static void agentmain(String agentArgs, Instrumentation inst) {
synchronized(lockObject) {
if(instrumentation == null) {
instrumentation = inst;
}
}
if(instrumentation!=null){
instrumentation.addTransformer(new ClassFileTransformer() {
@Override
public byte[] transform(ClassLoader loader, String classPath, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
// String className = classPath.replaceAll(File.separator, ".");
// if(!TReflect.isSystemType(className)) {
// return getClassBytes(className);
// } else {
return classfileBuffer;
// }
}
});
}
}
@Test
@JavaVersionRule.Enforce(value = 8, j9 = false)
@AgentAttachmentRule.Enforce
@IntegrationRule.Enforce
public void testInstanceReturningLambda() throws Exception {
assertThat(ByteBuddyAgent.install(), instanceOf(Instrumentation.class));
ClassLoader classLoader = lambdaSamples();
ClassFileTransformer classFileTransformer = new AgentBuilder.Default()
.with(poolStrategy)
.ignore(none())
.with(AgentBuilder.LambdaInstrumentationStrategy.ENABLED)
.type(isSubTypeOf(Callable.class)).transform(new SingleMethodReplacer("call"))
.installOn(ByteBuddyAgent.getInstrumentation());
try {
Class<?> sampleFactory = classLoader.loadClass(LAMBDA_SAMPLE_FACTORY);
Callable<?> instance = (Callable<?>) sampleFactory.getDeclaredMethod("instanceReturning").invoke(sampleFactory.getDeclaredConstructor().newInstance());
assertThat(instance.call(), notNullValue(Object.class));
} finally {
assertThat(ByteBuddyAgent.getInstrumentation().removeTransformer(classFileTransformer), is(true));
AgentBuilder.LambdaInstrumentationStrategy.release(classFileTransformer, ByteBuddyAgent.getInstrumentation());
}
}
private static void transformClass(String className, Instrumentation instrumentation) {
Class<?> targetCls = null;
ClassLoader targetClassLoader = null;
// see if we can get the class using forName
try {
targetCls = Class.forName(className);
targetClassLoader = targetCls.getClassLoader();
transform(targetCls, targetClassLoader, instrumentation);
return;
} catch (Exception ex) {
LOGGER.error("Class [{}] not found with Class.forName");
}
// otherwise iterate all loaded classes and find what we want
for(Class<?> clazz: instrumentation.getAllLoadedClasses()) {
if(clazz.getName().equals(className)) {
targetCls = clazz;
targetClassLoader = targetCls.getClassLoader();
transform(targetCls, targetClassLoader, instrumentation);
return;
}
}
throw new RuntimeException("Failed to find class [" + className + "]");
}
public static void premain(String agentArgs, Instrumentation inst) {
System.out.println("Hello from ManifestTestAgent!");
System.out.println("isNativeMethodPrefixSupported()=" +
inst.isNativeMethodPrefixSupported());
System.out.println("isRedefineClassesSupported()=" +
inst.isRedefineClassesSupported());
System.out.println("isRetransformClassesSupported()=" +
inst.isRetransformClassesSupported());
}
public static void premain(String agentArgs, Instrumentation inst) {
System.out.println("Hello from " +
"RedefineSubclassWithTwoInterfacesAgent!");
System.out.println("isRedefineClassesSupported()=" +
inst.isRedefineClassesSupported());
instrumentation = inst;
}
public static void premain(String options, Instrumentation ins) throws Exception {
String bootclasspath = System.getProperty("sun.boot.class.path");
System.out.println("bootclasspath: " + bootclasspath);
Class c = Class.forName("AgentSupport");
ClassLoader cl = c.getClassLoader();
if (cl != null) {
System.err.println("AgentSupport loaded by: " + cl);
throw new RuntimeException("AgentSupport class not loaded by boot class loader");
} else {
System.out.println("AgentSupport loaded by boot class loader");
}
}
private static synchronized void agent(
final AgentBuilder.RedefinitionStrategy redefinitionStrategy, final Instrumentation instrumentation)
{
if (null != logTransformer)
{
throw new IllegalStateException("agent already instrumented");
}
EventConfiguration.init();
if (DRIVER_EVENT_CODES.isEmpty() && ARCHIVE_EVENT_CODES.isEmpty() && CLUSTER_EVENT_CODES.isEmpty())
{
return;
}
EventLogAgent.instrumentation = instrumentation;
readerAgentRunner = new AgentRunner(
new SleepingMillisIdleStrategy(SLEEP_PERIOD_MS), Throwable::printStackTrace, null, newReaderAgent());
AgentBuilder agentBuilder = new AgentBuilder.Default(new ByteBuddy()
.with(TypeValidation.DISABLED))
.disableClassFormatChanges()
.with(new AgentBuilderListener())
.with(redefinitionStrategy);
agentBuilder = addDriverInstrumentation(agentBuilder);
agentBuilder = addArchiveInstrumentation(agentBuilder);
agentBuilder = addClusterInstrumentation(agentBuilder);
logTransformer = agentBuilder.installOn(instrumentation);
thread = new Thread(readerAgentRunner);
thread.setName("event-log-reader");
thread.setDaemon(true);
thread.start();
}
DefaultModuleEventWatcher(final Instrumentation inst,
final CoreLoadedClassDataSource classDataSource,
final CoreModule coreModule,
final boolean isEnableUnsafe,
final String namespace) {
this.inst = inst;
this.classDataSource = classDataSource;
this.coreModule = coreModule;
this.isEnableUnsafe = isEnableUnsafe;
this.namespace = namespace;
}
@Override
public void setup(Instrumentation instrumentation, AsyncEventProcessor eventProcessor) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
// JVM/GC metrics/events
executorService.submit(() -> JVMStatisticsTracer.setup(
(timestamp, event) -> eventProcessor.offer(timestamp, StandaloneHeader.getInstance().getHeader(), event)));
// Byte code instrumentation
executorService.submit(() -> FileSystemTracer.setup(instrumentation,
(timestamp, event) -> eventProcessor.offer(timestamp, StandaloneHeader.getInstance().getHeader(), event)));
// Set SPARK Listener
executorService.submit(() -> {
SparkListenerTracer.setup(StandaloneHeader.getInstance().getHeader(),
(timestamp, header, event) -> eventProcessor.offer(timestamp, header, event));
});
// Set FLINK Listener
executorService.submit(() -> {
FlinkReporterTracer.setup(StandaloneHeader.getInstance().getHeader(),
(timestamp, header, event) -> eventProcessor.offer(timestamp, header, event));
});
executorService.shutdown();
// We wait 2 sec executor to instrument classes
// If all classes are still not instrumented after that time we let the JVM continue startup
// in order to not block the container for too long on agent initialization
// Currently we are seeing avg duration of 160 s on MapRed and 6500 s on SPARK
// so we consider 3s as a reasonable duration
// Downside: we can have some classes not instrumenting loaded by the JVM so missing
// some metrics on a container
try {
executorService.awaitTermination(2000, TimeUnit.MILLISECONDS);
} catch (InterruptedException ignored) {
}
}
public DefaultAgentOption(final Instrumentation instrumentation, String agentId, String applicationName, final boolean isContainer, final ProfilerConfig profilerConfig, final List<String> pluginJars, final List<String> bootstrapJarPaths) {
this.instrumentation = Assert.requireNonNull(instrumentation, "instrumentation");
this.agentId = Assert.requireNonNull(agentId, "agentId");
this.applicationName = Assert.requireNonNull(applicationName, "applicationName");
this.isContainer = isContainer;
this.profilerConfig = Assert.requireNonNull(profilerConfig, "profilerConfig");
this.pluginJars = Assert.requireNonNull(pluginJars, "pluginJars");
if (bootstrapJarPaths == null) {
this.bootstrapJarPaths = Collections.emptyList();
} else {
this.bootstrapJarPaths = bootstrapJarPaths;
}
}
public static void premain(String options, Instrumentation ins) throws Exception {
String bootclasspath = System.getProperty("sun.boot.class.path");
System.out.println("bootclasspath: " + bootclasspath);
Class c = Class.forName("AgentSupport");
ClassLoader cl = c.getClassLoader();
if (cl != null) {
System.err.println("AgentSupport loaded by: " + cl);
throw new RuntimeException("AgentSupport class not loaded by boot class loader");
} else {
System.out.println("AgentSupport loaded by boot class loader");
}
}
public static void premain(String agentArgs, Instrumentation inst) {
System.out.println("Hello from RedefineMethodInBacktraceAgent!");
System.out.println("isRedefineClassesSupported()=" +
inst.isRedefineClassesSupported());
instrumentation = inst;
}
private Java9() {
try {
getModuleMethod = Class.class.getMethod("getModule");
// getModule() always returns non-null
glowrootModule = checkNotNull(getModuleMethod.invoke(Java9.class));
moduleClass = Class.forName("java.lang.Module");
redefineModuleMethod = Instrumentation.class.getMethod("redefineModule",
moduleClass, Set.class, Map.class, Map.class, Set.class, Map.class);
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
/**
* Premain of Garmadon agent
* <p>
* It initializes the socket appender, the AsyncEventProcessor
* (which is the thread serializing and pushing events to the appender),
* the ContainerHeader gathering information about the running container,
* attaches the instrumentation code and starts the thread reading JVM JMX events.
* </p>
*
* @param arguments agent option
* @param instrumentation agent instrumentation
*/
public static void premain(String arguments, Instrumentation instrumentation) {
try {
if (System.getProperty("garmadon.disable") == null) {
LOGGER.info("Starting Garmadon Agent Version {}", RELEASE);
String discovery = System.getProperty("garmadon.discovery", "local");
Connection connection = null;
switch (discovery) {
case "local":
connection = new FixedConnection("127.0.0.1", DEFAULT_FORWARDER_PORT);
break;
case "consul":
String consulServiceName = System.getProperty("garmadon.consul.service");
connection = new ConsulConnection(consulServiceName);
break;
default:
throw new UnsupportedOperationException("discovery " + discovery + " is not supported yet");
}
SocketAppender appender = new SocketAppender(connection);
// Init SocketAppender and EventProcessor
AsyncEventProcessor eventProcessor = new AsyncEventProcessor(appender);
//load user provided modules
loadModules(arguments, instrumentation, eventProcessor);
LOGGER.debug("Garmadon Agent initialized");
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void setContext(
ClassLoader apiCL,
ClassLoader containerCL,
List<? extends ClassLoader> moduleCLs,
Instrumentation instrumentation
) {
RuntimeModule.setStageLibraryClassLoaders(moduleCLs);
}
public static void setContext(ClassLoader api, ClassLoader container,
List<? extends ClassLoader> libs, Instrumentation instrumentation) {
Assert.assertNotNull(api);
Assert.assertNotNull(container);
Assert.assertEquals(3, libs.size());
boolean found = false;
for (URL url : ((SDCClassLoader) libs.get(0)).getURLs()) {
found = url.toExternalForm().endsWith("/libs-common-lib/x.jar");
if (found) {
break;
}
}
Assert.assertTrue(found);
setClassLoaders = true;
}
public static void premain(String agentArgs, Instrumentation inst) {
System.out.println("Hello from " +
"RedefineSubclassWithTwoInterfacesAgent!");
System.out.println("isRedefineClassesSupported()=" +
inst.isRedefineClassesSupported());
instrumentation = inst;
}
@Override
protected Strategy validate(Instrumentation instrumentation) {
if (!instrumentation.isRedefineClassesSupported()) {
throw new IllegalArgumentException("Does not support redefinition: " + instrumentation);
}
return this;
}
public static Set<Class<?>> searchClass(Instrumentation inst, String searchName, int limit) {
if (StringUtils.isBlank(searchName)) {
return Collections.emptySet();
}
final Set<Class<?>> matches = new HashSet<>();
for (Class<?> clazz : inst.getAllLoadedClasses()) {
if (searchName.equals(clazz.getName())) {
matches.add(clazz);
}
if (matches.size() >= limit) {
break;
}
}
return matches;
}
/**
* Start the JVM agent
*/
public static void premain(final String args, final Instrumentation instrumentation) {
// parse agent arguments
AgentConfig config = AgentConfig.parse(args);
// open reporter if required
Reporter reporter = new LogReporter(config);
reporter.start();
// register profilers for scheduling
Set<Profiler> profilers = new HashSet<>();
if (config.isProfilerEnabled(ProcFSProfiler.class.getSimpleName())) {
profilers.add(new ProcFSProfiler(config, reporter));
}
if (config.isProfilerEnabled(JVMProfiler.class.getSimpleName())) {
profilers.add(new JVMProfiler(config, reporter));
}
if (config.isProfilerEnabled(StackTraceProfiler.class.getSimpleName())) {
profilers.add(new StackTraceProfiler(config, reporter));
}
// start the profilers. They will be able to profile with their start() methods
startProfilers(profilers);
// add shutdown hook to correctly stop profilers and report last values on exit
registerShutdownHook(profilers, reporter);
}
/**
* Scans the instrumentation class path for modules and installs them on the JVM.
*/
public static void start(final String arguments, final Instrumentation instrumentation, boolean isRuntimeAttach) {
// This ensures that we will not load Kanela more than once on the same JVM.
if(Kanela.instrumentation == null) {
// We keep the reference in case we will need to reload the agent.
Kanela.instrumentation = instrumentation;
runWithTimeSpent(() -> {
InstrumentationClassPath.build().use(instrumentationClassLoader -> {
PreInitializeClasses.preInitializeClasses(instrumentationClassLoader);
BootstrapInjector.injectJar(instrumentation, "bootstrap");
val configuration = KanelaConfiguration.from(instrumentationClassLoader);
Logger.configureLogger(configuration);
if (isRuntimeAttach) configuration.runtimeAttach();
KanelaBanner.show(configuration);
installedTransformers = InstrumentationLoader.load(instrumentation, instrumentationClassLoader, configuration);
Reinstrumenter.attach(instrumentation, configuration, installedTransformers);
OldGarbageCollectorListener.attach(configuration.getOldGarbageCollectorConfig());
SystemThroughputCircuitBreaker.attach(configuration.getCircuitBreakerConfig());
updateLoadedSystemProperty();
});
});
}
}
public static void premain(String agentArgs, Instrumentation inst) throws Exception {
Module jlinkModule = ModuleLayer.boot().findModule( "jdk.jlink" ).get();
Module addIndexModule = ModuleLayer.boot().findModule( "org.hibernate.demos.jlink" ).get();
Map<String, Set<Module>> extraExports = new HashMap<>();
extraExports.put( "jdk.tools.jlink.plugin", Collections.singleton( addIndexModule ) );
// alter jdk.jlink to export its API to the module with our indexing plug-in
inst.redefineModule( jlinkModule,
Collections.emptySet(),
extraExports,
Collections.emptyMap(),
Collections.emptySet(),
Collections.emptyMap()
);
Class<?> pluginClass = jlinkModule.getClassLoader().loadClass( "jdk.tools.jlink.plugin.Plugin" );
Class<?> addIndexPluginClass = addIndexModule.getClassLoader().loadClass( "org.hibernate.demos.jlink.plugins.AddIndexPlugin" );
Map<Class<?>, List<Class<?>>> extraProvides = new HashMap<>();
extraProvides.put( pluginClass, Collections.singletonList( addIndexPluginClass ) );
// alter the module with the indexing plug-in so it provides the plug-in as a service
inst.redefineModule( addIndexModule,
Collections.emptySet(),
Collections.emptyMap(),
Collections.emptyMap(),
Collections.emptySet(),
extraProvides
);
}
EmbeddedAgentModule(@Nullable File pluginsDir, List<File> confDirs, boolean configReadOnly,
File logDir, File tmpDir, @Nullable Instrumentation instrumentation,
@Nullable PreCheckClassFileTransformer preCheckClassFileTransformer,
@Nullable File glowrootJarFile, String glowrootVersion, boolean offlineViewer)
throws Exception {
ticker = Ticker.systemTicker();
clock = Clock.systemClock();
// need to perform jrebel workaround prior to loading any jackson classes
JRebelWorkaround.perform();
pluginCache = PluginCache.create(pluginsDir, false);
if (offlineViewer) {
agentModule = null;
offlineViewerAgentModule =
new OfflineViewerAgentModule(pluginsDir, confDirs, configReadOnly);
} else {
// agent module needs to be started as early as possible, so that weaving will be
// applied to as many classes as possible
// in particular, it needs to be started before SimpleRepoModule which uses shaded H2,
// which loads java.sql.DriverManager, which loads 3rd party jdbc drivers found via
// services/java.sql.Driver, and those drivers need to be woven
ConfigService configService =
ConfigService.create(confDirs, configReadOnly, pluginCache.pluginDescriptors());
agentModule = new AgentModule(clock, null, pluginCache, configService, instrumentation,
glowrootJarFile, tmpDir, preCheckClassFileTransformer);
offlineViewerAgentModule = null;
}
this.confDirs = confDirs;
this.logDir = logDir;
this.version = glowrootVersion;
}
public static void premain(String options, Instrumentation ins) throws Exception {
Class<?> c = Class.forName("AgentSupport");
ClassLoader cl = c.getClassLoader();
if (cl != null) {
System.err.println("AgentSupport loaded by: " + cl);
throw new RuntimeException("AgentSupport class not loaded by boot class loader");
} else {
System.out.println("AgentSupport loaded by boot class loader");
}
}