Next we will create a service that wraps shell scripts. We do this in Java with Jax-WS annotations.
First create a new application
File > New > General > Applications
And a new project and name it. I added Web Services to the selected
project technologies. This added Java as well.
Create a new java
class that will launch scripts
Note: We checked the “Main Method” checkbox because we want
to also run the application from command line (or from IDE actually) during
testing and development phase.
This is the class that the wizard generated:
package
com.blogger.soanen;
public class ScriptWrapper
{
public ScriptWrapper() {
super();
}
public static void main(String[] args) {
ScriptWrapper scriptWrapper = new
ScriptWrapper();
}
}
Add java code to the
newly created Java class
Next we’ll add an execute method that wraps an existing
class “ProcessBuilder” that can be used to execute shell scripts. We also add a few return values to the class.
The end result is as this:
package
com.blogger.soanen;
import java.io.File;
import
java.io.IOException;
import
java.util.ArrayList;
import java.util.List;
public class ScriptWrapper
{
public final int IO_ERROR = -1;
public final int SCRIPT_INTERRUPTED =
-2;
public final int NULL_COMMAND_ELEMENT =
-3;
public final int EMPTY_COMMAND = -4;
public final int NOT_ALLOWED = -5;
public final int UNKNOWN_SCRIPT = -6;
public ScriptWrapper() {
super();
}
public int executeScript( String script,
String scriptDir,
String... args) {
List<String> command = new
ArrayList<String>(1+args.length);
command.add(script);
for(String arg : args)
command.add(arg);
ProcessBuilder pb = new
ProcessBuilder(command);
Process p;
pb.directory(new File(scriptDir));
try {
p = pb.start();
return p.waitFor();
} catch (IOException e) {
e.printStackTrace();
return IO_ERROR;
} catch (InterruptedException e) {
return SCRIPT_INTERRUPTED;
} catch (NullPointerException e) {
return NULL_COMMAND_ELEMENT;
}
catch (IndexOutOfBoundsException e) {
return EMPTY_COMMAND;
} catch (SecurityException e) {
return NOT_ALLOWED;
}
}
public static void main(String[] args) {
try {
ScriptWrapper scriptWrapper = new
ScriptWrapper();
int ret;
ret =
scriptWrapper.executeScript("cmd.exe", "c:\\temp",
"/c", "a.bat");
System.out.println("return
value = " + ret);
} catch (Exception e1) {
System.out.println(e1);
}
}
You can try out this program like this by selecting the Run
option from the pop-up menu:
The same run icon is visible on the top tool bar as well.
Let’s improve the program a little bit so that execute does
not take the program name but a symbolic name instead. This improves security
as only applications embedded in the wrapper class can be executed.
First create a helper class Script. Remember not to check
the main method this time.
I added
·
scriptPath – The real file name this script has
·
scriptDir – directory where the script is
executed (so a name like execDir might have been more descriptive…)
Potentially you might also want to add other fields like
·
userName
·
password
Here is the helper class:
package
com.blogger.soanen;
public class Script {
private String scriptPath;
private String scriptDir;
public Script() {
super();
}
public Script(String scriptPath,String
scriptDir) {
super();
this.scriptPath = scriptPath;
this.scriptDir = scriptDir;
}
public String getScriptPath() {
return scriptPath;
}
public void setScriptPath(String
scriptPath) {
this.scriptPath = scriptPath;
}
public String getScriptDir() {
return scriptDir;
}
public void setScriptDir(String scriptDir)
{
this.scriptDir = scriptDir;
}
}
Let’s add some code to the ShellScriptWrapper to have a Map
to store the relationship between the name of the script and the Script class
that contains the actual script file and directory to use as home dir when the
script is executed.
private
Map<String,Script> scripts = new HashMap<String,Script>();
We’ll also change the execute method slightly to read the
script name and directly from a Script class instead from the call parameters;
we can also remove the scriptDir parameter from the call.
The final program is like this:
package
com.blogger.soanen;
import java.io.File;
import
java.io.IOException;
import
java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ScriptWrapper
{
public final int IO_ERROR = -1;
public final int SCRIPT_INTERRUPTED = -2;
public final int NULL_COMMAND_ELEMENT = -3;
public final int EMPTY_COMMAND = -4;
public final int NOT_ALLOWED = -5;
public final int UNKNOWN_SCRIPT = -6;
private Map<String, Script> scripts =
new HashMap<String, Script>();
public ScriptWrapper() {
super();
scripts.put("a.bat", new
Script("C:\\TEMP\\a.bat", "C:\\TEMP"));
}
public int executeScript(String script, String...
args) {
Script s = scripts.get(script);
if (s != null) {
List<String> command = new
ArrayList<String>(1 + args.length);
command.add(s.getScriptPath());
for (String arg : args)
command.add(arg);
ProcessBuilder pb = new
ProcessBuilder(command);
Process p;
pb.directory(new
File(s.getScriptDir()));
try {
p = pb.start();
return p.waitFor();
} catch (IOException e) {
e.printStackTrace();
return IO_ERROR;
} catch (InterruptedException e) {
return SCRIPT_INTERRUPTED;
} catch (NullPointerException e) {
return NULL_COMMAND_ELEMENT;
} catch (IndexOutOfBoundsException
e) {
return EMPTY_COMMAND;
} catch (SecurityException e) {
return NOT_ALLOWED;
}
} else
return UNKNOWN_SCRIPT;
}
public static void main(String[] args) {
try {
ScriptWrapper scriptWrapper = new
ScriptWrapper();
int ret;
//ret =
scriptWrapper.executeScript("cmd.exe", "c:\\temp",
"/c", "a.bat");
ret =
scriptWrapper.executeScript("a.bat", "");
System.out.println("return
value = " + ret);
} catch (Exception e1) {
System.out.println(e1);
}
}
}
Hi there martti ylikoski,
VastaaPoistaFirst let me congratulate you for the great job doing this tutorials. It's helping me a lot.
I want to ask you if you have any idea how I can execute this script on Linux Gnome?
Thank you,
João
It is 2 years to late, but if one uses a LINUX all one needs to do is this:
VastaaPoista1. create at some locatin .sh file
touch test.sh
chmod +x test.sh
2. open the newly created file and add some SHELL script:
-------like this example------
#!/bin/sh
echo "TEST.......some file content" > /home/oracle/jdeveloper/mywork/ScriptWrapper/ScriptWraPPER/src/com/blogger/soanen/created_new_file.txt
echo "TEST2.... some file content" | tee second_created_new_file.txt
3. In the script provided by Martti edit the name of the script, the path to script and the path to directory where script is:
public ScriptWrapper() {
super();
scripts.put("test.sh", new Script("/home/oracle/jdeveloper/mywork/ScriptWrapper/ScriptWraPPER/src/com/blogger/soanen/test.sh", "/home/oracle/jdeveloper/mywork/ScriptWrapper/ScriptWraPPER/src/com/blogger/soanen"));
}
4. In the main methode edit the folowing line:
ret = scriptWrapper.executeScript("test.sh", "");
I hope it helped someone
It is 2 years to late, but if one uses a LINUX all one needs to do is this:
VastaaPoista1. create at some locatin .sh file
touch test.sh
chmod +x test.sh
2. open the newly created file and add some SHELL script:
-------like this example------
#!/bin/sh
echo "TEST.......some file content" > /home/oracle/jdeveloper/mywork/ScriptWrapper/ScriptWraPPER/src/com/blogger/soanen/created_new_file.txt
echo "TEST2.... some file content" | tee second_created_new_file.txt
3. In the script provided by Martti edit the name of the script, the path to script and the path to directory where script is:
public ScriptWrapper() {
super();
scripts.put("test.sh", new Script("/home/oracle/jdeveloper/mywork/ScriptWrapper/ScriptWraPPER/src/com/blogger/soanen/test.sh", "/home/oracle/jdeveloper/mywork/ScriptWrapper/ScriptWraPPER/src/com/blogger/soanen"));
}
4. In the main methode edit the folowing line:
ret = scriptWrapper.executeScript("test.sh", "");
I hope it helped someone