当以编程方式从网格进程中生成第二个Selenium网格节点作为另一个进程时出现ParameterException



我正在设置Selenium Grid,它可以从网格Servlet端点上的HTTP请求生成新的节点实例:SpawnNodeServlet。GET请求上的Servlet正在创建新的Selenium网格节点,并配置为将其注册到集线器。通过这种方式,我可以在需要时添加节点,只需在http://localhost:4444/grid/admin/SpawnNodeServlet下发送GET请求。在我想要生成第二个或下一个节点之前,一切都很好。只有第一个能正常工作,之后我得到了ParameterException(下面的所有代码)。由于第一个节点正确注册,因此参数应该很好。有什么想法吗?我认为,麻烦可能是在流程创建实现过程中。

我尝试将Runtime exec中的jar作为普通命令执行,但也不能正常工作。

final Runtime runtime = Runtime.getRuntime();
final Process command = runtime.exec(executionArgs.toArray(new String[0]));

以下是允许创建新节点实例的InstanceExecutor的主要代码:

public class InstanceExecutor {
private final Logger logger = Logger.getLogger(getClass().getName());
private BufferedReader errorBufferedReader;
private BufferedReader outputBufferedReader;
private int exitValue;
public void execute(List<String> args) throws InstanceExecutorException {
final List<String> executionArgs = new ArrayList<String>();
executionArgs.add(0, "java");
executionArgs.addAll(args);
try {
final ProcessBuilder processBuilder = new ProcessBuilder(executionArgs.toArray(new String[0]));
Process process = processBuilder.start();
logger.info("processBuilder.start()");
this.errorBufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
this.outputBufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
logger.info("BufferedReader's");
process.waitFor();
this.exitValue = process.exitValue();
if (this.exitValue != 0) {
throw new IOException("Failed to execute jar, " + this.getExecutionLog());
}
} catch (final IOException | InterruptedException e) {
throw new InstanceExecutorException(e);
}
}
public String getExecutionLog() {
StringBuilder error = new StringBuilder();
String line;
try {
while((line = this.errorBufferedReader.readLine()) != null) {
error
.append("n")
.append(line);
}
} catch (final IOException ignored) { }
StringBuilder output = new StringBuilder();
try {
while((line = this.outputBufferedReader.readLine()) != null) {
output
.append("n")
.append(line);
}
} catch (final IOException ignored) { }
try {
this.errorBufferedReader.close();
this.outputBufferedReader.close();
} catch (final IOException ignored) { }
return "exitValue: " + this.exitValue + ", error: " + error + ", output: " + output;
}
}

这类InstanceExecutor用于SpawnNodeServlet:的doGet

