最近,我使用BTrace来检查glassfish VM中抛出的异常。我使用脚本:
@BTrace public class OnThrow {
// store current exception in a thread local
// variable (@TLS annotation). Note that we can't
// store it in a global variable!
@TLS static Throwable currentException;
// introduce probe into every constructor of java.lang.Throwable
// class and store "this" in the thread local variable.
@OnMethod(
clazz="java.lang.Throwable",
method="<init>"
)
public static void onthrow(@Self Throwable self) {
currentException = self;
}
@OnMethod(
clazz="java.lang.Throwable",
method="<init>"
)
public static void onthrow1(@Self Throwable self, String s) {
currentException = self;
}
@OnMethod(
clazz="java.lang.Throwable",
method="<init>"
)
public static void onthrow1(@Self Throwable self, String s, Throwable cause) {
currentException = self;
}
@OnMethod(
clazz="+java.lang.Throwable",
method="<init>"
)
public static void onthrow2(@Self Throwable self, Throwable cause) {
currentException = self;
}
// when any constructor of java.lang.Throwable returns
// print the currentException's stack trace.
@OnMethod(
clazz="java.lang.Throwable",
method="<init>",
location=@Location(Kind.RETURN)
)
public static void onthrowreturn() {
if (currentException != null) {
Threads.jstack(currentException);
println("=====================");
currentException = null;
}
}
}当我用BTrace v.1.3.10.2 (20180129)使用'-v‘标志附加到GF4.1.1 (build 1)时,GF会生成以下stracktrace,并且我没有看到BTrace抛出控制台输出:
btrace DEBUG: parsed command line arguments]]
btrace DEBUG: Bootstrap ClassPath: .]]
btrace DEBUG: ignoring boot classpath element '.' - only jar files allowed]]
btrace DEBUG: System ClassPath: /usr/lib/jvm/java-8-oracle/jre/../lib/tools.jar]]
btrace DEBUG: debugMode is true]]
btrace DEBUG: probe descriptor path is .]]
btrace DEBUG: stdout is false]]
btrace DEBUG: starting agent thread]]
btrace DEBUG: Agent init took: 10482105ns]]
btrace DEBUG: starting server at 2020]]
btrace DEBUG: waiting for clients]]
btrace DEBUG: client accepted Socket[addr=/127.0.0.1,port=43496,localport=2020]]]
btrace DEBUG: got instrument command]]
btrace DEBUG: loading BTrace class]]
btrace DEBUG: verifying BTrace class ...]]
btrace DEBUG: BTrace class com.sun.btrace.samples.OnThrow verified]]
btrace DEBUG: preprocessing BTrace class com.sun.btrace.samples.OnThrow ...]]
btrace DEBUG: ... preprocessed]]
btrace DEBUG: loaded 'com.sun.btrace.samples.OnThrow' successfully]]
btrace DEBUG: creating BTraceRuntime instance for com.sun.btrace.samples.OnThrow]]
btrace DEBUG: created BTraceRuntime instance for com.sun.btrace.samples.OnThrow]]
btrace DEBUG: sending Okay command]]
btrace DEBUG: client com.sun.btrace.samples.OnThrow: got com.sun.btrace.comm.OkayCommand@26cab401]]
btrace DEBUG: about to defineClass com/sun/btrace/samples/OnThrow]]
btrace DEBUG: defineClass succeeded for com.sun.btrace.samples.OnThrow]]
btrace DEBUG: skipping transform for BTrace class com/sun/btrace/agent/RemoteClient$1]]
btrace DEBUG: starting client command handler thread]]
btrace DEBUG: skipping transform for BTrace class com/sun/btrace/agent/Main$3]]
btrace DEBUG: new Client created com.sun.btrace.agent.RemoteClient@44c6c5b2]]
btrace DEBUG: retransforming loaded classes]]
btrace DEBUG: filtering loaded classes]]
btrace DEBUG: skipping transform for BTrace class com/sun/btrace/runtime/ClassCache$Singleton]]
btrace DEBUG: skipping transform for BTrace class com/sun/btrace/runtime/ClassInfo$ClassName]]
btrace DEBUG: skipping transform for BTrace class com/sun/btrace/runtime/ClassInfo$JavaClassName]]
btrace DEBUG: skipping transform for BTrace class com/sun/btrace/runtime/ClassInfo$BaseClassName]]
btrace DEBUG: skipping transform for BTrace class com/sun/btrace/runtime/ClassInfo$InternalClassName]]
btrace DEBUG: skipping transform for BTrace class com/sun/btrace/runtime/BTraceClassReader$BailoutExceptio]]
btrace DEBUG: java.util.concurrent.ExecutionException: java.lang.IllegalStateException: This web container has not yet been started]]
java.util.concurrent.ExecutionException: java.lang.IllegalStateException: This web container has not yet been started
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at com.sun.btrace.agent.Main.startServer(Main.java:674)
at com.sun.btrace.agent.Main.access$000(Main.java:60)
at com.sun.btrace.agent.Main$2.run(Main.java:125)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalStateException: This web container has not yet been started
at org.glassfish.web.loader.WebappClassLoader.findResourceInternal(WebappClassLoader.java:2827)
at org.glassfish.web.loader.WebappClassLoader.findResource(WebappClassLoader.java:1320)
at org.glassfish.web.loader.WebappClassLoader.getResourceAsStream(WebappClassLoader.java:1528)
at com.sun.btrace.runtime.ClassInfo.loadExternalClass(ClassInfo.java:262)
at com.sun.btrace.runtime.ClassInfo.<init>(ClassInfo.java:215)
at com.sun.btrace.runtime.ClassCache.get(ClassCache.java:70)
at com.sun.btrace.runtime.ClassCache.get(ClassCache.java:62)
at com.sun.btrace.runtime.ClassCache.get(ClassCache.java:51)
at com.sun.btrace.agent.Client.retransformLoaded(Client.java:451)
at com.sun.btrace.agent.Main$3.run(Main.java:693)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
btrace DEBUG: waiting for clients]]
btrace DEBUG: skipping transform for BTrace class sun/security/ssl/ServerNameExtension]]
btrace DEBUG: skipping transform for BTrace class sun/security/ssl/UnknownExtension]]
btrace DEBUG: skipping transform for BTrace class sun/security/provider/PolicyFile$6]]我困惑的是玻璃鱼例外。当附加btrace时,已经有一个应用程序部署在GF上,该应用程序为HTTP请求提供服务。
如果部署了一个使用web容器的webapp (CDI/REST/JPA),为什么会引发‘容器尚未启动--?
发布于 2018-01-31 15:24:18
我终于发现了在这个快递上又看到了什么:
org.glassfish.web.loader.WebappClassLoader.getResourceAsStream(WebappClassLoader.java:1528)
at com.sun.btrace.runtime.ClassInfo.loadExternalClass(ClassInfo.java:262)
at com.sun.btrace.runtime.ClassInfo.<init>(ClassInfo.java:215)
at com.sun.btrace.runtime.ClassCache.get(ClassCache.java:70)
at com.sun.btrace.runtime.ClassCache.get(ClassCache.java:62)
at com.sun.btrace.runtime.ClassCache.get(ClassCache.java:51)
at com.sun.btrace.agent.Client.retransformLoaded(Client.java:451)我在BTrace代码中分析的方法之一是:
com.sun.btrace.agent.Client.retransformLoaded看上去像是:
void retransformLoaded() throws UnmodifiableClassException {
if (runtime != null) {
if (probe.isTransforming() && settings.isRetransformStartup()) {
ArrayList<Class> list = new ArrayList<>();
debugPrint("retransforming loaded classes");
debugPrint("filtering loaded classes");
ClassCache cc = ClassCache.getInstance();
for (Class c : inst.getAllLoadedClasses()) {
if (c != null) {
451 cc.get(c);
}
if (inst.isModifiableClass(c) && isCandidate(c))
debugPrint("candidate " + c + " added");
list.add(c);
}
...other stuffcc.get(c)抛出此异常。它使用来自ClassCache的方法:
ClassInfo get(ClassLoader cl, ClassName className) {
Map<ClassName, ClassInfo> infos = getInfos(cl);
ClassInfo ci = infos.get(className);
if (ci == null) {
70 ci = new ClassInfo(this, cl, className);
infos.put(className, ci);
}
return ci;
}和ClassInfo的构造函数
ClassInfo(ClassCache cache, ClassLoader cl, ClassName cName) {
this.cache = cache;
cLoaderId = (cl != null ? cl.toString() : "<null>");
classId = cName;
215 loadExternalClass(cl, cName);
}最后,构造函数的loadExternalClass方法:
private void loadExternalClass(final ClassLoader cl, final ClassName className) {
String resourcePath = className.getResourcePath();
262 InputStream typeIs = cl == null ? SYS_CL.getResourceAsStream(resourcePath) : cl.getResourceAsStream(resourcePath);
if (typeIs != null) {
try {
BTraceClassReader cr = new BTraceClassReader(cl, typeIs);
...使用ClassLoader.getSystemClassLoader().获取SYS_CL这实际上是WebappClassLoader,它是异常中的主要参与者。我注意到CDI/JPA类(在捕获和打印抛出EX的类之后)抛出了异常:
btrace DEBUG: Class class some.package.EntityManagerWrapper -> EX thrown: This web container has not yet been started]]
btrace DEBUG: Class class some.package.AsyncAuditFacade -> EX thrown: This web container has not yet been started]]
btrace DEBUG: Class class some.package.OperationAuditFacade -> EX thrown: This web container has not yet been started]]
btrace DEBUG: Class class some.package.FacadeConfigFactory -> EX thrown: This web container has not yet been started有人能告诉我为什么只有这些类在测试它们时抛出前类吗?
我的BTrace脚本是从示例中获取的,如下所示:
@TLS static Throwable currentException;
@OnMethod(
clazz="+java.lang.Throwable",
method="<init>"
)
public static void onthrow2(@Self Throwable self, Throwable cause) {
currentException = self;
}
@OnMethod(
clazz="java.lang.Throwable",
method="<init>",
location=@Location(Kind.RETURN)
)
public static void onthrowreturn() {
if (currentException != null) {
Threads.jstack(currentException);
println("=====================");
currentException = null;
}
}要解决这个问题,并从com.sun.btrace.agent.Client.retransformLoaded获得输出,我只需将第451行包装在BTrace中,就可以使用this块,并且一切都正常工作,并生成输出。
我想知道为什么会抛出这个异常?SYS_CL是一个默认的类加载器( CL ),我在Glassfish中看到,每个webapp都有自己新创建的CL。这些CDI/JPA类都使用WebappClassLoader加载( ClassInfo.class中的cl变量不是null - 262,我确实检查了cl='WebappClassLoader (delegate=true)'),那么它们为什么不愿意被检测呢?
寓意是你不能用BTrace和你想要的每一个脚本,因为环境框架会干扰探测。
https://stackoverflow.com/questions/48540484
复制相似问题