in src/core/src/main/java/org/apache/jmeter/JMeter.java [358:521]
public void start(String[] args) {
CLArgsParser parser = new CLArgsParser(args, options);
String error = parser.getErrorString();
if (error == null){// Check option combinations
boolean gui = parser.getArgumentById(NONGUI_OPT)==null;
boolean nonGuiOnly = parser.getArgumentById(REMOTE_OPT)!=null
|| parser.getArgumentById(REMOTE_OPT_PARAM)!=null
|| parser.getArgumentById(REMOTE_STOP)!=null;
if (gui && nonGuiOnly) {
error = "-r and -R and -X are only valid in non-GUI mode";
}
}
if (null != error) {
System.err.println("Error: " + error);//NOSONAR
System.out.println("Usage");//NOSONAR
System.out.println(CLUtil.describeOptions(options).toString());//NOSONAR
// repeat the error so no need to scroll back past the usage to see it
System.out.println("Error: " + error);//NOSONAR
return;
}
try {
initializeProperties(parser); // Also initialises JMeter logging
SecurityProviderLoader.addSecurityProvider(JMeterUtils.getJMeterProperties());
Thread.setDefaultUncaughtExceptionHandler(
(Thread t, Throwable e) -> {
if (!(e instanceof ThreadDeath)) {
log.error("Uncaught exception in thread {}", t, e);
System.err.println("Uncaught Exception " + e + " in thread " + t + ". See log file for details.");//NOSONAR
}
});
if (log.isInfoEnabled()) {
log.info(JMeterUtils.getJMeterCopyright());
log.info("Version {}", JMeterUtils.getJMeterVersion());
log.info("java.version={}", System.getProperty("java.version"));//$NON-NLS-1$ //$NON-NLS-2$
log.info("java.vm.name={}", System.getProperty("java.vm.name"));//$NON-NLS-1$ //$NON-NLS-2$
log.info("os.name={}", System.getProperty("os.name"));//$NON-NLS-1$ //$NON-NLS-2$
log.info("os.arch={}", System.getProperty("os.arch"));//$NON-NLS-1$ //$NON-NLS-2$
log.info("os.version={}", System.getProperty("os.version"));//$NON-NLS-1$ //$NON-NLS-2$
log.info("file.encoding={}", System.getProperty("file.encoding"));//$NON-NLS-1$ //$NON-NLS-2$
log.info("java.awt.headless={}", System.getProperty("java.awt.headless"));//$NON-NLS-1$ //$NON-NLS-2$
log.info("Max memory ={}", Runtime.getRuntime().maxMemory());
log.info("Available Processors ={}", Runtime.getRuntime().availableProcessors());
log.info("Default Locale={}", Locale.getDefault().getDisplayName());
log.info("JMeter Locale={}", JMeterUtils.getLocale().getDisplayName());
log.info("JMeterHome={}", JMeterUtils.getJMeterHome());
log.info("user.dir ={}", System.getProperty("user.dir"));//$NON-NLS-1$ //$NON-NLS-2$
log.info("PWD ={}", new File(".").getCanonicalPath());//$NON-NLS-1$
log.info("IP: {} Name: {} FullName: {}", JMeterUtils.getLocalHostIP(), JMeterUtils.getLocalHostName(),
JMeterUtils.getLocalHostFullName());
}
setProxy(parser);
updateClassLoader();
if (log.isDebugEnabled())
{
String jcp=System.getProperty("java.class.path");// $NON-NLS-1$
String[] bits = jcp.split(File.pathSeparator);
log.debug("ClassPath");
for(String bit : bits){
log.debug(bit);
}
}
// Set some (hopefully!) useful properties
Instant now = Instant.now();
JMeterUtils.setProperty("START.MS",Long.toString(now.toEpochMilli()));// $NON-NLS-1$
JMeterUtils.setProperty("START.YMD", getFormatter("yyyyMMdd").format(now));// $NON-NLS-1$ $NON-NLS-2$
JMeterUtils.setProperty("START.HMS", getFormatter("HHmmss").format(now));// $NON-NLS-1$ $NON-NLS-2$
// For unknown reason, TestElementSchema might fail to initialize in remote execution mode
// It reproduces with Java 11.0.13, and the error is StackOverflowError with the following stacktrace
// The workaround is to initialize Kotlin reflection before deserializing the test plan.
// at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174) ~[?:?]
// at java.net.URLClassLoader.defineClass(URLClassLoader.java:555) ~[?:?]
// at java.net.URLClassLoader$1.run(URLClassLoader.java:458) ~[?:?]
// at java.net.URLClassLoader$1.run(URLClassLoader.java:452) ~[?:?]
// at java.security.AccessController.doPrivileged(Native Method) ~[?:?]
// at java.net.URLClassLoader.findClass(URLClassLoader.java:451) ~[?:?]
// at java.lang.ClassLoader.loadClass(ClassLoader.java:589) ~[?:?]
// at org.apache.jmeter.DynamicClassLoader.loadClass(DynamicClassLoader.java:81) ~[ApacheJMeter.jar:5.5.1-SNAPSHOT]
// at java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[?:?]
// at kotlin.jvm.internal.ClassReference.<clinit>(ClassReference.kt:156) ~[kotlin-stdlib-1.8.21.jar:1.8.21-release-380(1.8.21)]
// at kotlin.jvm.internal.ReflectionFactory.getOrCreateKotlinClass(ReflectionFactory.java:30) ~[kotlin-stdlib-1.8.21.jar)]
// at kotlin.jvm.internal.Reflection.getOrCreateKotlinClass(Reflection.java:60) ~[kotlin-stdlib-1.8.21.jar:1.8.21-release-380(1.8.21)]
// at org.apache.jmeter.testelement.TestElementSchema.<init>(TestElementSchema.kt:33) ~[ApacheJMeter_core.jar:5.5.1-SNAPSHOT]
// at org.apache.jmeter.testelement.TestElementSchema$INSTANCE.<init>(TestElementSchema.kt:26) ~[ApacheJMeter_core.jar:5.5.1-SNAPSHOT]
// at org.apache.jmeter.testelement.TestElementSchema$INSTANCE.<init>(TestElementSchema.kt) ~[ApacheJMeter_core.jar:5.5.1-SNAPSHOT]
// at org.apache.jmeter.testelement.TestElementSchema.<clinit>(TestElementSchema.kt) ~[ApacheJMeter_core.jar:5.5.1-SNAPSHOT]
// at org.apache.jmeter.protocol.java.sampler.BeanShellSampler.<clinit>(BeanShellSampler.java:53) ~[ApacheJMeter_java.jar:5.5.1-SNAPSHOT]
// at jdk.internal.misc.Unsafe.ensureClassInitialized0(Native Method) ~[?:?]
TestElementSchema.INSTANCE.getGuiClass();
if (parser.getArgumentById(VERSION_OPT) != null) {
displayAsciiArt();
} else if (parser.getArgumentById(HELP_OPT) != null) {
displayAsciiArt();
System.out.println(JMeterUtils.getResourceFileAsText("org/apache/jmeter/help.txt"));//NOSONAR $NON-NLS-1$
} else if (parser.getArgumentById(OPTIONS_OPT) != null) {
displayAsciiArt();
System.out.println(CLUtil.describeOptions(options).toString());//NOSONAR
} else if (parser.getArgumentById(SERVER_OPT) != null) {
// Start the server
try {
RemoteJMeterEngineImpl.startServer(RmiUtils.getRmiRegistryPort()); // $NON-NLS-1$
startOptionalServers();
} catch (Exception ex) {
System.err.println("Server failed to start: "+ex);//NOSONAR
log.error("Giving up, as server failed with:", ex);
throw ex;
}
} else {
String testFile=null;
CLOption testFileOpt = parser.getArgumentById(TESTFILE_OPT);
if (testFileOpt != null){
testFile = testFileOpt.getArgument();
if (USE_LAST_JMX.equals(testFile)) {
testFile = LoadRecentProject.getRecentFile(0);// most recent
}
}
CLOption testReportOpt = parser.getArgumentById(REPORT_GENERATING_OPT);
if (testReportOpt != null) { // generate report from existing file
String reportFile = testReportOpt.getArgument();
extractAndSetReportOutputFolder(parser, deleteResultFile);
ReportGenerator generator = new ReportGenerator(reportFile, null);
generator.generate();
} else if (parser.getArgumentById(NONGUI_OPT) == null) { // not non-GUI => GUI
PluginManager.install(this, true);
String initialTestFile = testFile;
JMeterGuiLauncher.startGui(initialTestFile);
startOptionalServers();
} else { // NON-GUI must be true
extractAndSetReportOutputFolder(parser, deleteResultFile);
CLOption remoteTest = parser.getArgumentById(REMOTE_OPT_PARAM);
if (remoteTest == null) {
remoteTest = parser.getArgumentById(REMOTE_OPT);
}
CLOption jtl = parser.getArgumentById(LOGFILE_OPT);
String jtlFile = null;
if (jtl != null) {
jtlFile = processLAST(jtl.getArgument(), ".jtl"); // $NON-NLS-1$
}
CLOption reportAtEndOpt = parser.getArgumentById(REPORT_AT_END_OPT);
if(reportAtEndOpt != null && jtlFile == null) {
throw new IllegalUserActionException(
"Option -"+ ((char)REPORT_AT_END_OPT)+" requires -"+((char)LOGFILE_OPT )+ " option");
}
startNonGui(testFile, jtlFile, remoteTest, reportAtEndOpt != null);
startOptionalServers();
}
}
} catch (IllegalUserActionException e) {// NOSONAR
System.out.println("Incorrect Usage:"+e.getMessage());//NOSONAR
System.out.println(CLUtil.describeOptions(options).toString());//NOSONAR
} catch (Throwable e) { // NOSONAR
log.error("An error occurred: ", e);
System.out.println("An error occurred: " + e.getMessage());//NOSONAR
// FIXME Should we exit here ? If we are called by Maven or Jenkins
System.exit(1);
}
}