How to run sh script from jenkins - java

I need launch sh script from jenkins, it is simple, but my script change symlink for JAVA_HOME, in fact im switching between JDK versions using sh script. It works when Im launching job without jenkins(job writen on bash), but it does not working under jenkins... Jenkins remember JAVA_HOME after start and use this path... how can I change JAVA_HOME from sh script under jenkins ? may be from script invoke jenkins reload config if it's possible... thx for any help!

Just try as below ;
public static void execShellCmd(String cmd) {
try {
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(new String[] { "/bin/bash", "-c", cmd });
int exitValue = process.waitFor();
System.out.println("exit value: " + exitValue);
BufferedReader buf = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = "";
while ((line = buf.readLine()) != null) {
System.out.println("exec response: " + line);
}
} catch (Exception e) {
System.out.println(e);
}
}
For more details : Shell Script Running with java

Problem solved!!! soulution is simple, I have sh script that was launched in jenkins job like this:
./MY_SCRIPT.sh
And after that script launched under jenkins and I had problems with switching JAVA_HOME.
All is need to do launch script like this:
sh MY_SCRIPT.sh
and it will launched smt like from the system.

Related

Shell script exit too early due to docker pull, while running through ProcessBuilder

I have the following problem which seems to be caused by the "docker pull" in my shell script, as the pull works concurrently
#!/bin/bash
#VARIABLES
NAME="my-app"
IMAGE="my-image:latest"
#DOCKER
docker stop $NAME
docker rm $NAME
docker pull -q $IMAGE
docker run --name $NAME -d -p 1234:8080 --log-opt fluentd-address=localhost:2233 $IMAGE
Running the script through the terminal works just fine everything works as expected. But when I run it with the Java's ProcessBuilder the script exits much quicker and it seems that it skips the "docker pull" step. As i am not a Java developer and I am not very well familiar with the Language I have the feeling that is something related to the multi-concurrent nature of the docker pull command and the way how the Java Process Builder executes the shell script
The Java class that runs the shell script is this
try {
Collection<Task> tasks = taskService.getProjectTasksByProjectKey(projectId);
Task findTask = findTaskByTaskId(tasks, taskId);
if (findTask.getTaskId() != null) {
ProcessBuilder pb = new ProcessBuilder(findTask.getCmdPath());
Process process = pb.start();
String output;
try (InputStream in = process.getInputStream();
InputStream err = process.getErrorStream();
OutputStream closeOnly = process.getOutputStream()) {
while (process.isAlive()) {
long skipped = in.skip(in.available())
+ err.skip(err.available());
if(skipped == 0L) {
process.waitFor(5L, TimeUnit.MILLISECONDS);
}
}
output = loadStream(in);
} finally {
process.destroy();
}
// String error = loadStream(process.getErrorStream());
// int rc = process.waitFor();
// log.debug("exit code ->>> " + rc);
// StringBuilder output = new StringBuilder();
// BufferedReader reader = new BufferedReader(
// new InputStreamReader(process.getInputStream()));
//
// String line;
//
// while ((line = reader.readLine()) != null) {
// output.append(line + "\n");
// }
//
// int exitVal = process.waitFor();
// if (exitVal == 0) {
// System.out.println(output);
//
// return output.toString();
// } else {
// //abnormal...
// }
return output;
}
else {
throw new InvalidTaskModelException(taskId);
}
} catch (InvalidModelException e) {
throw new InvalidModelException(projectId);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static String loadStream(InputStream s) throws Exception
{
BufferedReader br = new BufferedReader(new InputStreamReader(s));
StringBuilder sb = new StringBuilder();
String line;
while((line=br.readLine()) != null)
sb.append(line).append("\n");
return sb.toString();
}
The commented lines are different ways I tried to do it.
If anyone encountered a similar problem any help would be much appreciated!
It is good that you already take care for the processes' STDOUT and STDIN. But rather than skipping copy them to System.out so you can see what is going on. I suspect something is not going as per your expectations.
Looking at the bash script you posted and the fact you are trying to run several processes: Is it possible your java code is running the bash script line by line? Be aware your java program it is not a BASH interpreter, so e.g. variable substitution should not work.
why you can not run each command in thread and joins them so that unless therad 1 is not completed . next thread can not start .
also please add command to verify image is downloaded successfully
docker pull -q $IMAGE
docker images | grep $IMAGE
docker run --name $NAME -d -p 1234:8080 --log-opt fluentd-address=localhost:2233 $IMAGE
i am guessing there are 2 possiblities are here
Check local directory persmission if possible give 755 permission to
it .
Java process itself is not able to execute docker command due
to permission issue, run process as sudo user.

How to load bashrc in java program and execute command

public CGAOperationStatus downloadMetaData() {
CGAOperationStatus retCgaOperationStatus = new CGAOperationStatus();
try {
createDirectoryIfNeeded("/sure/replication/metadata");
String prepareRsyncCommand = "gsutil -m rsync -d -r gs://"
+ storeCredentials.getStoreAccount()
+ "/sure/metadata /sure/replication/metadata'";
Process p = Runtime.getRuntime().exec(prepareRsyncCommand);
p.waitFor();
} catch (Exception e) {
System.out.print("Exception in downloading metadata from GoogleBucket");
retCgaOperationStatus
.setScgaError(CGAError.SCGA_EXCEPTION_OCCURRED);
ExceptionHandler.logException(logger, e);
retCgaOperationStatus.setErrorMessage(e.getMessage());
}
return retCgaOperationStatus;
}
I have installed and Gcloud SDK on linux machine and i am trying to run gsutil command from a Jar File and my jar is executed from some outside program over ssh . But it just not working.
If i am running same command manually it works fine. May be because .bashrc is loaded when i am running command.
How can i do same thing from java.
You should use a String[] instead of a simple String as a parameter in the call to Runtime.
Runtime.getRuntime().exec(new String[]{"gsutil", "-m", "rsync", "-d", "-r", "gs://"+ storeCredentials.getStoreAccount(), "/sure/metadata /sure/replication/metadata'"});

Hide Putty terminal while running from Java

I am running the following code in Java for running a shell script in Ubuntu.
But when it is running, y=the putty terminal will be displayed. But i dont want this. How will I hide this terminal.
ProcessBuilder pb = new ProcessBuilder(winBasePath + "putty.exe", "-ssh", "-m", winBasePath + "runHiveCmd.txt", linuxSystem, "-pw", linuxPwd);
Process p = pb.start();
try {
p.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
Try this
ProcessBuilder pb =
new ProcessBuilder("cmd.exe", "/C", "START", "/MIN", winBasePath + "putty.exe", ...);
If performing a remote command via ssh, consider jsch. This provides cleaner integration does not require ProcessBuilder. Here is an example you could start with

Command line argument works in console, fails from within Runtime.getRuntime().exec

Trying to build a basic launcher for a java game. I'm building the proper command to run the application. When the following command executes in the launcher, the launcher closes as expected, but the command doesn't appear to work - either it doesn't work or the game launches and immediately crashes.
When I print this same command to the console and copy/paste it into console and execute manually, it works perfectly.
/**
*
*/
protected void launch(){
currentStatusMsg = "Launching...";
String cmd = "java -jar";
cmd += " -Djava.library.path=\"" +nativesDirectory.getAbsolutePath() + "\"";
cmd += " \""+applicationJar.getAbsolutePath() + "\"";
System.out.println(cmd);
try {
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(cmd);
//closeLauncher();
BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line=null;
while((line=input.readLine()) != null) {
System.out.println(line);
}
int exitVal = pr.waitFor();
System.out.println("Exited with error code "+exitVal);
} catch(Exception e) {
System.out.println(e.toString());
e.printStackTrace();
}
}
I tried adding something to read the output, but nothing is printed.
I was originally using the following format instead, but it has the same effect:
Process pr = Runtime.getRuntime().exec(new String[]{
"java",
"-Djava.library.path=\"" +nativesDirectory.getAbsolutePath() + "\"",
"-jar",
applicationJar.getAbsolutePath()});
Update I realized I was closing the launcher before allowing the debug code to run. The system only prints: "Exited with error code 1"
I finally was able to get the subprocess error to print. It states:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no lwjgl in java.library.path
However, it should be available because the command I'm executing includes the library path, and when this exact command is run manually, it works fine.
the java command launcher is not a shell. don't use quoting and space separated commands because it won't end well. put each argument into a separate String without any extra quoting, and use the exec(String[]) method.

Run bash scripts from JAVA and return the results

I am attempting to get output of a shell / bash script, that is run from a JAVA program, although I am not having much luck, the code is as follows:
GetStats(winhostname);
public static String winhostname "cmd /c hostname";
public static void GetStats(String operation)
{
try
{
Process p=Runtime.getRuntime().exec(operation);
p.waitFor();
BufferedReader reader=new BufferedReader(new InputStreamReader(p.getInputStream()));
String line=reader.readLine();
while(line!=null)
{
System.out.println(line);
if (operation.equals("winhostname"))
{
winhostnamevalue = line;
}
line=reader.readLine();
}
}
catch(IOException e1) {}
catch(InterruptedException e2) {}
}
This works on Windows fine, so I changed the value of winhostname to "sh namecheck.sh" (which simply echos the hostname) and the shell script is located in the same directory as the java / class file. Although when run I get a blank result, not null, just blank.
Try /bin/sh. I do not sure that when you are running program from java it has all environment that you have when you are working with shell.
If it does not work try to run some command (e.g. pwd). But provide full path. Then, when it works try your command again and be sure that it can find your script. For the beginning use absolute path. Then move to relative path.
Good luck.

Categories

Resources