Closed wu-sheng closed 8 years ago
I try to use lastest version 1.4.6 to fixed this issue. I get another exception, when the application uses log4j.(remove agent, everything is fine. )
objc[75496]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/bin/java and /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/libinstrument.dylib. One of the two will be used. Which one is undefined.
Exception in thread "main" java.lang.NoClassDefFoundError: sun/reflect/GeneratedMethodAccessor4
at sun.reflect.GeneratedMethodAccessor4.<clinit>(Unknown Source)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at java.lang.Class.newInstance(Class.java:438)
at sun.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:403)
at sun.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:394)
at java.security.AccessController.doPrivileged(Native Method)
at sun.reflect.MethodAccessorGenerator.generate(MethodAccessorGenerator.java:393)
at sun.reflect.MethodAccessorGenerator.generateMethod(MethodAccessorGenerator.java:75)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:53)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.apache.logging.log4j.status.StatusLogger$BoundedQueue.<clinit>(StatusLogger.java)
at org.apache.logging.log4j.status.StatusLogger.<init>(StatusLogger.java:75)
at org.apache.logging.log4j.status.StatusLogger.classInitializer$tFvp9PAT(StatusLogger.java:64)
at org.apache.logging.log4j.status.StatusLogger.<clinit>(StatusLogger.java)
at org.apache.logging.log4j.LogManager.classInitializer$2uwbj97q(LogManager.java:60)
at org.apache.logging.log4j.LogManager.<clinit>(LogManager.java)
at com.ai.cloud.skywalking.sample.util.DubboStart.classInitializer$oOb0838P(DubboStart.java:9)
at com.ai.cloud.skywalking.sample.util.DubboStart.<clinit>(DubboStart.java)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:260)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:122)
Caused by: java.lang.ClassNotFoundException: sun.reflect.GeneratedMethodAccessor4
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 25 more
Since versions 1.4.*, Byte Buddy excludes the bootstrap class loader from instrumentation by default. It seems like you are trying to instrument too many classes including classes within the JVM.
I recommend you to change your strategy for instrumenting. Instead of doing "no-op" transformations like:
if (pluginDefine == null) {
return builder;
}
you should exclude classes when setting type(exclusivePackageClass())
such that those classes are never triggered. Also, you should not catch exceptions; Byte Buddy catches them and aborts the transformation what is much more performant. You can still log exceptions by registering an AgentBuilder.Listener
.
I change my code like this.
new AgentBuilder.Default().type(enhanceClassMatcher(pluginDefineCategory)).transform(new AgentBuilder.Transformer() {
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader) {
AbstractClassEnhancePluginDefine pluginDefine = pluginDefineCategory.findPluginDefine(typeDescription.getTypeName());
return pluginDefine.define(typeDescription.getTypeName(), builder);
}
}).with(new AgentBuilder.Listener() {
@Override
public void onTransformation(TypeDescription typeDescription, ClassLoader classLoader, JavaModule module, DynamicType dynamicType) {
}
@Override
public void onIgnored(TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) {
logger.info("ignore to enhance class " + typeDescription.getTypeName());
}
@Override
public void onError(String typeName, ClassLoader classLoader, JavaModule module, Throwable throwable) {
logger.error("Failed to enhance class " + typeName, throwable);
}
@Override
public void onComplete(String typeName, ClassLoader classLoader, JavaModule module) {
logger.info("enhance class " + typeName + " complete.");
}
}).installOn(instrumentation);
And I will test my project today, hope it will work as my wish.
In 1.4.17, the sun.reflect.
namespace is now excluded if not specified otherwise. After updating, you should be able to run your agent without any preconfiguration; you should still adapt your mapping. I am closing this issue and but I am happy to reopen it if your problem persists and you can provide more information.
First of all, thanks for your project. We build a very popular java APM(Application Performance Management) project named SkyWalking(https://github.com/wu-sheng/sky-walking) based on ByteBuddy.
Today, we meet an issues as follow:
Now, we tried many ways. The only way to avoid this issue, is add a matcher and exclude package 'sun.*', like this:
We hope this issue could be fixed soon enough. Thank you. @wu-sheng @ascrutae