Launching and stopping appium server programmtically

Hi,

Is there a way to launch/stop the appium server programmatically?

Also is there way where can capture all the logs of appium server in a log file?

Thanks and regards,
M.Karthik

7 Likes

[Update] For a complete updated guide with code example, please refer to this.

@karthik_holla
I am gonna use Java and Windows to help explain that to you, you can use the equivalent of that in your preferred language/OS:

  • To start Appium server programmatically, you need the following:
    1. Command executor tool (I prefer the second approach as it will handle most of the OS specific problems on your behalf):
    1. Tell the tool what program you need to start. This is OS dependent and differs from OS version to another in some cases. You can use the next table to find the one matching your environment.
    • Windows: cmd /c
    • Linux: /bin/env
    • Mac: /bin/sh
    1. Invoke the NodeJS server and pass the arguments it needs to start the server. You can do that using the following command (Replace C:/Program Files (x86) with the path to your Appium installation folder):

“C:/Program Files (x86)/Appium/node.exe” “C:/Program Files (x86)/Appium/node_modules/appium/bin/Appium.js”

  1. The last step is to provide the Appium server arguments as normal.

Putting all that together, you formulate a command like:

cmd /c “C:/Program Files (x86)/Appium/node.exe” “C:/Program Files (x86)/Appium/node_modules/appium/bin/Appium.js” --address 127.0.0.1 --chromedriver-port 9516 --bootstrap-port 4725 --selendroid-port 8082 --no-reset --local-timezone

To execute that command using Apache Commons Exec:

DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
Executor executor = new DefaultExecutor();
executor.setExitValue(1);
executor.execute(new CommandLine(“The command you just formulated above”), resultHandler);

I am not sure if it’s the best approach, but it works just fine with me. @bootstraponline @jlipps Can you please confirm if this is the best approach?


  • To stop Appium server, just replace step 3 above by:

    • Windows: taskkill /F /IM node.exe
    • Linux: killall node
    • Mac: killall node

Note: In case of starting more than one server instance on the same machine, you have to replace the killall command to prevent killing the server of the first instance after staring a second one. Sadly I hit a dead-end in this part (I am currently leaving the server instances opened and I close them manually after the test is done until I find a better approach to killing the server in a more smart way).


  • To capture all Appium log messages in a file, add the following flag to your Appium server arguments:

–log “log-file-path”

Hope this helps. Just ask if anything is not clear :smile:

7 Likes

@Hassan_Radi
Thank for such an elaborate explanation. However i am new to Appium so have some tough time trying to understand what needs to be done.

Can you please suggest what needs to be passed as parameters to executor.execute(new CommandLine(“The command you just formulated above”), resultHandler);

Also can you please explain the command which is to be executed?

cmd /c -->to start the command prompt
“C:/Program Files (x86)/Appium/node.exe”–>to start the node exe
“C:/Program Files (x86)/Appium/node_modules/appium/bin/Appium.js” --address 127.0.0.1 --chromedriver-port 9516 --bootstrap-port 4725 --selendroid-port 8082 --no-reset --local-timezone–>more explanation on this would be really helpful.

i am using java and executing the scripts on windows 7.

thanks in advance,
Karthik

@karthik_holla
This is responsible for starting the Appium server:

This represents the Appium server arguments. You use whatever you want to start the server with (I was just giving you an example of how to do it).

To create the CommandLine object from the command, do that:

