I am using MAC terminal to start appium server. In terminal I have executed command appium & to start the server which is working.
I have installed appium server through terminal using npm -g install appium
However when I am trying to execute the same code using Java then server is not starting.
Code:
Runtime.getRuntime().exec(new String[]{"/bin/sh","appium &"})
Error:
No such file or directory.
I have also tried to create shell script with appium command. When I invoke the shell script through Java, it says that command not found.
Code to invoke shell script command.
Process p = new ProcessBuilder(new String[]{"/bin/sh","-c","sh appium.sh"})
On invoking in Java, it gives error "appium.sh:Error on line1 - appium command not found"
When I invoked the same shell script through the terminal, appium server started successfully.
You can use below code for Starting appium server using java code and use service_url while intializing appium driver .Example is taken from THIS POST
import java.io.File;
import io.appium.java_client.service.local.AppiumDriverLocalService;
import io.appium.java_client.service.local.AppiumServiceBuilder;
public class AppiumServerStartStop {
static String Appium_Node_Path="C:\\Program Files (x86)\\Appium\\node.exe";
static String Appium_JS_Path="C:\\Program Files (x86)\\Appium\\node_modules\\appium\\bin\\appium.js";
static AppiumDriverLocalService service;
static String service_url;
public static void appiumStart() throws Exception{
service = AppiumDriverLocalService.buildService(new AppiumServiceBuilder().
usingPort(2856).usingDriverExecutable(new File(Appium_Node_Path)).
withAppiumJS(new File(Appium_JS_Path)));
service.start();
Thread.sleep(25000);
service_url = service.getUrl().toString();
}
public static void appiumStop() throws Exception{
service.stop();
}
}
public static void startAppiumServer() {
try {
Thread.sleep(3000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
final String appiumNodeFilePath = APPIUM_NODE_FILE_PATH;
final String appiumJavaScriptServerFile = APPIUM_JAVA_SCRIPT_SERVER_FILE_PATH;
final String appiumServerPortNumber = APPIUM_SERVER_PORT_NUMBER;
final String appiumServerConfigurations = "--no-reset --local-timezone --port "+ appiumServerPortNumber+ " -bp "+(Integer.parseInt(appiumServerPortNumber)+1);
(new Thread(){
public void run(){
String startCommand ="\"" + appiumNodeFilePath + "\" \""+ appiumJavaScriptServerFile + "\" "+ appiumServerConfigurations;
System.out.println("Server start command: "+startCommand);
executeCommand(startCommand);
}
}).start();
try {
Thread.sleep(25000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void executeCommand(String command) {
String s = null;
try {
Process p = Runtime.getRuntime().exec(command);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
System.out.println("Appium Server Output Logs:\n");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
System.out.println("Appium Server Error Logs:\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
} catch (IOException e) {
System.out.println("exception: ");
e.printStackTrace();
}
}
APPIUM_NODE_FILE_PATH="C:\Program Files (x86)\Appium\node.exe";
APPIUM_JAVA_SCRIPT_SERVER_FILE_PATH="C:\ProgramFiles(x86)\Appium\node_modules\appium\bin\appium.js
If you are interested to learn how it should be implemented, check appium-java-client AppiumDriverLocalService class.
And since you are using java in most cases its better to use AppiumDriverLocalService instead implementing your own solution:
AppiumDriverLocalService service = AppiumDriverLocalService.
buildDefaultService();
service.start() // to start appium server
...
service.getUrl() // to get URL of running server
...
service.isRunning() // to check if appium server is alive
...
service.stop() // to stop appium server
Related
I want launch a batch file with JAVA. So I create a shortcut to this file and config Run as Administrator. I tested the batch file and it run success. But when, I run it with java, the batch file don't run with Administrator and the request is denied.
In java source, I try to call a shortcut of cmd.exe with shortcut configed Run as Administrator. And java source open the commandline with Administrator success.
Please help me.
Here my code:
package testfp;
import java.io.*;
public class RunCommand {
String command,result;
public RunCommand(String command) {
this.command = command;
run();
System.out.println(this.result);
}
public void run() {
try
{
Process process = Runtime.getRuntime().exec("cmd /c start C:\\Users\\minhlc\\Desktop\\test\\CMD");
// Fail to open with Administrator
// Process process = Runtime.getRuntime().exec("cmd /c start C:\\Users\\minhlc\\Desktop\\test\\start_apache");
// process.destroy();
// Process process = Runtime.getRuntime().exec("cmd /c start");
// kill_process();
BufferedReader br = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
try {
while ((line = br.readLine()) != null) {
this.result = this.result + "\n" + line;
}
} finally {
// br.close();
};
} catch (IOException e)
{
e.printStackTrace();
}
}
public void kill_process()
{
try {
Runtime.getRuntime().exec("taskkill /f /im cmd.exe") ;
} catch (Exception e) {
e.printStackTrace();
}
}
public String get_result() {
return result;
}
}
Thank for reading.
You need to run the java process with an administration privilege.
Open command line with "Run as administrator" and then
java -jar you_app.jar
This question already has answers here:
Execute external program through terminal in Java
(4 answers)
Executing another java program from our java program [duplicate]
(3 answers)
Closed 4 years ago.
Using
String cmdString = "cmd.exe /c start python ";
Process p = Runtime.getRuntime().exec(cmdString);
I can open the command prompt and run python. I now want to interact with the command prompt. I have read that using
public static void main(String[] args)
{
BufferedWriter writerToProc;
String scriptPath = "C:\\Users\\MichaelMi\\Documents\\SourceTree\\NODE-Sensor-Configurator\\src\\application\\resources\\BACnet-CMD-Line-Upgrader\\UpgradeApplication.py";
String iniPath = "C:\\Users\\MichaelMi\\Documents\\SourceTree\\NODE-Sensor-Configurator\\src\\application\\resources\\BACnet-CMD-Line-Upgrader\\BACpypes.ini";
String execString = "python " + scriptPath + " --ini " + iniPath;
String cmdString = "cmd.exe /c start " + execString ;
try {
Process p = Runtime.getRuntime().exec(cmdString);
writerToProc = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
writerToProc.write(cmdString);
writerToProc.flush();
writerToProc.write("whois\n");
writerToProc.flush();
readErrors(p);
readOutput(p);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void readOutput(Process p)
{
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
Runnable task = new Runnable() {
#Override
public void run() {
try {
if(stdInput.ready())
{
stdInput.lines().forEach((l) -> System.out.println(l));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread backgroundThread = new Thread(task);
backgroundThread.setDaemon(true);
backgroundThread.start();
}
public static void readErrors(Process p)
{
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
Runnable task = new Runnable() {
#Override
public void run() {
try {
if(stdError.ready())
{
stdError.lines().forEach((l) -> System.out.println(l));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread backgroundThread = new Thread(task);
backgroundThread.setDaemon(true);
backgroundThread.start();
}
Is supposed to allow me to write to the open command prompt. However this is not working for me. I am getting no exceptions thrown or status errors. I simply do not know how to write to an open command prompt.
I see two problems in your code:
One problem is the used command-line:
cmd.exe /c start python This starts a new cmd.exe instance which itself the uses start to start a detached python process. The detached process is therefore not connected to your BufferedReader/BufferedWriter.
Your second problem is that python does not execute your "1+1" via stdin.
You can simply verify that by creating a file test with the context 1+1\n and execute it on the console: python < test. You will see no output.
See also piping from stdin to a python code in a bash script.
In this case you need to close the input stream before you can read the output streams of the python process. If anyone knows a better way please let us know.
public static void main(String[] args) {
String cmdString = "python";
try {
ProcessBuilder pb = new ProcessBuilder(cmdString);
Process pr = pb.start();
try (BufferedReader readerOfProc = new BufferedReader(
new InputStreamReader(pr.getInputStream()));
BufferedReader errorsOfProc = new BufferedReader(
new InputStreamReader(pr.getErrorStream()))) {
try (BufferedWriter writerToProc = new BufferedWriter(
new OutputStreamWriter(pr.getOutputStream()));) {
writerToProc.write("myVar=1+1\r\n");
writerToProc.write("print(myVar)\r\n");
writerToProc.flush();
} catch (Exception e) {
e.printStackTrace();
}
String s;
while ((s = readerOfProc.readLine()) != null) {
System.out.println("stdout: " + s);
}
while ((s = errorsOfProc.readLine()) != null) {
System.out.println("stdout: " + s);
}
System.out.println("exit code: " + pr.waitFor());
}
} catch (Exception e) {
e.printStackTrace();
}
}
Hope this helps!
I want to run a python file that can run AWS CloudFormation template using JAVA.
I am passing python file in JAVA code.
When I run the JAVA code it pauses at the following state:
compile-single:
run-single:
If i run the Python file from terminal it works perfectly.
Java Code:
private void RunPythonActionPerformed(java.awt.event.ActionEvent evt) {
String pythonScriptPath = "path to python file";
String[] cmd = new String[2];
cmd[0] = "python"; // check version of installed python: python -V
cmd[1] = pythonScriptPath;
// create runtime to execute external command
Runtime rt = Runtime.getRuntime();
Process pr = null;
try {
pr = rt.exec(cmd);
// retrieve output from python script
} catch (IOException ex) {
Logger.getLogger(Page2.class.getName()).log(Level.SEVERE, null, ex);
}
BufferedReader bfr = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line = "";
try {
while((line = bfr.readLine()) != null) {
// display each output line form python script
System.out.println(line);
}
// TODO add your handling code here:
} catch (IOException ex) {
Logger.getLogger(Page2.class.getName()).log(Level.SEVERE, null, ex);
}
}
Provide path to your source file at <complete path to your python source file>
Copying working code for you. For me output is Python 3.6.5
package com.samples;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class ProcessBuilderSample {
public static void main(String [] args) throws IOException {
RunPythonActionPerformed();
}
private static void RunPythonActionPerformed() throws IOException {
String pythonScriptPath = "python -V";
Process p = Runtime.getRuntime().exec(pythonScriptPath);
BufferedReader bfr = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
try {
while((line = bfr.readLine()) != null) {
// display each output line form python script
System.out.println(line);
}
// TODO add your handling code here:
} catch (IOException ex) {
}
}
}
I have a Java Swing class from which I want my Java application to run a local python program after clicking a button. The following code does not run the executable python I have created.
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
try {
// TODO add your handling code here:
Process process =
Runtime.getRuntime().exec("C:\\Users\\User\\Desktop\\hello.exe");
} catch (IOException ex) {
Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
I have even tried running the python script file using:
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
try {
Process p= Runtime.getRuntime().exec("C:\\Python27\\python.exe \"C:\\Users\\User\\Desktop\\hello.py\"");
} catch (IOException ex) {
Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
I have no errors yet neither does the job. I can run applications like notepad etc using the same syntax, however I cant with python and I'm unsure how to resolve this.
P.s. I do have Python 2.7 PATH in my environment variable. Also, the above are just the methods for the action performed by the buttons. I have all the other methods and main class in my full program.
Process p= Runtime.getRuntime().exec("cmd /c /K \"C:\\Python27\\python.exe C:\\Users\\User\\Desktop\\hello.py\"");
do this way.. call the Python from cmd
I tried this simple example & it worked for me...
Files : CallPython.java & hello.py
CallPython.java
import java.util.*;
import java.io.*;
class CallPython{
public static void main(String args[]){
try{
Process proc= Runtime.getRuntime().exec("python hello.py");
BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
/*
BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
*/
stdInput.lines().forEach(System.out::println);
}
catch(IOException e){
System.err.println("Error occured while executing an external process...");
}
}
}
hello.py
print('Hello...from python script');
Output:
Hello...from python script
Is there a way I can get appium to startup within the code I am writing for a junit test? Since appium only needs to run when my test is running it doesnt make sense to me to keep the appium server always going.
Right now I am using junit and maven to run test builds. Due to stability issues with appium it will sometimes die in the middle of the build, thus failing all remaining tests. I want to know if it is possible to add something to the #Before method to start the appium server before connecting the WebDriver to it, and then terminating it in the #After method. This should address any issues with appium failures since it can reset before starting the next test.
Still looking into starting and ending processes in general in java to see if this will work. If I figure this out I will update this post to help anyone else interested in testing this way.
Figured out how to get this to work by just running the terminal command within the code
#Before
public void setUp() throws Exception {
closeSimulatorAndInstruments(); // also closes any appium servers
appium = Runtime.getRuntime().exec("/usr/local/bin/appium");
Thread.sleep(1000); // wait for appium to start up, not sure how to check the status
... // start test
}
#After
public void tearDown() throws Exception {
captureScreenshot(testName.getMethodName());
driver.quit();
appium.destroy(); // kills the appium server so it wont collide with the next run
}
I'm seeing issues with my CI box running jenkins attempting to do this but it's probably unrelated. Locally this is working great since I don't have to remember to run appium separately anymore or check to see if it died. This is not advised however if you need to see the appium output which may contain important errors
I have written a library for this.
/**
*#author Raghu Nair
*/
public class Appium {
private static volatile Appium instance;
public static Appium getInstance(String outFile, String errFile) {
if (instance == null) {
synchronized (Appium.class) {
if (instance == null) {
instance = new Appium(outFile, errFile);
}
}
}
return instance;
}
Process process;
final String outFile;
final String errFile;
private Appium(String outFile, String errFile) {
this.outFile = outFile;
this.errFile = errFile;
}
public void start() throws IOException {
if (process != null) {
stop();
}
String processName = System.getProperty("appium.bin");
String processString = processName + " -lt 180000";
ProcessBuilder builder = new ProcessBuilder("bash");
process = builder.start();
OutputStream outStream = System.out;
if (outFile != null) {
outStream = new FileOutputStream(outFile);
}
OutputStream errStream = System.err;
if (errFile != null) {
errStream = new FileOutputStream(errFile);
}
handleStream(process.getInputStream(), new PrintWriter(outStream));
handleStream(process.getErrorStream(), new PrintWriter(errStream));
try (PrintWriter writer = new PrintWriter(process.getOutputStream())) {
//writer.println("kill -9 `ps -ef | grep appium | cut -d' ' -f2`");
writer.println("export PATH=$PATH:/usr/bin/:/usr/local/bin/");
writer.println(processString);
writer.flush();
}
}
private void handleStream(final InputStream processOut, final PrintWriter writer) {
Thread outHandler;
outHandler = new Thread(new Runnable() {
#Override
public void run() {
try {
BufferedReader stdout = new BufferedReader(
new InputStreamReader(processOut));
String line;
while ((line = stdout.readLine()) != null) {
writer.println(line);
writer.flush();
}
} catch (IOException ex) {
ex.printStackTrace(System.err);
}
}
});
outHandler.start();
}
public void stop() {
System.out.println("Stopping the process");
if (process != null) {
try {
process.destroy();
process.getErrorStream().close();
process.getInputStream().close();
process.getOutputStream().close();
} catch (IOException ex) {
ex.printStackTrace(System.err);
}
}
}
public static void main(String[] args) throws Exception {
System.setProperty("appium.bin", "/Applications/Appium.app//Contents/Resources/node_modules/.bin/appium");
Appium appium = Appium.getInstance("/Users/<user>/tmp/appium.out", "/Users/<user>/tmp/appium.err");
appium.start();
TimeUnit.SECONDS.sleep(30);
appium.stop();
}
I've solved this in a very similar way using a DefaultExecutor to keep track of the Appium process so it can be destroyed at the end of the tests. This also allows the Appium output to be logged out during the tests using a DefaultExecuteResultHandler.
To avoid using a sleep to wait for Appium to start, you could create your WebDriver instance inside a try-catch
for (int i = 10; i > 0; i--) {
try {
driver = new RemoteWebDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
// If we successfully attach to appium, exit the loop.
i = 0;
} catch (UnreachableBrowserException e) {
LOGGER.info("Waiting for Appium to start");
}
}
You could add a sleep in the catch block if you wanted to poll less frequently.
I see we can improve a bit above solution.
Create Profiles for each environment ( define appium home)
you could redirect the Process output stream to a file. File name could be defined in profile are in java file.