How to run NPM Command in Java using Process Builder - java

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
public class TestUnZip {
public static void main(String[] args) throws IOException, InterruptedException{
String destFolder="E:\\TestScript";
/*
* Location where the Nodejs Project is Present
*/
System.out.println(destFolder);
String cmdPrompt="cmd";
String path="/c";
String npmUpdate="npm update";
String npm="npm";
String update="update";
File jsFile=new File(destFolder);
List<String> updateCommand=new ArrayList<String>();
updateCommand.add(cmdPrompt);
updateCommand.add(path);
updateCommand.add(npmUpdate);
runExecution(updateCommand,jsFile);
}
public static void runExecution(List<String> command, File navigatePath) throws IOException, InterruptedException{
System.out.println(command);
ProcessBuilder executeProcess=new ProcessBuilder(command);
executeProcess.directory(navigatePath);
Process resultExecution=executeProcess.start();
BufferedReader br=new BufferedReader(new InputStreamReader(resultExecution.getInputStream()));
StringBuffer sb=new StringBuffer();
String line;
while((line=br.readLine())!=null){
sb.append(line+System.getProperty("line.separator"));
}
br.close();
int resultStatust=resultExecution.waitFor();
System.out.println("Result of Execution"+(resultStatust==0?"\tSuccess":"\tFailure"));
}
}
The Above Program works fine, but this program is depend on Windows Machine, I want to run the same program in other Machine as well.
1) NPM is a Command comes as a bundle of NodeJS. (I run NodeJS as a service, I have defined the Environment Variable, so I can run npm update command from any folder)
2) I can't find a work around to run the npm update command without using the "cmd", "/c". If I do I get following error
Exception in thread "main" java.io.IOException: Cannot run program "npm update" (in directory "E:\TestScript"): CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessBuilder.start(Unknown Source)
3) Do we have option of Running the npm update command as a parameter of Node.exe. If so can anyone provide me the proper work around.
4) Same as I like, I use mocha framework to run the test script and result generates the .xml file.
5) I want mocha command also being invoked using process builder.

The problem is that ProcessBuilder does not respect the PATHEXT variable on Windows.
It's true there is no npm binary on Windows, there's a npm.cmd. My best solution is to check the platform. Something like this:
static boolean isWindows() {
return System.getProperty("os.name").toLowerCase().contains("win");
}
static String npm = isWindows() ? "npm.cmd" : "npm";
static void run() {
Process process = new ProcessBuilder(npm, "update")
.directory(navigatePath)
.start()
}

