JMeter源码解析之NewDriver.java(一)
NewDriver.java主要作用
JMeter程序入口:JMeter的主类-设置初始类路径和加载程序。
文件路径
路径地址:…\apache-jmeter-5.1\src\core\org\apache\jmeter\NewDriver.java
文章重点关于static内容中的代码解析
详细的解释请关注代码中的解释
static {final List<URL> jars = new LinkedList<>();/*** 通过System.getProperty的方法获取系统自带的各种参数,其中有一种参数为"java.class.path",这里获取的是执行JMeter机器的这台PC* */final String initiaClasspath = System.getProperty(JAVA_CLASS_PATH);/*** 从获取的initiaClasspath变量路径中找到JMeter路径,通过文件分隔符“;”进行分隔* */// Find JMeter home dir from the initial classpathString tmpDir;/*** 获得所有Java相关的内容* 例如:C:\Program Files\Java\jdk1.8.0_101\jre\lib\charsets.jar* C:\Program Files\Java\jdk1.8.0_101\jre\lib\deploy.jar* Tokens计算值,猜测是其他操作系统,如Mac OS,因为用window 10,获取的Token值数据是25,远远大于条件中给出的1或者2* 所以我们运行的代码分支是在else后面的内容* */StringTokenizer tok = new StringTokenizer(initiaClasspath, File.pathSeparator);if (tok.countTokens() == 1|| (tok.countTokens() == 2 // Java on Mac OS can add a second entry to the initial classpath&& OS_NAME_LC.startsWith("mac os x")// $NON-NLS-1$)) {File jar = new File(tok.nextToken());try {tmpDir = jar.getCanonicalFile().getParentFile().getParent();} catch (IOException e) {tmpDir = null;}} else {// e.g. started from IDE with full classpath/*** 获取JMeter路径,如果获取不到,返回的参数是为空,把null替换成“空值”,如果获取有数据,则说明设置过JMeter路径,如果没有即判断tmpDir.length() == 0* 去获取对应的路径,首先通过System.getProperty("user.dir")的方法获取了程序启动的工程所在文件夹,比如当前工程为:D:\1.JAVA\JmeterDemo,则打印的就是这个路径* 当通过getParent()或者getAbsolutePath(),可以知道获取的路径分别是D:\1.JAVA和D:\1.JAVA\JmeterDemo,然后将值给了tmpDir供下面判断* */tmpDir = System.getProperty("jmeter.home","");// Allow override $NON-NLS-1$ $NON-NLS-2$if (tmpDir.length() == 0) {File userDir = new File(System.getProperty("user.dir"));// $NON-NLS-1$//获取相对路径地址
// tmpDir = userDir.getAbsoluteFile().getParent();//获取绝对路径地址tmpDir = userDir.getAbsoluteFile().getAbsolutePath();}}JMETER_INSTALLATION_DIRECTORY=tmpDir;/** Does the system support UNC paths? If so, may need to fix them up* 判断操作系统是否window* later*/boolean usesUNC = OS_NAME_LC.startsWith("windows");// $NON-NLS-1$// Add standard jar locations to initial classpath/*** 加载JMeter对应目录下的JMeter安装目录下的jar包,当前支持三种路径的加载* 第一种:..\lib* 第二种:..\lib\ext* 第三种:..\lib\junit* */StringBuilder classpath = new StringBuilder();File[] libDirs = new File[] { new File(JMETER_INSTALLATION_DIRECTORY + File.separator + "lib"),// $NON-NLS-1$ $NON-NLS-2$new File(JMETER_INSTALLATION_DIRECTORY + File.separator + "lib" + File.separator + "ext"),// $NON-NLS-1$ $NON-NLS-2$new File(JMETER_INSTALLATION_DIRECTORY + File.separator + "lib" + File.separator + "junit")};// $NON-NLS-1$ $NON-NLS-2$for (File libDir : libDirs) {//获取所有对应目录下的jar包,首先要判断对应的目录和Jar包是否存在,当对应目录下没有任何JAR包,则抛异常,类似这种异常:java.lang.Throwable: Could not access D:\1.JAVA\JmeterDemo\lib\ext1// at com.test.demo.GetProperties.main(GetProperties.java:22)File[] libJars = libDir.listFiles((dir, name) -> name.endsWith(".jar"));if (libJars == null) {new Throwable("Could not access " + libDir).printStackTrace(); // NOSONAR No logging herecontinue;}Arrays.sort(libJars); // Bug 50708 Ensure predictable order of jarsfor (File libJar : libJars) {try {String s = libJar.getPath();// Fix path to allow the use of UNC URLsif (usesUNC) {if (s.startsWith("\\\\") && !s.startsWith("\\\\\\")) {// $NON-NLS-1$ $NON-NLS-2$s = "\\\\" + s;// $NON-NLS-1$} else if (s.startsWith("//") && !s.startsWith("///")) {// $NON-NLS-1$ $NON-NLS-2$s = "//" + s;// $NON-NLS-1$}} // usesUNC/*** 添加Jar包* new File(s)是通过给定的路径创建一个File对象。* toURI()是File类的方法,将文件路径转换为URI(统一资源标识符)对象。* toURL()是URI类的方法,将URI对象转换为URL(统一资源定位符)对象。* 生成一个jar包路径* */jars.add(new File(s).toURI().toURL());// See Java bug 4496398classpath.append(CLASSPATH_SEPARATOR);classpath.append(s);} catch (MalformedURLException e) { // NOSONAREXCEPTIONS_IN_INIT.add(new Exception("Error adding jar:"+libJar.getAbsolutePath(), e));}}// ClassFinder needs the classpath//将JMeter中获取的Jar进行设置,重新设置环境变量System.setProperty(JAVA_CLASS_PATH, initiaClasspath + classpath.toString());loader = AccessController.doPrivileged((PrivilegedAction<DynamicClassLoader>) () ->new DynamicClassLoader(jars.toArray(new URL[jars.size()])));
}