Jmeter源码系列(1)-NewDriver类详解-Jmeter 的启动器
写在前面的话
Jmeter 全称(Apache JMeter)是一个开源的、功能强大的性能测试工具,用于对各种应用程序和协议进行功能、负载、压力和性能测试。它被广泛应用于软件开发和计划阶段,以确保应用程序在各种负载情况下的稳定性和可靠性。
本系列将从 Jmeter 代码层面陆续剖析其实现原理,包括但不限于 Jmeter 设计思路,Jmeter 核心对象/接口/方法。如有错误,敬请指正!
NewDriver
NewDriver 是 org.apache.jmeter 包下的一个类,如下是 NewDriver 源码中的类说明
从这个说明中,我们可以知道,这个类提供了 2 个主要功能:
- 初始化 classpath
- 初始化一个 loader, 这个 loader 其实就是一个动态类加载器
以下内容摘抄自 NewDriver 源码,在源码中会使用注释来说明关键代码的作用,最后也会做总结,让我们开始吧
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| public final class NewDriver {
private static final String CLASSPATH_SEPARATOR = File.pathSeparator; private static final String OS_NAME = System.getProperty("os.name"); private static final String OS_NAME_LC = OS_NAME.toLowerCase(java.util.Locale.ENGLISH); private static final String JAVA_CLASS_PATH = "java.class.path"; private static final String JMETER_LOGFILE_SYSTEM_PROPERTY = "jmeter.logfile"; private static final String HEADLESS_MODE_PROPERTY = "java.awt.headless";
private static final DynamicClassLoader loader; private static final String JMETER_INSTALLATION_DIRECTORY; private static final List<Exception> EXCEPTIONS_IN_INIT = new ArrayList<>();
static { final List<URL> jars = new ArrayList<>();
final String initiaClasspath = System.getProperty(JAVA_CLASS_PATH); String tmpDir;
StringTokenizer tok = new StringTokenizer(initiaClasspath, File.pathSeparator);
if (tok.countTokens() == 1|| (tok.countTokens() == 2 && OS_NAME_LC.startsWith("mac os x"))) { File jar = new File(tok.nextToken()); try { tmpDir = jar.getCanonicalFile().getParentFile().getParent(); } catch (IOException e) { tmpDir = null; } } else {
tmpDir = System.getProperty("jmeter.home", System.getenv("JMETER_HOME")); if (tmpDir == null || tmpDir.length() == 0) { File userDir = new File(System.getProperty("user.dir")); tmpDir = userDir.getAbsoluteFile().getParent(); } } if (tmpDir == null) { tmpDir = System.getenv("JMETER_HOME"); } JMETER_INSTALLATION_DIRECTORY = tmpDir; boolean usesUNC = OS_NAME_LC.startsWith("windows"); StringBuilder classpath = new StringBuilder();
File[] libDirs = new File[] { new File(JMETER_INSTALLATION_DIRECTORY + File.separator + "lib"), new File(JMETER_INSTALLATION_DIRECTORY + File.separator + "lib" + File.separator + "ext"), new File(JMETER_INSTALLATION_DIRECTORY + File.separator + "lib" + File.separator + "junit")}; for (File libDir : libDirs) { File[] libJars = libDir.listFiles((dir, name) -> name.endsWith(".jar")); if (libJars == null) { new Throwable("Could not access " + libDir).printStackTrace(); continue; }
Arrays.sort(libJars); for (File libJar : libJars) { try { String s = libJar.getPath(); if (usesUNC) { if (s.startsWith("\\\\") && !s.startsWith("\\\\\\")) { s = "\\\\" + s; } else if (s.startsWith("//") && !s.startsWith("///")) { s = "//" + s; } } jars.add(new File(s).toURI().toURL()); classpath.append(CLASSPATH_SEPARATOR); classpath.append(s); } catch (MalformedURLException e) { EXCEPTIONS_IN_INIT.add(new Exception("Error adding jar:"+libJar.getAbsolutePath(), e)); } } } System.setProperty(JAVA_CLASS_PATH, initiaClasspath + classpath.toString());
loader = AccessController.doPrivileged( (PrivilegedAction<DynamicClassLoader>) () -> new DynamicClassLoader(jars.toArray(new URL[jars.size()])) ); } }
|
从上面的代码中,我们可以看到,NewDriver 在实例化时,会执行一个静态代码块,主要作用就是加载 Jmeter 安装目录下的 jar 包。
Main方法介绍
下面介绍 NewDriver 的 main 方法,这个方法就是整个 Jmeter 启动的入口方法。
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 31 32 33 34 35 36 37 38 39 40 41
| public static void main(String[] args) {
if(!EXCEPTIONS_IN_INIT.isEmpty()) { System.err.println("Configuration error during init, see exceptions:"+exceptionsToString(EXCEPTIONS_IN_INIT)); } else {
Thread.currentThread().setContextClassLoader(loader);
setLoggingProperties(args); try {
if(System.getProperty(HEADLESS_MODE_PROPERTY) == null && shouldBeHeadless(args)) { System.setProperty(HEADLESS_MODE_PROPERTY, "true"); }
Class<?> initialClass = loader.loadClass("org.apache.jmeter.JMeter");
Object instance = initialClass.getDeclaredConstructor().newInstance();
Method startup = initialClass.getMethod("start", new Class[] { new String[0].getClass() }); startup.invoke(instance, new Object[] { args }); } catch(Throwable e){ e.printStackTrace(); System.err.println("JMeter home directory was detected as: "+JMETER_INSTALLATION_DIRECTORY); } } }
|
main 方法其实很简单直接,就是看下是不是要启动 GUI,然后就是通过反射调用 Jmeter 的 start 方法,来开始测试。
综上,NewDriver 其实就是一个启动器,正如其所在源码模块 launcher 一样,他的作用就是为 Jmeter 真正启动做好准备。
好了,NewDriver 就介绍完了,下一章将介绍 Jmeter 这个核心类,以及调用其 start(String[] args) 之后会发生什么…