In Unix or Linux os , the PathBuilder takes the default environment path , so we have to change the environment path and run the npm command through the bash.
import java.io.File;
import java.util.Map;
public class CommandExecutor {
public void exceuteCommand(String commandString,String
directoryToExecuteCommand) {
try {
ProcessBuilder processBuilder = new ProcessBuilder(new String{"bash", "-c",commandString});
Map<String, String> env = processBuilder.environment();
processBuilder.directory(new File(directoryToExecuteCommand));
String envPath="/home/admin123/.nvm/versions/node/v10.15.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin";
env.put("PATH",envPath);
processBuilder.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String args[]) {
CommandExecutor commandExecutor=new CommandExecutor();
commandExecutor.exceuteCommand("npm install", "/home/admin123/Desktop");
}
}

Related

Command not running in Spring-Boot application

I created a simplest Spring-Boot application to test running command, see the completed code below, after click Run 'Application' in InteliJ, console ends up with Process finished with exit code 0, no directory structures in console display.
Run dir c: in terminal returns all the files and directories, seems Process process = Runtime.getRuntime().exec("cmd /c dir C:"); does not run at all.
I put process = Runtime.getRuntime().exec("dir C:");, running application again, this time console output ends up with java.io.IOException: CreateProcess error=2, apparently Java runtime recognized command as invalid.
Why Process process = Runtime.getRuntime().exec("cmd /c dir C:"); does not return any result?
package
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
#SpringBootApplication
public class Application {
public static void main(String[] args) { SpringApplication.run(Application.class); }
#Bean
public CommandLineRunner CommandLineRunnerBean() {
return (args) -> {
Process process = Runtime.getRuntime().exec("cmd /c dir C:");
// process = Runtime.getRuntime().exec("dir C:");
}
}
}
First, code that you posted doesn't compile.
When you write this line of code:
Process process = Runtime.getRuntime().exec("cmd /c dir C:");
Process is executed, but you need to write code that will display result of this process in console.
You can get result of process by calling :
process.getInputStream()
getInputStream() method gets the input stream of the subprocess. The stream obtains data piped from the standard output stream of the process represented by Process object.
Third, to display all directories in C drive, you should use this path:
Process process = Runtime.getRuntime().exec(String.format("cmd /c dir %s", "C:\\"));
To summarize, if you want to see all directories in your C: drive, first you will need to create a class which will used to output result of process to java console as I mentioned above.
Let's call that class HelperReader.
Here is the code:
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.function.Consumer;
public class HelperReader implements Runnable {
private InputStream inputStream;
private Consumer<String> consumer;
public HelperReader(InputStream inputStream, Consumer<String> consumer) {
this.inputStream = inputStream;
this.consumer = consumer;
}
#Override
public void run() {
new BufferedReader(new InputStreamReader(inputStream)).lines()
.forEach(consumer);
}
}
Change code in your Application class to something like this:
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.concurrent.Executors;
#SpringBootApplication
public class Application implements CommandLineRunner {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
#Override
public void run(String... args) throws Exception {
Process process = Runtime.getRuntime().exec(String.format("cmd /c dir %s", "C:\\"));
HelperReader streamGobbler =
new HelperReader(process.getInputStream(), System.out::println);
Executors.newSingleThreadExecutor().submit(streamGobbler);
}
}
Run the application and you should see something like following picture in console.

How to Invoke "Powershell script file" from Java in Linux operating system

Class:-
=====================
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class TestPowershell {
public static void main(String[] args) throws IOException
{
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("cmd powershell \"\\Test\\Powershell\\powershell.ps1\" ");
proc.getOutputStream().close();
InputStream is = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isr);
String line;
while ((line = reader.readLine()) != null)
{
System.out.println(line);
}
reader.close();
proc.getOutputStream().close();
}
}
I am trying to execute a powershell file by using java in linux environment , i am getting exceptions (above i attached class and exceptions), kindly provide me a test class which can execute powershell script file in linux. Thanks in advance
1st download the FreeSSHD http://www.freesshd.com/?ctt=download in your windows(server). make sure run it as Administrator.
for setup FreeSSHD follow this URL http://www.techrepublic.com/blog/tr-dojo/set-up-a-free-ssh-server-on-windows-7-with-freesshd/ after setup you can ssh that windows system from linux or using putty.
to execute powershell script from linux to remote windows system using java
package com.sysvana.router.config;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
public class Test {
static String hostname = "10.1.10.60";
static String username = "administrator";
static String password = "P#ssw0rd";
public static void main(String[] args) throws IOException {
Connection conn = new Connection(hostname);
conn.connect();
boolean isAuthenticated = conn.authenticateWithPassword (username, password);
if (isAuthenticated == false){
System.out.println("authentication failed");
}
System.out.println(isAuthenticated);
Session sess = conn.openSession ();
sess.execCommand ("powershell C:/Users/Administrator/Desktop/test.ps1");
InputStream stdout = new StreamGobbler (sess.getStdout ());
BufferedReader br = new BufferedReader (new InputStreamReader (stdout));
while (true)
{
String line = br.readLine ();
if (line == null) break;
System.out.println (line);
}
System.out.println ("Exit code" + sess.getExitStatus ());
sess.close ();
conn.close ();
}
}
use Ganymed SSH-2 jar http://www.ganymed.ethz.ch/ssh2/
Your problem is that you're not actually trying to run PowerShell. You're using this:
runtime.exec("cmd powershell \"\\Test\\Powershell\\powershell.ps1\" ")
which means it's trying to run a file called cmd, which is not part of Linux.
Also, in another part of the code, you're trying to run powershell.exe. Typically, Linux programs don't have a .exe extension. You may have ported your Java application from Windows, but you need to be aware that Linux is different. It doesn't come with Powershell as standard, and doesn't use .exe file extension.
You can install PowerShell at https://github.com/PowerShell/PowerShell.
On Linux, PowerShell (once installed from the above) is invoked with the pwsh command. You will need to change your Java program accordingly.
Thanks for all your answers.
Finally, I got to know while working with PowerShell we should run the script in windows OS only because Microsoft is the owner for PowerShell and they give more features in Windows OS.
what I did is, I ran the script in Windows OS & generated a CSV file and kept in SFTP folder, by using java I loaded my file and processed my next process.

How to execute FreeSwitch command using java code