public class SpawnNodeServlet extends RegistryBasedServlet {
public SpawnNodeServlet() {
this(null);
}
public SpawnNodeServlet(GridRegistry registry) {
super(registry);
}
private final Logger logger = Logger.getLogger(getClass().getName());
private InstanceExecutor instanceExecutor = new InstanceExecutor();
private final List<String> nodeArgs = new ArrayList<String>();
private void sendResponse(HttpServletResponse response) throws IOException {
PrintWriter out = response.getWriter();
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.setStatus(200);
out.flush();
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
logger.info("Spawning additional node");
nodeArgs.add("-Dwebdriver.chrome.driver="libs//chromedriver"");
nodeArgs.add("-cp");
nodeArgs.add("hub/target/hub-1.0.0-jar-with-dependencies.jar:node/target/node-1.0.0-jar-with-dependencies.jar");
nodeArgs.add("org.openqa.grid.selenium.GridLauncherV3");
nodeArgs.add("-role");
nodeArgs.add("node");
nodeArgs.add("-nodeConfig");
nodeArgs.add("node/config.json");
try {
instanceExecutor.execute(nodeArgs);
} catch (InstanceExecutorException e) {
throw new IOException(e);
}
sendResponse(response);
}
}

这是我在http://localhost:4444/grid/admin/SpawnNodeServlet:上执行两次GET请求后的控制台日志

3:27:46.126 INFO [SpawnNodeServlet.doGet] - Spawning additional node
23:27:46.141 INFO [InstanceExecutor.execute] - processBuilder.start()
23:27:46.142 INFO [InstanceExecutor.execute] - BufferedReader's
23:27:47.018 INFO [DefaultGridRegistry.add] - Registered a node http://169.254.168.67:8992
23:27:47.018 INFO [DefaultProxy.startPolling] - startPolling()
23:30:33.954 INFO [SpawnNodeServlet.doGet] - Spawning additional node
23:30:33.959 INFO [InstanceExecutor.execute] - processBuilder.start()
23:30:33.960 INFO [InstanceExecutor.execute] - BufferedReader's
2019-09-08 23:30:34.203:WARN:osjs.HttpChannel:qtp1128948651-14: /grid/admin/SpawnNodeServlet java.io.IOException: exception.InstanceExecutorException: java.io.IOException: Failed to execute jar, exitValue: 1, error:
Exception in thread "main" com.beust.jcommander.ParameterException: Was passed main parameter '-Dwebdriver.chrome.driver="libs//chromedriver"' but no main parameter was defined in your arg class
at com.beust.jcommander.JCommander.initMainParameterValue(JCommander.java:936)
at com.beust.jcommander.JCommander.parseValues(JCommander.java:752)
at com.beust.jcommander.JCommander.parse(JCommander.java:340)
at com.beust.jcommander.JCommander.parse(JCommander.java:319)
at org.openqa.grid.selenium.GridLauncherV3.parse(GridLauncherV3.java:218)
at org.openqa.grid.selenium.GridLauncherV3.lambda$buildLaunchers$7(GridLauncherV3.java:271)
at org.openqa.grid.selenium.GridLauncherV3.lambda$launch$0(GridLauncherV3.java:86)
at java.base/java.util.Optional.map(Optional.java:265)
at org.openqa.grid.selenium.GridLauncherV3.launch(GridLauncherV3.java:86)
at org.openqa.grid.selenium.GridLauncherV3.main(GridLauncherV3.java:70), output:

正如您所看到的,第一次执行会正确地生成Node,但第二次执行会出现此错误。

应该如何将这个流程构建器逻辑更改为不等待流程结束(我试图删除它,只创建流程,但它也不起作用),并能够生成1个以上的Selenium网格节点?

在SpawnNodeServlet中,您应该删除类字段nodeArgs,并将nodeArgs定义为本地方法变量。

您有实例字段:

private final List<String> nodeArgs = new ArrayList<String>();

第一个服务调用列表后包含:

"-Dwebdriver.chrome.driver="libs//chromedriver""
"-cp"
"hub/target/hub-1.0.0-jar-with-dependencies.jar:node/target/node-1.0.0-jar-with-dependencies.jar"
"org.openqa.grid.selenium.GridLauncherV3"
"-role"
"node"
"-nodeConfig"
"node/config.json"

第二次调用后:

"-Dwebdriver.chrome.driver="libs//chromedriver""
"-cp"
"hub/target/hub-1.0.0-jar-with-dependencies.jar:node/target/node-1.0.0-jar-with-dependencies.jar"
"org.openqa.grid.selenium.GridLauncherV3"
"-role"
"node"
"-nodeConfig"
"node/config.json"
"-Dwebdriver.chrome.driver="libs//chromedriver""
"-cp"
"hub/target/hub-1.0.0-jar-with-dependencies.jar:node/target/node-1.0.0-jar-with-dependencies.jar"
"org.openqa.grid.selenium.GridLauncherV3"
"-role"
"node"
"-nodeConfig"
"node/config.json"

然后您将此列表传递给执行者:

instanceExecutor.execute(nodeArgs);

这不是有效的java参数列表。

最新更新