mnaufaldillah

NewDriver Jmeter

Oct 23rd, 2021
482
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to you under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  * http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17.  
  18. package org.apache.jmeter;
  19.  
  20. // N.B. this must only use standard Java packages
  21. import java.io.File;
  22. import java.io.IOException;
  23. import java.io.PrintWriter;
  24. import java.io.StringWriter;
  25. import java.lang.reflect.Method;
  26. import java.net.MalformedURLException;
  27. import java.net.URL;
  28. import java.security.AccessController;
  29. import java.security.PrivilegedAction;
  30. import java.text.SimpleDateFormat;
  31. import java.util.ArrayList;
  32. import java.util.Arrays;
  33. import java.util.Date;
  34. import java.util.List;
  35. import java.util.StringTokenizer;
  36.  
  37. /**
  38.  * Main class for JMeter - sets up initial classpath and the loader.
  39.  *
  40.  */
  41. public final class NewDriver {
  42.  
  43.     private static final String CLASSPATH_SEPARATOR = File.pathSeparator;
  44.  
  45.     private static final String OS_NAME = System.getProperty("os.name");// $NON-NLS-1$
  46.  
  47.     private static final String OS_NAME_LC = OS_NAME.toLowerCase(java.util.Locale.ENGLISH);
  48.  
  49.     private static final String JAVA_CLASS_PATH = "java.class.path";// $NON-NLS-1$
  50.  
  51.     private static final String JMETER_LOGFILE_SYSTEM_PROPERTY = "jmeter.logfile";// $NON-NLS-1$
  52.  
  53.     private static final String HEADLESS_MODE_PROPERTY = "java.awt.headless";// $NON-NLS-1$
  54.     /** The class loader to use for loading JMeter classes. */
  55.     private static final DynamicClassLoader loader;
  56.  
  57.     /** The directory JMeter is installed in. */
  58.     private static final String JMETER_INSTALLATION_DIRECTORY;
  59.  
  60.     private static final List<Exception> EXCEPTIONS_IN_INIT = new ArrayList<>();
  61.  
  62.     static {
  63.         final List<URL> jars = new ArrayList<>();
  64.         final String initiaClasspath = System.getProperty(JAVA_CLASS_PATH);
  65.  
  66.         // Find JMeter home dir from the initial classpath
  67.         String tmpDir;
  68.         StringTokenizer tok = new StringTokenizer(initiaClasspath, File.pathSeparator);
  69.         if (tok.countTokens() == 1
  70.                 || (tok.countTokens()  == 2 // Java on Mac OS can add a second entry to the initial classpath
  71.                     && OS_NAME_LC.startsWith("mac os x")// $NON-NLS-1$
  72.                    )
  73.            ) {
  74.             File jar = new File(tok.nextToken());
  75.             try {
  76.                 tmpDir = jar.getCanonicalFile().getParentFile().getParent();
  77.             } catch (IOException e) {
  78.                 tmpDir = null;
  79.             }
  80.         } else {// e.g. started from IDE with full classpath
  81.             tmpDir = System.getProperty("jmeter.home", System.getenv("JMETER_HOME"));// Allow override $NON-NLS-1$ $NON-NLS-2$
  82.             if (tmpDir == null || tmpDir.length() == 0) {
  83.                 File userDir = new File(System.getProperty("user.dir"));// $NON-NLS-1$
  84.                 tmpDir = userDir.getAbsoluteFile().getParent();
  85.             }
  86.         }
  87.         if (tmpDir == null) {
  88.             tmpDir = System.getenv("JMETER_HOME");
  89.         }
  90.         JMETER_INSTALLATION_DIRECTORY=tmpDir;
  91.  
  92.         /*
  93.          * Does the system support UNC paths? If so, may need to fix them up
  94.          * later
  95.          */
  96.         boolean usesUNC = OS_NAME_LC.startsWith("windows");// $NON-NLS-1$
  97.  
  98.         // Add standard jar locations to initial classpath
  99.         StringBuilder classpath = new StringBuilder();
  100.         File[] libDirs = new File[] { new File(JMETER_INSTALLATION_DIRECTORY + File.separator + "lib"),// $NON-NLS-1$ $NON-NLS-2$
  101.                 new File(JMETER_INSTALLATION_DIRECTORY + File.separator + "lib" + File.separator + "ext"),// $NON-NLS-1$ $NON-NLS-2$
  102.                 new File(JMETER_INSTALLATION_DIRECTORY + File.separator + "lib" + File.separator + "junit")};// $NON-NLS-1$ $NON-NLS-2$
  103.         for (File libDir : libDirs) {
  104.             File[] libJars = libDir.listFiles((dir, name) -> name.endsWith(".jar"));
  105.             if (libJars == null) {
  106.                 new Throwable("Could not access " + libDir).printStackTrace(); // NOSONAR No logging here
  107.                 continue;
  108.             }
  109.             Arrays.sort(libJars); // Bug 50708 Ensure predictable order of jars
  110.             for (File libJar : libJars) {
  111.                 try {
  112.                     String s = libJar.getPath();
  113.  
  114.                     // Fix path to allow the use of UNC URLs
  115.                     if (usesUNC) {
  116.                         if (s.startsWith("\\\\") && !s.startsWith("\\\\\\")) {// $NON-NLS-1$ $NON-NLS-2$
  117.                             s = "\\\\" + s;// $NON-NLS-1$
  118.                         } else if (s.startsWith("//") && !s.startsWith("///")) {// $NON-NLS-1$ $NON-NLS-2$
  119.                             s = "//" + s;// $NON-NLS-1$
  120.                         }
  121.                     } // usesUNC
  122.  
  123.                     jars.add(new File(s).toURI().toURL());// See Java bug 4496398
  124.                     classpath.append(CLASSPATH_SEPARATOR);
  125.                     classpath.append(s);
  126.                 } catch (MalformedURLException e) { // NOSONAR
  127.                     EXCEPTIONS_IN_INIT.add(new Exception("Error adding jar:"+libJar.getAbsolutePath(), e));
  128.                 }
  129.             }
  130.         }
  131.  
  132.         // ClassFinder needs the classpath
  133.         System.setProperty(JAVA_CLASS_PATH, initiaClasspath + classpath.toString());
  134.         loader = AccessController.doPrivileged(
  135.                 (PrivilegedAction<DynamicClassLoader>) () ->
  136.                         new DynamicClassLoader(jars.toArray(new URL[jars.size()]))
  137.         );
  138.     }
  139.  
  140.     /**
  141.      * Prevent instantiation.
  142.      */
  143.     private NewDriver() {
  144.     }
  145.  
  146.     /**
  147.      * Generate an array of jar files located in a directory.
  148.      * Jar files located in sub directories will not be added.
  149.      *
  150.      * @param dir to search for the jar files.
  151.      */
  152.     private static File[] listJars(File dir) {
  153.         if (dir.isDirectory()) {
  154.             return dir.listFiles((f, name) -> {
  155.                 if (name.endsWith(".jar")) {// $NON-NLS-1$
  156.                     File jar = new File(f, name);
  157.                     return jar.isFile() && jar.canRead();
  158.                 }
  159.                 return false;
  160.             });
  161.         }
  162.         return new File[0];
  163.     }
  164.  
  165.     /**
  166.      * Add a URL to the loader classpath only; does not update the system classpath.
  167.      *
  168.      * @param path to be added.
  169.      * @throws MalformedURLException when <code>path</code> points to an invalid url
  170.      */
  171.     public static void addURL(String path) throws MalformedURLException {
  172.         File furl = new File(path);
  173.         loader.addURL(furl.toURI().toURL()); // See Java bug 4496398
  174.         File[] jars = listJars(furl);
  175.         for (File jar : jars) {
  176.             loader.addURL(jar.toURI().toURL()); // See Java bug 4496398
  177.         }
  178.     }
  179.  
  180.     /**
  181.      * Add a URL to the loader classpath only; does not update the system
  182.      * classpath.
  183.      *
  184.      * @param url
  185.      *            The {@link URL} to add to the classpath
  186.      */
  187.     public static void addURL(URL url) {
  188.         loader.addURL(url);
  189.     }
  190.  
  191.     /**
  192.      * Add a directory or jar to the loader and system classpaths.
  193.      *
  194.      * @param path
  195.      *            to add to the loader and system classpath
  196.      * @throws MalformedURLException
  197.      *             if <code>path</code> can not be transformed to a valid
  198.      *             {@link URL}
  199.      */
  200.     public static void addPath(String path) throws MalformedURLException {
  201.         File file = new File(path);
  202.         // Ensure that directory URLs end in "/"
  203.         if (file.isDirectory() && !path.endsWith("/")) {// $NON-NLS-1$
  204.             file = new File(path + "/");// $NON-NLS-1$
  205.         }
  206.         loader.addURL(file.toURI().toURL()); // See Java bug 4496398
  207.         StringBuilder sb = new StringBuilder(System.getProperty(JAVA_CLASS_PATH));
  208.         sb.append(CLASSPATH_SEPARATOR);
  209.         sb.append(path);
  210.         File[] jars = listJars(file);
  211.         for (File jar : jars) {
  212.             loader.addURL(jar.toURI().toURL()); // See Java bug 4496398
  213.             sb.append(CLASSPATH_SEPARATOR);
  214.             sb.append(jar.getPath());
  215.         }
  216.  
  217.         // ClassFinder needs this
  218.         System.setProperty(JAVA_CLASS_PATH,sb.toString());
  219.     }
  220.  
  221.     /**
  222.      * Get the directory where JMeter is installed. This is the absolute path
  223.      * name.
  224.      *
  225.      * @return the directory where JMeter is installed.
  226.      */
  227.     public static String getJMeterDir() {
  228.         return JMETER_INSTALLATION_DIRECTORY;
  229.     }
  230.  
  231.     /**
  232.      * The main program which actually runs JMeter.
  233.      *
  234.      * @param args
  235.      *            the command line arguments
  236.      */
  237.     public static void main(String[] args) {
  238.         if(!EXCEPTIONS_IN_INIT.isEmpty()) {
  239.             System.err.println("Configuration error during init, see exceptions:"+exceptionsToString(EXCEPTIONS_IN_INIT)); // NOSONAR Intentional System.err use
  240.         } else {
  241.             Thread.currentThread().setContextClassLoader(loader);
  242.  
  243.  
  244.             setLoggingProperties(args);
  245.  
  246.             try {
  247.                 // Only set property if it has not been set explicitely
  248.                 if(System.getProperty(HEADLESS_MODE_PROPERTY) == null && shouldBeHeadless(args)) {
  249.                     System.setProperty(HEADLESS_MODE_PROPERTY, "true");
  250.                 }
  251.                 Class<?> initialClass = loader.loadClass("org.apache.jmeter.JMeter");// $NON-NLS-1$
  252.                 Object instance = initialClass.getDeclaredConstructor().newInstance();
  253.                 Method startup = initialClass.getMethod("start", new Class[] { new String[0].getClass() });// $NON-NLS-1$
  254.                 startup.invoke(instance, new Object[] { args });
  255.             } catch(Throwable e){ // NOSONAR We want to log home directory in case of exception
  256.                 e.printStackTrace(); // NOSONAR No logger at this step
  257.                 System.err.println("JMeter home directory was detected as: "+JMETER_INSTALLATION_DIRECTORY); // NOSONAR Intentional System.err use
  258.             }
  259.         }
  260.     }
  261.  
  262.     /**
  263.      * @param exceptionsInInit List of {@link Exception}
  264.      * @return String
  265.      */
  266.     private static String exceptionsToString(List<Exception> exceptionsInInit) {
  267.         StringBuilder builder = new StringBuilder();
  268.         for (Exception exception : exceptionsInInit) {
  269.             StringWriter stringWriter = new StringWriter();
  270.             PrintWriter printWriter = new PrintWriter(stringWriter);
  271.             exception.printStackTrace(printWriter); // NOSONAR
  272.             builder.append(stringWriter.toString())
  273.                 .append("\r\n");
  274.         }
  275.         return builder.toString();
  276.     }
  277.  
  278.     /*
  279.      * Set logging related system properties.
  280.      */
  281.     private static void setLoggingProperties(String[] args) {
  282.         String jmLogFile = getCommandLineArgument(args, 'j', "jmeterlogfile");// $NON-NLS-1$ $NON-NLS-2$
  283.  
  284.         if (jmLogFile != null && !jmLogFile.isEmpty()) {
  285.             jmLogFile = replaceDateFormatInFileName(jmLogFile);
  286.             System.setProperty(JMETER_LOGFILE_SYSTEM_PROPERTY, jmLogFile);// $NON-NLS-1$
  287.         } else if (System.getProperty(JMETER_LOGFILE_SYSTEM_PROPERTY) == null) {// $NON-NLS-1$
  288.             System.setProperty(JMETER_LOGFILE_SYSTEM_PROPERTY, "jmeter.log");// $NON-NLS-1$ $NON-NLS-2$
  289.         }
  290.  
  291.         String jmLogConf = getCommandLineArgument(args, 'i', "jmeterlogconf");// $NON-NLS-1$ $NON-NLS-2$
  292.         File logConfFile = null;
  293.  
  294.         if (jmLogConf != null && !jmLogConf.isEmpty()) {
  295.             logConfFile = new File(jmLogConf);
  296.         } else if (System.getProperty("log4j.configurationFile") == null) {// $NON-NLS-1$
  297.             logConfFile = new File("log4j2.xml");// $NON-NLS-1$
  298.             if (!logConfFile.isFile()) {
  299.                 logConfFile = new File(JMETER_INSTALLATION_DIRECTORY, "bin" + File.separator + "log4j2.xml");// $NON-NLS-1$ $NON-NLS-2$
  300.             }
  301.         }
  302.  
  303.         if (logConfFile != null) {
  304.             System.setProperty("log4j.configurationFile", logConfFile.toURI().toString());// $NON-NLS-1$
  305.         }
  306.     }
  307.  
  308.     private static boolean shouldBeHeadless(String[] args) {
  309.         for (String arg : args) {
  310.             if("-n".equals(arg) || "-s".equals(arg) || "-g".equals(arg)) {
  311.                 return true;
  312.             }
  313.         }
  314.         return false;
  315.     }
  316.     /*
  317.      * Find command line argument option value by the id and name.
  318.      */
  319.     private static String getCommandLineArgument(String[] args, int id, String name) {
  320.         final String shortArgName = "-" + ((char) id);// $NON-NLS-1$
  321.         final String longArgName = "--" + name;// $NON-NLS-1$
  322.  
  323.         String value = null;
  324.  
  325.         for (int i = 0; i < args.length; i++) {
  326.             if ((shortArgName.equals(args[i]) && i < args.length - 1)
  327.                     || longArgName.equals(args[i])) {
  328.                 if (!args[i + 1].startsWith("-")) {// $NON-NLS-1$
  329.                     value = args[i + 1];
  330.                 }
  331.                 break;
  332.             } else if (!shortArgName.equals(args[i]) && args[i].startsWith(shortArgName)) {
  333.                 value = args[i].substring(shortArgName.length());
  334.                 break;
  335.             }
  336.         }
  337.  
  338.         return value;
  339.     }
  340.  
  341.     /*
  342.      * If the fileName contains at least one set of paired single-quotes, reformat using DateFormat
  343.      */
  344.     @SuppressWarnings("JdkObsolete")
  345.     private static String replaceDateFormatInFileName(String fileName) {
  346.         try {
  347.             StringBuilder builder = new StringBuilder();
  348.  
  349.             // TODO: replace with java.time.*
  350.             final Date date = new Date();
  351.             int fromIndex = 0;
  352.             int begin = fileName.indexOf('\'', fromIndex);// $NON-NLS-1$
  353.             int end;
  354.  
  355.             String format;
  356.             SimpleDateFormat dateFormat;
  357.  
  358.             while (begin != -1) {
  359.                 builder.append(fileName.substring(fromIndex, begin));
  360.  
  361.                 fromIndex = begin + 1;
  362.                 end = fileName.indexOf('\'', fromIndex);// $NON-NLS-1$
  363.                 if (end == -1) {
  364.                     throw new IllegalArgumentException("Invalid pairs of single-quotes in the file name: " + fileName);// $NON-NLS-1$
  365.                 }
  366.  
  367.                 format = fileName.substring(begin + 1, end);
  368.                 dateFormat = new SimpleDateFormat(format);
  369.                 builder.append(dateFormat.format(date));
  370.  
  371.                 fromIndex = end + 1;
  372.                 begin = fileName.indexOf('\'', fromIndex);// $NON-NLS-1$
  373.             }
  374.  
  375.             if (fromIndex < fileName.length() - 1) {
  376.                 builder.append(fileName.substring(fromIndex));
  377.             }
  378.  
  379.             return builder.toString();
  380.         } catch (Exception ex) {
  381.             System.err.println("Error replacing date format in file name:"+fileName+", error:"+ex.getMessage()); // NOSONAR
  382.         }
  383.  
  384.         return fileName;
  385.     }
  386. }
RAW Paste Data