Jacoco是一个Java代码覆盖率统计工具,见:http://www.eclemma.org/jacoco/
JaCoCo is a free code coverage library for Java, which has been created by the EclEmma team based on the lessons learned from using and integration existing libraries for many years.
今天帮助同事将Jacoco部署到测试环境的JBoss中,以便进行代码覆盖率统计的实验,然后加上了Jacoco作为javaagent后,JBoss就启动不了了,看到的jboss.log中错误信息如下:
1 2 3 4 5 6 7 |
Error opening zip file or JAR manifest missing : /root/Jacoco/jacocoagent.jar Error occurred during initialization of VM agent library failed to init: instrument #Java选项和ClassPath相关信息: JAVA_OPTS: -Dprogram.name=run-test.sh -server -Xms1280m -Xmx1280m -javaagent:/root/Jacoco/jacocoagent.jar=output=tcpserver -Djava.net.preferIPv4Stack=true -Xrunjdwp:transport=dt_socket,address=8887,server=y,suspend=n -Djava.library.path=/usr/local/jboss/bin/native CLASSPATH: /usr/local/jboss/bin/run.jar:/usr/local/jdk/lib/tools.jar |
一开始,找资料试图解决这个问题,很久都没有解决问题了,网上大都遇到的情况是“-javaagent”这你不应该加上“-D”,但我这里一开始就没有这个问题的。
后来,晚上忽然想想是否可以挪动jacocoagent.jar到jboss的路径$JBOSS_HOME/bin之下,后来试了一下,居然正常了,启动JBoss启动后Java进程的命令如下:
1 |
/usr/local/jdk/bin/java -Dprogram.name=run-test.sh -server -Xms1280m -Xmx1280m -javaagent:/usr/local/jboss/bin/jacocoagent.jar=output=tcpserver -Djava.net.preferIPv4Stack=true -Xrunjdwp:transport=dt_socket,address=8887,server=y,suspend=n -Djava.library.path=/usr/local/jboss/bin/native -Djava.endorsed.dirs=/usr/local/jboss/lib/endorsed -classpath /usr/local/jboss/bin/run.jar:/usr/local/jdk/lib/tools.jar org.jboss.Main -c service -b 0.0.0.0 |
没有认认真真阅读jboss的启动脚本和没有研究jboos的加载Jar的一些基本知识,所以暂时无法解释是何原理。(待了解后补充)
jacocoagent.jar的路径为 /usr/local/jboss/lib/jacocoagent.jar 也是可以的。
后来早上到公司一下就看出问题所在了,我简直弱爆了,原来只是文件读取权限的问题,jboss启动的java进程时用nobody这个用户启动的,它对/root/下的东西没有读取权限的。
一些简单信息如下:
1 2 3 4 5 6 7 |
[root@host_77-201 jboss]# ls -l / .... dr-xr-x---. 8 root root 4096 Sep 10 09:27 root drwxr-xr-x. 14 root root 4096 Mar 23 2012 usr ..... [root@host_77-201 jboss]# ps -ef | grep java nobody 30846 30837 21 09:19 ? 00:01:56 /usr/local/jdk/bin/java -D...... |
哎,简单的文件读取权限问题,它的报错信息不够直观啊~~
后记:
当使用acoco的client端去远程连接server端时,一直报“connection refused”的错误,后来发现时jacocoagent启动时默认限制了仅有本地地址127.0.0.1才能连接这个server端的端口;需要在JVM启动的avaagent (jacocoagent)时制定address参数。具体现象和修改如下:
1 2 3 4 5 6 7 8 9 10 11 |
# 使用Java选项为:-javaagent:/usr/local/jboss/lib/jacocoagent.jar=output=tcpserver,port=6301 # 得到 netstat命令总agent试用的6301端口信息如下 # 进绑定在127.0.0.1的6301端口,不能接收本机之外的连接 [root@host_77-201 jboss]# netstat -tnl | grep 6301 tcp 0 0 127.0.0.1:6301 0.0.0.0:* LISTEN # 在启动jacocoagent时,需要添加 address=*,以便接受来自远程主机的连接 # 修改偶的Java选项为:-javaagent:/usr/local/jboss/lib/jacocoagent.jar=output=tcpserver,port=6300,address=* # netsat 命令的输出如下,这样就正常了,远程的client端可以正常连接到server(agent)端了 [root@host_77-201 jboss]# netstat -tnl | grep 6300 tcp 0 0 0.0.0.0:6300 0.0.0.0:* LISTEN |