下面列出了java.lang.instrument.UnmodifiableClassException#java.lang.instrument.ClassFileTransformer 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Adds the specified class file transformer to this class loader. The
* transformer will then be able to modify the bytecode of any classes
* loaded by this class loader after the invocation of this method.
*
* @param transformer The transformer to add to the class loader
*/
@Override
public void addTransformer(ClassFileTransformer transformer) {
if (transformer == null) {
throw new IllegalArgumentException(sm.getString(
"webappClassLoader.addTransformer.illegalArgument", getContextName()));
}
if (this.transformers.contains(transformer)) {
// if the same instance of this transformer was already added, bail out
log.warn(sm.getString("webappClassLoader.addTransformer.duplicate",
transformer, getContextName()));
return;
}
this.transformers.add(transformer);
log.info(sm.getString("webappClassLoader.addTransformer", transformer, getContextName()));
}
public synchronized void
addTransformer(ClassFileTransformer transformer, boolean canRetransform) {
if (transformer == null) {
throw new NullPointerException("null passed as 'transformer' in addTransformer");
}
if (canRetransform) {
if (!isRetransformClassesSupported()) {
throw new UnsupportedOperationException(
"adding retransformable transformers is not supported in this environment");
}
if (mRetransfomableTransformerManager == null) {
mRetransfomableTransformerManager = new TransformerManager(true);
}
mRetransfomableTransformerManager.addTransformer(transformer);
if (mRetransfomableTransformerManager.getTransformerCount() == 1) {
setHasRetransformableTransformers(mNativeAgent, true);
}
} else {
mTransformerManager.addTransformer(transformer);
}
}
/**
* Create a new SimpleLoadTimeWeaver for the given class loader.
* @param classLoader the {@code ClassLoader} to delegate to for
* weaving (<i>must</i> support the required weaving methods).
* @throws IllegalStateException if the supplied {@code ClassLoader}
* does not support the required weaving methods
*/
public ReflectiveLoadTimeWeaver(@Nullable ClassLoader classLoader) {
Assert.notNull(classLoader, "ClassLoader must not be null");
this.classLoader = classLoader;
Method addTransformerMethod = ClassUtils.getMethodIfAvailable(
this.classLoader.getClass(), ADD_TRANSFORMER_METHOD_NAME, ClassFileTransformer.class);
if (addTransformerMethod == null) {
throw new IllegalStateException(
"ClassLoader [" + classLoader.getClass().getName() + "] does NOT provide an " +
"'addTransformer(ClassFileTransformer)' method.");
}
this.addTransformerMethod = addTransformerMethod;
Method getThrowawayClassLoaderMethod = ClassUtils.getMethodIfAvailable(
this.classLoader.getClass(), GET_THROWAWAY_CLASS_LOADER_METHOD_NAME);
// getThrowawayClassLoader method is optional
if (getThrowawayClassLoaderMethod == null) {
if (logger.isDebugEnabled()) {
logger.debug("The ClassLoader [" + classLoader.getClass().getName() + "] does NOT provide a " +
"'getThrowawayClassLoader()' method; SimpleThrowawayClassLoader will be used instead.");
}
}
this.getThrowawayClassLoaderMethod = getThrowawayClassLoaderMethod;
}
@Test
@AgentAttachmentRule.Enforce
public void InputFormatTracer_should_intercept_InputFormat_direct_implementor() throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
assertThat(ByteBuddyAgent.install(), instanceOf(Instrumentation.class));
//Install tracer
ClassFileTransformer classFileTransformer = new MapReduceTracer.InputFormatTracer().installOnByteBuddyAgent();
try {
//Call InputFormat
Class<?> type = classLoader.loadClass(MapReduceInputFormatTestClasses.OneLevelHierarchy.class.getName());
invokeRecordReader(type);
invokeListInputSplits(type);
//Verify mock interaction
verify(eventHandler, times(2)).accept(any(Long.class), argument.capture());
DataAccessEventProtos.PathEvent pathEvent = DataAccessEventProtos.PathEvent
.newBuilder()
.setPath(inputPath)
.setType(PathType.INPUT.name())
.build();
assertEquals(pathEvent, argument.getValue());
} finally {
ByteBuddyAgent.getInstrumentation().removeTransformer(classFileTransformer);
}
}
public synchronized void
addTransformer(ClassFileTransformer transformer, boolean canRetransform) {
if (transformer == null) {
throw new NullPointerException("null passed as 'transformer' in addTransformer");
}
if (canRetransform) {
if (!isRetransformClassesSupported()) {
throw new UnsupportedOperationException(
"adding retransformable transformers is not supported in this environment");
}
if (mRetransfomableTransformerManager == null) {
mRetransfomableTransformerManager = new TransformerManager(true);
}
mRetransfomableTransformerManager.addTransformer(transformer);
if (mRetransfomableTransformerManager.getTransformerCount() == 1) {
setHasRetransformableTransformers(mNativeAgent, true);
}
} else {
mTransformerManager.addTransformer(transformer);
}
}
public synchronized void
setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) {
if (!isNativeMethodPrefixSupported()) {
throw new UnsupportedOperationException(
"setNativeMethodPrefix is not supported in this environment");
}
if (transformer == null) {
throw new NullPointerException(
"null passed as 'transformer' in setNativeMethodPrefix");
}
TransformerManager mgr = findTransformerManager(transformer);
if (mgr == null) {
throw new IllegalArgumentException(
"transformer not registered in setNativeMethodPrefix");
}
mgr.setNativeMethodPrefix(transformer, prefix);
String[] prefixes = mgr.getNativeMethodPrefixes();
setNativeMethodPrefixes(mNativeAgent, prefixes, mgr.isRetransformable());
}
public synchronized void
addTransformer(ClassFileTransformer transformer, boolean canRetransform) {
if (transformer == null) {
throw new NullPointerException("null passed as 'transformer' in addTransformer");
}
if (canRetransform) {
if (!isRetransformClassesSupported()) {
throw new UnsupportedOperationException(
"adding retransformable transformers is not supported in this environment");
}
if (mRetransfomableTransformerManager == null) {
mRetransfomableTransformerManager = new TransformerManager(true);
}
mRetransfomableTransformerManager.addTransformer(transformer);
if (mRetransfomableTransformerManager.getTransformerCount() == 1) {
setHasRetransformableTransformers(mNativeAgent, true);
}
} else {
mTransformerManager.addTransformer(transformer);
}
}
public synchronized void
setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) {
if (!isNativeMethodPrefixSupported()) {
throw new UnsupportedOperationException(
"setNativeMethodPrefix is not supported in this environment");
}
if (transformer == null) {
throw new NullPointerException(
"null passed as 'transformer' in setNativeMethodPrefix");
}
TransformerManager mgr = findTransformerManager(transformer);
if (mgr == null) {
throw new IllegalArgumentException(
"transformer not registered in setNativeMethodPrefix");
}
mgr.setNativeMethodPrefix(transformer, prefix);
String[] prefixes = mgr.getNativeMethodPrefixes();
setNativeMethodPrefixes(mNativeAgent, prefixes, mgr.isRetransformable());
}
/**
* Adds the specified class file transformer to this class loader. The
* transformer will then be able to modify the bytecode of any classes
* loaded by this class loader after the invocation of this method.
*
* @param transformer The transformer to add to the class loader
*/
@Override
public void addTransformer(ClassFileTransformer transformer) {
if (transformer == null) {
throw new IllegalArgumentException(sm.getString(
"webappClassLoader.addTransformer.illegalArgument", getContextName()));
}
if (this.transformers.contains(transformer)) {
// if the same instance of this transformer was already added, bail out
log.warn(sm.getString("webappClassLoader.addTransformer.duplicate",
transformer, getContextName()));
return;
}
this.transformers.add(transformer);
log.info(sm.getString("webappClassLoader.addTransformer", transformer, getContextName()));
}
public synchronized void
setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) {
if (!isNativeMethodPrefixSupported()) {
throw new UnsupportedOperationException(
"setNativeMethodPrefix is not supported in this environment");
}
if (transformer == null) {
throw new NullPointerException(
"null passed as 'transformer' in setNativeMethodPrefix");
}
TransformerManager mgr = findTransformerManager(transformer);
if (mgr == null) {
throw new IllegalArgumentException(
"transformer not registered in setNativeMethodPrefix");
}
mgr.setNativeMethodPrefix(transformer, prefix);
String[] prefixes = mgr.getNativeMethodPrefixes();
setNativeMethodPrefixes(mNativeAgent, prefixes, mgr.isRetransformable());
}
public synchronized void
addTransformer(ClassFileTransformer transformer, boolean canRetransform) {
if (transformer == null) {
throw new NullPointerException("null passed as 'transformer' in addTransformer");
}
if (canRetransform) {
if (!isRetransformClassesSupported()) {
throw new UnsupportedOperationException(
"adding retransformable transformers is not supported in this environment");
}
if (mRetransfomableTransformerManager == null) {
mRetransfomableTransformerManager = new TransformerManager(true);
}
mRetransfomableTransformerManager.addTransformer(transformer);
if (mRetransfomableTransformerManager.getTransformerCount() == 1) {
setHasRetransformableTransformers(mNativeAgent, true);
}
} else {
mTransformerManager.addTransformer(transformer);
}
}
public synchronized void
addTransformer( ClassFileTransformer transformer) {
TransformerInfo[] oldList = mTransformerList;
TransformerInfo[] newList = new TransformerInfo[oldList.length + 1];
System.arraycopy( oldList,
0,
newList,
0,
oldList.length);
newList[oldList.length] = new TransformerInfo(transformer);
mTransformerList = newList;
}
@Override
public void addTransformer(ClassFileTransformer transformer) {
InvocationHandler adapter = new JBossMCTranslatorAdapter(transformer);
Object adapterInstance = Proxy.newProxyInstance(this.translatorClass.getClassLoader(),
new Class<?>[] {this.translatorClass}, adapter);
try {
this.addTranslator.invoke(this.target, adapterInstance);
}
catch (Throwable ex) {
throw new IllegalStateException("Could not add transformer on JBoss 6 ClassLoader " + this.classLoader, ex);
}
}
private boolean instrument(String source, ResolvedSourceLocation location, final int line) throws UnmodifiableClassException, ClassNotFoundException {
ClassFileTransformer transformer = new MonitorClassFileTransformer(classFileBuffer, source, location, line);
try {
Class<?> clazz = instrumentInfo.signatureToClass(location.getClassSignature());
inst.addTransformer(transformer, true);
inst.retransformClasses(clazz);
instrumentInfo.addTransformedClasses(clazz);
return true;
} finally {
inst.removeTransformer(transformer);
}
}
/**
* The agent class must implement a public static premain method similar in principle to the main application entry point.
* After the Java Virtual Machine (JVM) has initialized,
* each premain method will be called in the order the agents were specified,
* then the real application main method will be called.
**/
public static void premain(String agentArgs, Instrumentation inst) {
System.out.println("NS4Agent.premain() was called.");
/* Provides services that allow Java programming language agents to instrument programs running on the JVM.*/
_inst = inst;
/* ClassFileTransformer : An agent provides an implementation of this interface in order to transform class files.*/
ClassFileTransformer trans = new AgentTransformer();
System.out.println("Adding a NS4Agent instance to the JVM.");
/*Registers the supplied transformer.*/
_inst.addTransformer(trans);
}
/**
* Create a new instance of the {@link GlassFishLoadTimeWeaver} class using
* the supplied {@link ClassLoader}.
* @param classLoader the {@code ClassLoader} to delegate to for weaving
*/
public GlassFishLoadTimeWeaver(@Nullable ClassLoader classLoader) {
Assert.notNull(classLoader, "ClassLoader must not be null");
Class<?> instrumentableLoaderClass;
try {
instrumentableLoaderClass = classLoader.loadClass(INSTRUMENTABLE_LOADER_CLASS_NAME);
this.addTransformerMethod = instrumentableLoaderClass.getMethod("addTransformer", ClassFileTransformer.class);
this.copyMethod = instrumentableLoaderClass.getMethod("copy");
}
catch (Throwable ex) {
throw new IllegalStateException(
"Could not initialize GlassFishLoadTimeWeaver because GlassFish API classes are not available", ex);
}
ClassLoader clazzLoader = null;
// Detect transformation-aware ClassLoader by traversing the hierarchy
// (as in GlassFish, Spring can be loaded by the WebappClassLoader).
for (ClassLoader cl = classLoader; cl != null && clazzLoader == null; cl = cl.getParent()) {
if (instrumentableLoaderClass.isInstance(cl)) {
clazzLoader = cl;
}
}
if (clazzLoader == null) {
throw new IllegalArgumentException(classLoader + " and its parents are not suitable ClassLoaders: A [" +
instrumentableLoaderClass.getName() + "] implementation is required.");
}
this.classLoader = clazzLoader;
}
public synchronized void
addTransformer( ClassFileTransformer transformer) {
TransformerInfo[] oldList = mTransformerList;
TransformerInfo[] newList = new TransformerInfo[oldList.length + 1];
System.arraycopy( oldList,
0,
newList,
0,
oldList.length);
newList[oldList.length] = new TransformerInfo(transformer);
mTransformerList = newList;
}
/**
* Create a new {@link WebSphereClassPreDefinePlugin}.
* @param transformer the {@link ClassFileTransformer} to be adapted
* (must not be {@code null})
*/
public WebSphereClassPreDefinePlugin(ClassFileTransformer transformer) {
this.transformer = transformer;
ClassLoader classLoader = transformer.getClass().getClassLoader();
// First force the full class loading of the weaver by invoking transformation on a dummy class
try {
String dummyClass = Dummy.class.getName().replace('.', '/');
byte[] bytes = FileCopyUtils.copyToByteArray(classLoader.getResourceAsStream(dummyClass + ".class"));
transformer.transform(classLoader, dummyClass, null, null, bytes);
}
catch (Throwable ex) {
throw new IllegalArgumentException("Cannot load transformer", ex);
}
}
private byte[] applyTransformers(String name, byte[] bytes) {
String internalName = StringUtils.replace(name, ".", "/");
try {
for (ClassFileTransformer transformer : this.classFileTransformers) {
byte[] transformed = transformer.transform(this, internalName, null, null, bytes);
bytes = (transformed != null ? transformed : bytes);
}
return bytes;
}
catch (IllegalClassFormatException ex) {
throw new IllegalStateException(ex);
}
}
@Test
public void testCtorWithClassLoaderThatDoesNotExposeAGetThrowawayClassLoaderMethodIsOkay() {
JustAddTransformerClassLoader classLoader = new JustAddTransformerClassLoader();
ReflectiveLoadTimeWeaver weaver = new ReflectiveLoadTimeWeaver(classLoader);
weaver.addTransformer(new ClassFileTransformer() {
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) {
return "CAFEDEAD".getBytes();
}
});
assertEquals(1, classLoader.getNumTimesGetThrowawayClassLoaderCalled());
}
private TransformerManager
findTransformerManager(ClassFileTransformer transformer) {
if (mTransformerManager.includesTransformer(transformer)) {
return mTransformerManager;
}
if (mRetransfomableTransformerManager != null &&
mRetransfomableTransformerManager.includesTransformer(transformer)) {
return mRetransfomableTransformerManager;
}
return null;
}
@Override
public void addTransformer(ClassFileTransformer transformer) {
Assert.notNull(transformer, "Transformer must not be null");
FilteringClassFileTransformer actualTransformer =
new FilteringClassFileTransformer(transformer, this.classLoader);
synchronized (this.transformers) {
if (this.instrumentation == null) {
throw new IllegalStateException(
"Must start with Java agent to use InstrumentationLoadTimeWeaver. See Spring documentation.");
}
this.instrumentation.addTransformer(actualTransformer);
this.transformers.add(actualTransformer);
}
}
synchronized boolean
includesTransformer(ClassFileTransformer transformer) {
for (TransformerInfo info : mTransformerList) {
if ( info.transformer() == transformer ) {
return true;
}
}
return false;
}
public synchronized boolean
removeTransformer(ClassFileTransformer transformer) {
if (transformer == null) {
throw new NullPointerException("null passed as 'transformer' in removeTransformer");
}
TransformerManager mgr = findTransformerManager(transformer);
if (mgr != null) {
mgr.removeTransformer(transformer);
if (mgr.isRetransformable() && mgr.getTransformerCount() == 0) {
setHasRetransformableTransformers(mNativeAgent, false);
}
return true;
}
return false;
}
@Test
@AgentAttachmentRule.Enforce
public void ContainerResourceMonitoringModule_should_attach_to_recordCpuUsage() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchFieldException {
assertThat(ByteBuddyAgent.install(), instanceOf(Instrumentation.class));
final Header[] header = new Header[1];
final Object[] event = new Object[1];
TriConsumer<Long, Header, Object> cons = (t, h, o) -> {
header[0] = h;
event[0] = o;
};
ReflectionHelper.setField(null, classLoader.loadClass(ContainerResourceMonitoringTracer.class.getName()), "eventHandler", cons);
ClassFileTransformer classFileTransformer = new ContainerResourceMonitoringTracer.VcoreUsageTracer().installOnByteBuddyAgent();
try {
Class<?> clazz = classLoader.loadClass(ContainerMetrics.class.getName());
Constructor<?> constructor = clazz.getDeclaredConstructor(MetricsSystem.class, ContainerId.class, long.class, long.class);
constructor.setAccessible(true);
Object inFormat = constructor.newInstance(mock(MetricsSystem.class), ContainerId.fromString("container_e16940_1541383784275_24407_01_000023"), 5L, 5L);
Method m = clazz.getDeclaredMethod("recordCpuUsage", int.class, int.class);
m.invoke(inFormat, 10, 10000);
assertNotNull(header[0]);
assertNotNull(event[0]);
} finally {
ByteBuddyAgent.getInstrumentation().removeTransformer(classFileTransformer);
}
}
public synchronized void
addTransformer( ClassFileTransformer transformer) {
TransformerInfo[] oldList = mTransformerList;
TransformerInfo[] newList = new TransformerInfo[oldList.length + 1];
System.arraycopy( oldList,
0,
newList,
0,
oldList.length);
newList[oldList.length] = new TransformerInfo(transformer);
mTransformerList = newList;
}
boolean
setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) {
TransformerInfo[] transformerList = getSnapshotTransformerList();
for ( int x = 0; x < transformerList.length; x++ ) {
TransformerInfo transformerInfo = transformerList[x];
ClassFileTransformer aTransformer = transformerInfo.transformer();
if ( aTransformer == transformer ) {
transformerInfo.setPrefix(prefix);
return true;
}
}
return false;
}
public synchronized boolean
removeTransformer(ClassFileTransformer transformer) {
if (transformer == null) {
throw new NullPointerException("null passed as 'transformer' in removeTransformer");
}
TransformerManager mgr = findTransformerManager(transformer);
if (mgr != null) {
mgr.removeTransformer(transformer);
if (mgr.isRetransformable() && mgr.getTransformerCount() == 0) {
setHasRetransformableTransformers(mNativeAgent, false);
}
return true;
}
return false;
}
public synchronized void
addTransformer( ClassFileTransformer transformer) {
TransformerInfo[] oldList = mTransformerList;
TransformerInfo[] newList = new TransformerInfo[oldList.length + 1];
System.arraycopy( oldList,
0,
newList,
0,
oldList.length);
newList[oldList.length] = new TransformerInfo(transformer);
mTransformerList = newList;
}
@Override
public Collection<ClassFileTransformer> getTransformers() {
if (Boolean.getBoolean("talend.component.beam.transformers.skip")) {
return emptySet();
}
final String classes = System.getProperty("talend.component.beam.transformers.io.enhanced");
return singleton(classes == null ? new BeamIOTransformer()
: new BeamIOTransformer(
Stream.of(classes.split(",")).map(String::trim).filter(it -> !it.isEmpty()).collect(toSet())));
}