CommandLine command = new CommandLine();
command.addArgument(“cmd);
command.addArgument(”\c");
command.addArgument(“"C:/Program Files (x86)/Appium/node.exe"”);
command.addArgument(“"C:/Program Files (x86)/Appium/node_modules/appium/bin/Appium.js"”);
commadn.addArgument(“–address”);

Keep passing all the parameters as above. Keep in mind that you add a new argument for each space separated part of the command.

@Hassan_Radi,

thank you for explaining things. I was able to launch appium server. It even got connected to the device. But, failed while launching the appium driver with the error “Cannot bind to socket”. Below is the code snippet which launches the appium server.

System.out.println(“driver being created…”);
CommandLine command = new CommandLine(“cmd”);
//command.addArgument(“cmd”);
command.addArgument("/c");
command.addArgument(“C:\Users\mkarthik\Documents\selenium\Appium\node.exe”);
command.addArgument(“C:\Users\mkarthik\Documents\selenium\Appium\node_modules\appium\bin\appium.js\”);
command.addArgument("–address");
command.addArgument(“127.0.0.1”);
command.addArgument("–bootstrap-port");
command.addArgument(“4242”);
command.addArgument("–no-reset");
command.addArgument("–log");
command.addArgument(“C:\Users\mkarthik\workspace\Android\AppiumMobileAutomation\src\com\log\appiumLogs.txt”);
resultHandler = new DefaultExecuteResultHandler();
executor = new DefaultExecutor();
executor.setExitValue(1);
executor.execute(command, resultHandler);

Please can you advice what needs to overcome this failure. Also i am unable to see anything getting stored in logs.
i have attached the appium server logs.

appium server logs.txt (7.1 KB)

Hi @Hassan_Radi,

i was able to execute the script by launching the server programmatically.

Just a question: when i changed command.addArgument(“4244”); to command.addArgument(“4724”); it worked.

sbootstrap-port would always refer to the device port where appium server forwards the command?

please help as it would make things much clearer to understand.

Thanks and regards,
M.Karthik

As the Appium documentation mentions,

–bootstrap-port : port to use on device to talk to Appium server

I never change the bootstrap-port, changing it and acting in this way might be a bug in Appium. @bootstraponline @jlipps Is that a bug??

As of the other problem you mentioned, that nothing is stored in the logs: I took a look at the log you provided and I can see that Appium logs are present and I quote:

e[36minfoe[39m: Welcome to Appium v1.2.0 (REV e53f49c706a25242e66d36685c268b599cc18da5)
e[90mdebuge[39m: Non-default server args: {“address”:“127.0.0.1”,“bootstrapPort”:4242,“noReset”:true,“log”:“C:\Users\mkarthik\workspace\Android\AppiumMobileAutomation\src\com\log\appiumLogs.txt”}
e[36minfoe[39m: Appium REST http interface listener started on 127.0.0.1:4723
e[36minfoe[39m: LogLevel: debug

1 Like

Thanks for providing this useful info, helped me a lot.

This is what worked for me…
CommandLine command = new CommandLine(“cmd”);
command.addArgument("/c");
command.addArgument(“C://Users//…//Appium//node.exe”);
command.addArgument(“C://Users//…//Appium//node_modules//appium//bin//appium.js”);
command.addArgument("–address");
command.addArgument(“0.0.0.0”);
command.addArgument("–port");
command.addArgument(“4724”);
command.addArgument("–no-reset");
command.addArgument("–log");
command.addArgument(“C://Users//…//log//appiumLogs.txt”);
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
DefaultExecutor executor = new DefaultExecutor();
executor.setExitValue(1);
executor.execute(command, resultHandler);

1 Like

How do we stop the server and free the port in the end?

As I mentioned in the main post:

You will end up with something like this:

CommandLine command = new CommandLine(“cmd”);
command.addArgument(“/c”);
command.addArgument(“taskkill”);
command.addArgument(“/F”);
command.addArgument(“/IM”);
command.addArgument(“node.exe”);

This does not work for me.

When i try to re-run the test, I see the error:
e[31merrore[39m: Couldn’t start Appium REST http interface listener. Requested port is already in use. Please make sure there’s no other instance of Appium running already.

I have to manually kill the process from Windows Task Manager and the re-run the test.

1 Like

It works just fine with me … Are you sure you are not doing something wrong??

Hey, Guys

I use processBuilder for that. It has method destroy().
You could check my example in the thread:

1 Like

I thought about using it at first, but it turned out that it doesn’t destroy any spawned processes started by your application. You will end up with memory leaks and probably some errors when you try to open it again.

It perfectly closes child processes. As you can see, there is a process tree and when cmd.exe (with PID 6320) get closed - all child processes get closed as well

As I understood from the image you shared, you are starting a new JVM inside the original one. That’s why when you call the destroy function, the Java process and all of its child processes are destroyed. In my case, I was starting the Appium server from the original JVM which means that all of its spawned processes won’t be destroyed until the original Java JVM terminates.

P.S: I am running more than one server instance simultaneously and I can’t wait to clear up memory at the end when the JVM terminates.

Parent java process from the screenshot above - is IDE:-)
Just test run via “mvn test” command-line and got the same result: all processes closed perfectly!

Looks like it’s working :smile: with the destry method and there is no need to taskill the process … I am not sure why it wasn’t working with me when I tried it?
Anyway, I will give it another try. Thanks :smile:

Hi Everyone,

When I tried to launch the server, I am geeting this below error:
" /Applications/Appium.app/Contents/Resources/node/bin/node: cannot execute binary file "

My code is this, Can anyone please help on this ?
CommandLine command = new CommandLine("/bin/sh");
command.addArgument("/Applications/Appium.app/Contents/Resources/node/bin/node");
command.addArgument("/Applications/Appium.app/Contents/Resources/node_modules/appium/bin/appium.js");
command.addArgument("–address");
command.addArgument(“127.0.0.1”);
command.addArgument("–port");
command.addArgument(“4723”);
command.addArgument("–no-reset");
command.addArgument("–log");
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
DefaultExecutor executor = new DefaultExecutor();
executor.setExitValue(1);

Thanks in advance.

Try using

command.addArgument(“argument”, false);