Running BTrace custom script with GlassFish V3

GlassFish V3でBTraceのカスタムスクリプトを使用しようとすると、以下のようなNoClassDefFoundErrorが出て、正しく実行できないことがあります。

致命的: GRIZZLY0038: HTTP Processing error.
java.lang.NoClassDefFoundError: MyTracer
	at com.sun.enterprise.web.pwc.connector.coyote.PwcCoyoteRequest.$btrace$MyTracer$m(PwcCoyoteRequest.java)
	at com.sun.enterprise.web.pwc.connector.coyote.PwcCoyoteRequest.(PwcCoyoteRequest.java)
	at com.sun.enterprise.web.connector.coyote.PECoyoteConnector.createRequest(PECoyoteConnector.java:283)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:205)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
	at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
	at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
	at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
	at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
	at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
	at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
	at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
	at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
	at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
	at java.lang.Thread.run(Thread.java:680)
Caused by: java.lang.ClassNotFoundException: MyTracer not found by org.glassfish.web.glue [288]
	at org.apache.felix.framework.ModuleImpl.findClassOrResourceByDelegation(ModuleImpl.java:787)
	at org.apache.felix.framework.ModuleImpl.access$400(ModuleImpl.java:71)
	at org.apache.felix.framework.ModuleImpl$ModuleClassLoader.loadClass(ModuleImpl.java:1768)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
	... 19 more

どうやらこの原因は、OSGiフレームワークのfelixとの兼ね合いによる問題のようです。felixの設定ファイルは、3.1.1まではglassfish/osgi/felix/conf/config.propertiesにあったのですが、3.1.2からはEquinoxと統合され、glassfish/conf/osgi.propertiesにあります。最新のGlassFish 3.1.2.2でosgi.propertiesの内容を確認すると、以下のようにBTrace関連のライブラリはデフォルトでfelixの管理外でクラスが読まれるようになっていますが、BTraceスクリプトも同じようにfelix管理外となるようにしなければならないようです。

glassfish/conf/osgi.properties:

org.osgi.framework.bootdelegation=${eclipselink.bootdelegation}, \
                                  com.sun.btrace, com.sun.btrace.*, \
                                  org.netbeans.lib.profiler, org.netbeans.lib.profiler.*

BTraceスクリプトのパッケージ名をbootdelegationに追加しても良いのですが、環境設定に手をいれると後々困ることもあるので、簡単に対応するには、BTraceスクリプトのパッケージ名の方をbootdelegationに列挙されているパッケージ名のいずれかになるように変更してしまってもよいでしょう。例えば、BTraceスクリプトのパッケージ名をcom.sun.btrace.scriptsと宣言してしまいます。

MyTrace.java:

package com.sun.btrace.scripts;
         :
@BTrace public class MyTrace {
         :

後は修正したスクリプトをbtracecでコンパイルすれば、実行中のGlassFishサーバにスクリプトをアタッチできます。

$ btracec MyTracer.java

$ jps
80075 Jps
79806 glassfish.jar

$ btrace 79806 com/sun/btrace/scripts/MyTracer.class

ただし、GlassFish本体のクラス群をトレースしたいときは、btraceコマンドでは手遅れだったりするため、domain.xmlのJVMオプションで起動時から組み込まれるようにする必要がある場合もあります。

glassfish/domains/domain1/config/domain.xml:

<jvm-options>-javaagent:/Users/foo/java/tool/btrace-1.2.1/build/btrace-agent.jar=script=/Users/foo/java/btscripts/com/sun/btrace/scripts/MyTracer.class</jvm-options>

投稿されたコメント:

コメント
  • HTML文法 不許可
About

Takashi Nishigaya
Principal Consultant
Technology Solution Consulting
Oracle Consulting Services

Search

Categories
Archives
« 4月 2014
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
今日