I am new to freeswitch, I have tried originate command in freeswitch from fs_cli console and it was working properly. now my requirement is to execute the same from a java application. I have tried following code.
package org.freeswitch.esl.client.outbound.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class Call {
Call() throws IOException {
Process pr = Runtime.getRuntime().exec("fs_cli -x reloadxml");
BufferedReader br = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String str = null;
while ((str = br.readLine()) != null) {
System.out.println(str);
}
System.out.print("success");
}
public static void main(String[] args) throws IOException {
Call call;
call = new Call();
}
}
You should use mod_esl.
There are java examples in conlfluence.
Also, I made example for spring boot + netty (for outbound mode)
Above problem get resolved :
I have created a .sh script with the bellow code snippet:
#!/bin/bash
fs_cli -x "reloadxml"
echo "executed at : $(date)" >> /var/tmp/testlog.txt
and execute this .sh file using java code. That's it.
I have created a testlog.txt file to check weather the fs_cli -x "reloadxml" command is executed or not.

How to change the path in command prompt using java

import java.io.Console;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.Executor;
import com.jacob.com.LibraryLoader;
import autoitx4java.AutoItX;
public class SilentInstallation {
public static void main(String[] args) throws IOException, InterruptedException {
String[] cmd = { "C:\\WINDOWS\\system32\\cmd.exe", "/c", "start" };
try {
Runtime runtime = Runtime.getRuntime();
Process p = runtime.exec(cmd);
}
catch (java.io.IOException exception) {
System.out.println("Caught IOException: " + exception.getMessage());
}
}
}
Here is my code in which I am running command prompt using java. But the problem here I am facing is I can't be able to change the path in command prompt using java code.
Since this code is using in Automation, so is there any command or method in java that can be used to change the path in the command prompt.
I have also used ProcessBuilder to change the directory path.
Any Recommendations.....
This should be enough:
Process p = ...
p.getOutputStream().write("cd d:\\/r/n".getBytes());

Write an executable .sh file with Java for OSX

So I am trying to write an .sh file that will be executable, this is how I'm currently writing it:
Writer output = null;
try {
output = new BufferedWriter(new FileWriter(file2));
output.write(shellScriptContent);
output.close();
} catch (IOException ex) {
Logger.getLogger(PunchGUI.class.getName()).log(Level.SEVERE, null, ex);
}
So that writes the file just fine, but it is not executable. Is there a way to change the executable status when I write it?
Edit: To further clarify, I am trying to make it execute by default, so that for instance, if you double clicked the generated file, it would automatically execute.
You can call File.setExecutable() to set the owner's executable bit for the file, which might be sufficient for your case. Or you can just chmod it yourself with a system call with Process.
Alas, full-powered programmatic alteration of file permissions isn't available until Java 7. It'll be part of the New IO feature set, which you can read more about here.
You'd need to chmod it, and you can probably do it by exec'ing a system command like such:
Really all you'd need is to fire off something like this:
Runtime.getRuntime().exec("chmod u+x "+FILENAME);
But if you want to keep track of it more explicitly can capture stdin / stderr then something more like:
Process p = Runtime.getRuntime().exec("chmod u+x "+FILENAME);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
Which I got from here:
http://www.devdaily.com/java/edu/pj/pj010016/pj010016.shtml
Update:
Test program:
package junk;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class Main{
private String scriptContent = '#!/bin/bash \n echo "yeah toast!" > /tmp/toast.txt';
public void doIt(){
try{
Writer output = new BufferedWriter(new FileWriter("/tmp/toast.sh"));
output.write(scriptContent);
output.close();
Runtime.getRuntime().exec("chmod u+x /tmp/toast.sh");
}catch (IOException ex){}
}
public static void main(String[] args){
Main m = new Main();
m.doIt();
}
}
On linux if you open up a file browser and double click on /tmp/toast.sh and choose to run it, it should generate a text file /tmp/toast.txt with the words 'yeah toast'. I assume Mac would do the same since it's BSD under the hood.
In Java 7 you can call Files.setPosixFilePermissions. Here is an example:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
import java.util.Set;
class FilePermissionExample {
public static void main(String[] args) throws IOException {
final Path filepath = Paths.get("path", "to", "file.txt");
final Set<PosixFilePermission> permissions = Files.getPosixFilePermissions(filepath);
permissions.add(PosixFilePermission.OWNER_EXECUTE);
Files.setPosixFilePermissions(filepath, permissions);
}
}
On Mac OS X, besides chmod +x, you have to give a .command extension to your shell script if you want to launch it with a double-click.
This answer I wrote for the question how do I programmatically change file permissions shows a chmod example via a native call using jna, which should work on Mac OS X.

Categories