Jmeter动态加载测试类
2016-06-29 15:14
399 查看
继上篇文章《Jmeter+H2Database动态部署JAR包到代理端》实现了测试业务jar包的动态部署后,再不重启代理端Jmeter的情况下,jar的变化内容仍无法自动加载到Jmeter内存,所以还是不能实现一次启动,动态更新的目的。
因为,Jmeter在启动的时候会自动加载lib目录下的jar包,如果不重启,目录下更新的jar包也不能加载到内存。所以,要实现类的动态加载,必须在Jmeter测试类中实现业务类的重载。
即在Jmeter测试类中的setupTest()方法中要自定义代码实现业务类的加载。
此处以一个简单例子说明实现过程:
public
class TransDemo {
public String action(){
Stringstr =
"action1st.";
System.out.println(str);
return
str;
}
public
voidinit() {
System.out.println("testingstart....");
}
public
voidend() {
System.out.println("testingover!!!!");
}
}
将其导出为perftest-trans.jar,将这个包放到jmeter/lib目录以外的地方。如:c:/perftest-trans.jar (不能放在Jmeter/lib目录下)。
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
public
classTransDemoActions extends AbstractJavaSamplerClient{
SampleResultresult=
null;
public Class<?>trans =
null;
Arguments params=
null;
Method methodInit=
null;
Method methodAction=
null;
Method methodEnd=
null;
MyClassLoader classLoader=
null;
Object newTrans=
null;
/**
* 自定义类加载方法
* @param jarpath
* @param classpath
*/
public
void loadClass(String[] jarpath,Stringclasspath){
URL[] urls= new URL[] {};
classLoader =
new MyClassLoader(urls,null);
try {
for(String jar:jarpath){
classLoader.addJar(new File(jar.trim()).toURI().toURL());
System.out.println("load jar file : "+jar.trim());
}
trans =
classLoader.loadClass(classpath);
System.out.println("load class file : "+classpath);
methodInit =
trans.getDeclaredMethod("init");
methodAction =
trans.getDeclaredMethod("action");
methodEnd =
trans.getDeclaredMethod("end");
boolean accessible =
methodInit.isAccessible();
if(accessible ==false){
methodInit.setAccessible(true);
}
newTrans =
trans.newInstance();
} catch (Exceptione) {
e.printStackTrace();
}
}
/**
* 自定义jmeter外部参数
*/
public Arguments getDefaultParameters() {
Arguments params=
new Arguments();
params.addArgument("TRANS_JARPATH","c:/perftest-trans.jar");
params.addArgument("TRANS_CLASSPATH","perftest.jmeter.trans.TransDemo");
returnparams;
}
public
void setupTest(JavaSamplerContext arg0) {
try {
loadClass(arg0.getParameter("TRANS_JARPATH").split(","),arg0.getParameter("TRANS_CLASSPATH"));
//通过反射调用TestDemo的init()方法,下同
methodInit.invoke(newTrans);
}catch(IllegalAccessException e) {
e.printStackTrace();
}catch(IllegalArgumentException e) {
e.printStackTrace();
}catch(InvocationTargetException e) {
e.printStackTrace();
}
}
@Override
public SampleResult runTest(JavaSamplerContextarg0) {
try {
methodAction.invoke(newTrans);
}catch(IllegalAccessException e) {
e.printStackTrace();
}catch(IllegalArgumentException e) {
e.printStackTrace();
}catch(InvocationTargetException e) {
e.printStackTrace();
}
returnresult;
}
public
void teardownTest(JavaSamplerContext
arg0) {
try {
methodEnd.invoke(newTrans);
}catch(IllegalAccessException e) {
e.printStackTrace();
}catch(IllegalArgumentException e) {
b21d
e.printStackTrace();
}catch(InvocationTargetException e) {
e.printStackTrace();
}catch (Exceptione) {
e.printStackTrace();
}
}
/**
* 自定义内部类实现动态加载class
* @author
*
*/
static
class MyClassLoader extends URLClassLoader {
public MyClassLoader(URL[]urls) {
super(urls);
}
public MyClassLoader(URL[]urls, ClassLoader
parent) {
super(urls,parent);
}
public
void addJar(URL url) {
this.addURL(url);
}
}
}
将其导出为perftest-actons.jar,并将它放入<jmeterPath>/lib/ext下,在Jmeter启动时可以自动发现这个测试类: perftest.jemter.action.TestDemoActons 。
//此处修改打印输出字符
String str =
"actionsecond.";
System.out.println(str);
return
str;
}
重新将TransDemo.class打包为perftest-trans.jar,并覆盖前面的c:/perftest-trans.jar
小结:
所以要实现类的动态加载,必须在Jmeter测试类AbstractJavaSamplerClient(java请求)中使用URLClassLoader实现被测业务类的重新加载,并使用invoke()方法调用业务方法。
自此,通过《Jmeter+H2Database动态部署JAR包到代理端》及本篇可以为分布式测试中的众多代理端实现被测业务(jar)包的实时更新及业务测试类(class)的热加载。
再也不用重启100+台Jmeter代理端而烦恼了。
因为,Jmeter在启动的时候会自动加载lib目录下的jar包,如果不重启,目录下更新的jar包也不能加载到内存。所以,要实现类的动态加载,必须在Jmeter测试类中实现业务类的重载。
即在Jmeter测试类中的setupTest()方法中要自定义代码实现业务类的加载。
此处以一个简单例子说明实现过程:
编写要被测业务类:TransDemo.java
package perftest.jmeter.trans;public
class TransDemo {
public String action(){
Stringstr =
"action1st.";
System.out.println(str);
return
str;
}
public
voidinit() {
System.out.println("testingstart....");
}
public
voidend() {
System.out.println("testingover!!!!");
}
}
将其导出为perftest-trans.jar,将这个包放到jmeter/lib目录以外的地方。如:c:/perftest-trans.jar (不能放在Jmeter/lib目录下)。
编写Jmeter测试类:TransDemoActions.java
package perftest.jemter.action;import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
public
classTransDemoActions extends AbstractJavaSamplerClient{
SampleResultresult=
null;
public Class<?>trans =
null;
Arguments params=
null;
Method methodInit=
null;
Method methodAction=
null;
Method methodEnd=
null;
MyClassLoader classLoader=
null;
Object newTrans=
null;
/**
* 自定义类加载方法
* @param jarpath
* @param classpath
*/
public
void loadClass(String[] jarpath,Stringclasspath){
URL[] urls= new URL[] {};
classLoader =
new MyClassLoader(urls,null);
try {
for(String jar:jarpath){
classLoader.addJar(new File(jar.trim()).toURI().toURL());
System.out.println("load jar file : "+jar.trim());
}
trans =
classLoader.loadClass(classpath);
System.out.println("load class file : "+classpath);
methodInit =
trans.getDeclaredMethod("init");
methodAction =
trans.getDeclaredMethod("action");
methodEnd =
trans.getDeclaredMethod("end");
boolean accessible =
methodInit.isAccessible();
if(accessible ==false){
methodInit.setAccessible(true);
}
newTrans =
trans.newInstance();
} catch (Exceptione) {
e.printStackTrace();
}
}
/**
* 自定义jmeter外部参数
*/
public Arguments getDefaultParameters() {
Arguments params=
new Arguments();
params.addArgument("TRANS_JARPATH","c:/perftest-trans.jar");
params.addArgument("TRANS_CLASSPATH","perftest.jmeter.trans.TransDemo");
returnparams;
}
public
void setupTest(JavaSamplerContext arg0) {
try {
loadClass(arg0.getParameter("TRANS_JARPATH").split(","),arg0.getParameter("TRANS_CLASSPATH"));
//通过反射调用TestDemo的init()方法,下同
methodInit.invoke(newTrans);
}catch(IllegalAccessException e) {
e.printStackTrace();
}catch(IllegalArgumentException e) {
e.printStackTrace();
}catch(InvocationTargetException e) {
e.printStackTrace();
}
}
@Override
public SampleResult runTest(JavaSamplerContextarg0) {
try {
methodAction.invoke(newTrans);
}catch(IllegalAccessException e) {
e.printStackTrace();
}catch(IllegalArgumentException e) {
e.printStackTrace();
}catch(InvocationTargetException e) {
e.printStackTrace();
}
returnresult;
}
public
void teardownTest(JavaSamplerContext
arg0) {
try {
methodEnd.invoke(newTrans);
}catch(IllegalAccessException e) {
e.printStackTrace();
}catch(IllegalArgumentException e) {
b21d
e.printStackTrace();
}catch(InvocationTargetException e) {
e.printStackTrace();
}catch (Exceptione) {
e.printStackTrace();
}
}
/**
* 自定义内部类实现动态加载class
* @author
*
*/
static
class MyClassLoader extends URLClassLoader {
public MyClassLoader(URL[]urls) {
super(urls);
}
public MyClassLoader(URL[]urls, ClassLoader
parent) {
super(urls,parent);
}
public
void addJar(URL url) {
this.addURL(url);
}
}
}
将其导出为perftest-actons.jar,并将它放入<jmeterPath>/lib/ext下,在Jmeter启动时可以自动发现这个测试类: perftest.jemter.action.TestDemoActons 。
启动Jmeter,建立测试计划和添加线程组及“Java请求”
线程组大小设置为1,线程循环次数设置2:即一个虚拟用户进行2次迭代。运行测试
运行测试可以看到System.out.println的输出结果:修改被测业务类TransDemo的action()方法
public String action(){//此处修改打印输出字符
String str =
"actionsecond.";
System.out.println(str);
return
str;
}
重新将TransDemo.class打包为perftest-trans.jar,并覆盖前面的c:/perftest-trans.jar
重新运行测试
在不关闭和重启Jmeter的情况下,再次执行测试,可以看到输出信息已经改变为“action seconde.”:小结:
所以要实现类的动态加载,必须在Jmeter测试类AbstractJavaSamplerClient(java请求)中使用URLClassLoader实现被测业务类的重新加载,并使用invoke()方法调用业务方法。
自此,通过《Jmeter+H2Database动态部署JAR包到代理端》及本篇可以为分布式测试中的众多代理端实现被测业务(jar)包的实时更新及业务测试类(class)的热加载。
再也不用重启100+台Jmeter代理端而烦恼了。
相关文章推荐
- 用myeclipse打jar包,使其包含依赖jar包的指向
- 服务器性能监控命令
- Redis学习文章
- centos7 修改中文字符集
- 控制edittext
- 支持向量机 smo算法
- node.js express(二)
- Div+CSS网页布局中CSS无效的十个常见原因
- javascript的setTimeout()用法总结,js的setTimeout()方法
- MySQL数据类型与存储范围
- 迈思德物联网网关问答集锦
- Light OJ 1014 Ifter Party [因子分解]【数论】
- jQuery学习日记(一):jQuery 对象与 DOM 对象
- Apache 安装和虚拟主机的配置
- word ladder
- 深入理解傅立叶变换(详细)
- Kmp算法理解
- Java实现redis管道
- JavaScript事件
- iOS 时间戳 时间串 比较和转换