Rsync command not working in java - java

The following commands works directly:
rsync -rtuc --delete-after --exclude '.git*' --filter 'protect .git/**/*' ~/some/source/ ~/some/destination/
But when run via java:
private Boolean syncFiles() {
// Success flag default to true
Boolean success = true;
// Attempt sync repo
try {
ProcessBuilder runtimeProcessBuilder = new ProcessBuilder().inheritIO().command(new String[]{
"rsync", "-rtuc","--delete-after", "--exclude", "'.git*'", "--filter", "'protect .git/**/*'", "~/some/source/", "~/some/destination/"
});
// Wait until process terminates
int output = runtimeProcessBuilder.start().waitFor();
// Determine if successful
if (output == 0) {
System.out.println("Backup of " + getSource() + " to " + getDestination()
+ " was successful");
} else {
System.out.println("Error: rsync returned error code: " + output);
success = false;
}
} catch (Exception ex) {
success = false;
System.out.println("Error:");
System.out.println(ex.getMessage());
Logger.getLogger(Rsync.class.getName()).log(Level.SEVERE, null, ex);
}
return success;
}
I get the error:
Unknown filter rule: `'protect .git/**/*'' Error: rsync returned error
code: 1 rsync error: syntax or usage error (code 1) at exclude.c(902)
[client=3.1.2]

The shell handles quoting before passing the parameters to the command.
The comes into play with this part of your command line:
'protect .git/**/*'
The shell interprets this as the single parameter:
protect .git/**/*
If the single quotes had not been there in the first place, the shell would have:
interpreted it as two parameters (because of the space)
expanded glob characters like "*"
The solution is to pass:
"protect .git/**/"
as one of your Java parameters, rather than "'protect .git/**/*'".
You may have similar problems with ~, which the shell will expand to your home directory.

The answer to the solution is as follows:
The ProcessBuilder object needs to be initialised as follows:
ProcessBuilder runtimeProcessBuilder = new ProcessBuilder().inheritIO().command(new String[]{
"rsync", "-rtuc","--delete-after", "--filter", "protect .git", "--exclude", "'.git*'", "~/some/source/", "~/some/destination/"
});

Related

RServe: control pipe to master process is closed/broken

I have this R script:
palindrome <- function(p) {
for(i in 1:floor(nchar(p)/2) ) {
r <- nchar(p) - i + 1
if ( substr(p, i, i) != substr(p, r, r) ) return(FALSE)
}
return(TRUE)
}
that I am calling from Java using the following code:
connection.serverSource("C:\\Users\\x\\Desktop\\R Script\\Palindrome.R");
the connection is of type RConnection is created as follows:
public void startConnection() {
PATH_TO_R = SystemUtils.IS_OS_UNIX ? "R" : "C:\\Program Files\\R\\R-3.6.1\\bin\\x64\\R.exe";
try {
String cmd = PATH_TO_R + " -e " + "\"library(Rserve);Rserve(port=" + 6311+ ")\"";
Runtime.getRuntime().exec(cmd);
RConnection connection = new RConnection("localhost", 6311);
} catch (IOException | RserveException e) {
e.printStackTrace();
}
}
The problem is I am having this error thrown and have no idea how to fix it:
org.rosuda.REngine.Rserve.RserveException: serverSource failed, request status: control pipe to master process is closed/broken
any help will be much appreciated!
The function serverSource (just like serverEval and serverShutdown) directly works on the main R+Rserve process, this feature is off by default. You can enable it in /etc/Rserv.conf adding the line control enabled (config reference).
If you don't already use an Rserve config file, you can simply create it in the default location /etc/Rserv.conf (linux/macOS) or create it anywhere (also windows) and pass the location as parameter when starting Rserve: R CMD Rserve --RS-conf <your path here> (command line arguments at the bottom of the page).

Process does not exit when launched from Java

I am launching WebTorrent-CLI from within my Java application as a separate process. I am using zt-exec for managing the process. When WebTorrent is launched with the following command, it is supposed to exit after the file at given index (value of --select) has been downloaded.
"D:\downloadmanager\node\webtorrent.cmd" download "magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&dn=Sintel" --select 0 --out "D://nf/"
As expected, webtorrent-cli does exit after downloading 0th file when the command above is used to launch it from command line. But when I try the same from within my Java app, it completely ignores the --select option and continues downloading other files in the torrent.
Basically, when launched as a process from Java, webtorrent ignores all the options set (--select, --out or whatever). I should mention that there is nothing wrong with the library because recently I've tried replacing it with commons-exec and that solved nothing. Also, to make sure that the right command is passed while starting the process, I'm printing the command right before calling executor.start(). The command above is copied from the output retrieved from printing the command before the process starts.
This is how the process is started:
#Override
public synchronized void start() throws IOException {
if (mWasDownloadStarted || mWasDownloadFinished) return;
mExec.getCommand().listIterator().forEachRemaining(s -> {
System.out.print(s + " ");
});
mExec.start();
setProcessId();
mWasDownloadStarted = true;
mWasDownloadStopped = false;
}
This is how the command is prepared:
private String buildCommand() {
List <String> command = new ArrayList<>();
command.add("\"" + mManager.mWTLocation + "\"");
command.add("download");
command.add("\"" + mManager.mMagnetUrl + "\"");
if (mManager.mFileIndex >= 0) {
command.add("--select " + mManager.mFileIndex);
}
if (mManager.mSaveTo != null) {
command.add("--out \"" + mManager.mSaveTo + "\"");
}
mManager.mExec.command(command);
String cmdStr = "";
for (String s : command) {
cmdStr = cmdStr.concat(s + " ");
}
return cmdStr.trim();
}
What might be wrong?
Okay, so I was able to fix this issue.
The / character following the path specified as value of --out was causing the problem. In order to fix this, I added a line in node_modules/webtorrent-cli/bin/cmd.js to print the arguments passed to webtorrent:
console.log(process.argv)
With the /, output of this line was something like the following:
[ 'D:\\downloadmanager\\node\\node.exe',
'D:\\downloadmanager\\node\\node_modules\\webtorrent-cli\\bin\\cmd.js',
'download',
'magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&dn=Sintel',
'--select',
'0',
'--out',
'D:\\nf"' ]
Note the " that is included in the path after D:\\nf. When / is removed from the path, the quote disappears and webtorrent behaves as expected.
I doubt that this is a bug in webtorrent. I think zt-exec (or maybe I) was doing something stupid.
Somewhat unrelated, but I think I should also mention that I had to enclose every value for each option with quotes, even the index, to get rid of other nasty errors (e.g.: Error 87, the parameter is incorrect)

Java Bukkit/Spigot - Block Specified Commands

i'm trying to make a plugin, it must block a specified commands setted by config. i've maked this but it doesn't block any command.
Code:
#EventHandler(priority = EventPriority.HIGHEST)
public void onPreprocess(PlayerCommandPreprocessEvent event)
{
Player player = event.getPlayer();
String command = event.getMessage();
List<String> bCmds = this.plugin.cfg.getStringList("blocked-commands");
for (String bCmd : bCmds)
{
if(command.equalsIgnoreCase(bCmd))
{
event.setCancelled(true);
}
}
}
Config:
blocked-commands:
- /pl
- /op
- /sp
- /gravityblock
PS: I've tried to use:
String command = event.getMessage().subString(1);
Thanks for Help... :)
Registered events? implemented listner?
Also your code will not work with additional arguments in the command.
If it contains spaces, split it with " " and get the first element to just get the command
if (cmd.contains(" ")) cmd = cmd.split(" ")[0];
As stated by Bukkit's wiiki, the priorities are called in the following order:
EventPriority.LOWEST
EventPriority.LOW
EventPriority.NORMAL
EventPriority.HIGH
EventPriority.HIGHEST
EventPriority.MONITOR
Maybe you could try to use the Lowest priority, so the event gets cancelled before the command is handled.
I also believe that the command might have arguments, so it might not be equal to the string provided, you should also try
String command = event.getMessage();
if (command.toLowerCase().startsWith("/command") ) {
//cancel
}

Having Java call an Applescript file with arguments

I have a Java program that calls an Applescript file to run, and returns information back to Java. However, I need to also pass some arguments to the Applescript file. The relevant portion of the Java file:
public static void scriptRunner(String[] args) {
// Connect to the database.
ConnectionManager.getInstance().setDBType(DBType.MYSQL);
// Prepare the AppleScript file to be executed.
String homeFolder = System.getenv("HOME");
File scriptFile = new File(homeFolder + "/Documents/Output--Test.applescript");
InputStream scriptStream = null;
try {
scriptStream = FileUtils.openInputStream(scriptFile);
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "Could not find the Output AppleScript file. Please notify Chris McGee", "File not found", JOptionPane.ERROR_MESSAGE);
ConnectionManager.getInstance().close();
System.exit(1);
}
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(scriptStream));
// These two lines prepare the scripting engine, ready to run the script.
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("AppleScript");
// Add the parameters to the engine so they will be passed to the script.
engine.put("javaOrderNum", args[0]);
engine.put("javaShipDate", args[1]);
engine.put("javaInitials", args[2]);
engine.put("javaOverruns", args[3]);
// Run the script and evaluate the result.
log.trace("Run the script and evaluate the result.");
Object result = null;
try {
result = engine.eval(bufferedReader); // Run the script and place the result into an abstract object.
} catch (ScriptException e) {
JOptionPane.showMessageDialog(null, "Either an error occurred with the Output script or the user cancelled it.", "Script error / cancel", JOptionPane.INFORMATION_MESSAGE);
ConnectionManager.getInstance().close();
System.exit(1);
}
log.debug(result); // Check that we received the correct information back from the script.
log.debug("");
.
.
.
Sadly, the engine.put lines, as suggested from a forum I read during my searches to get this problem solved, don't seem to work. The AppleScript file:
-- Get variables passed in
set jOrderNum to item 1 of arguments
set jShipDate to item 2 of arguments
set jInitials to item 3 of arguments
set jOverruns to item 4 of arguments
-- Set the correct folder variable
if (folderExists(POSIX path of "/Volumes/Users/Scripts/")) then
set server_prefix to "/Volumes/Users/Scripts/"
else if (folderExists(POSIX path of "/centralserver/Users/Scripts/")) then
set server_prefix to "/centralserver/Users/Scripts/"
else
display alert "Please connect to the central server, then try again.
If you have already done so, please let Chris McGee know."
end if
with timeout of (30 * 60) seconds
tell application "Adobe InDesign CS6"
set myJavaScript to server_prefix & "sky-artdept/Test/Output.jsx"
set myResult to do script myJavaScript with arguments {jOrderNum, jShipDate, jInitials, jOverruns} language javascript
return myResult
end tell
end timeout
on folderExists(posixPath)
return ((do shell script "if test -e " & quoted form of posixPath & "; then
echo 1;
else
echo 0;
fi") as integer) as boolean
end folderExists
I am given an error that the variable arguments is not defined. What can I try next?
I can't help with the javascript running the applescript. But, you applescript code is missing a declaration. You're asking for "item 1 of arguments" but you never define the variable arguments.
When the script is not inside any handler, it is implicit that it is inside a run() handler. And, since you're needing to pass arguments on run, you should try wrapping your script, minus the on folderExists() handler, inside a run handler that includes the arguments declaration.
on run(arguments)
-- Get variables passed in
set jOrderNum to item 1 of arguments
set jShipDate to item 2 of arguments
…
end timeout
end run
on folderExists(posixPath)
…
end folderExists

Execute jar file many times and analyse output

I'd like to test which of two implementation in java of a problem is the fastest.
I've 2 jar files with the two implementation I can execute from the terminal. I want to execute both about 100 times and analyse which one is the fastest to do that or that task.
In the output one of the line is "executing time : xx", I need to catch this xx to put in an array or something like that to analyse it later
While I'm executing the jar, I've also to give some input commands (like a name to search or a number).
I don't with which language is it the easiest to do it.
I know the basis in Bash and Python
thank you
Excuse me, but Why you dont make a jar that call n-times any jar?
For Example:
public static void main(String[] args) {
for(int i=0;i<1000;i++) {
params1 = randomNumber();
params2 = randomName();
...
paramsN = randomTime();
MYJAR1 test1 = new MYJAR1(params1,params2,...,paramsN);
timerStart();
test1.start();
timerEnd();
printTimer();
}
}
and make the same for the second jar.
I hope that my idea can help you.
Bye
If you use (say) Perl, you can spawn the process off, capture the output via a redirection and filter the times. e.g.
if (open(PROCESS, "myproc |")) {
while(<PROCESS>) {
if (/executing time : (\d+)/) {
# $1 has the time now
}
}
}
(not compiled or tested!)
Perhaps the simplest way of analysing the data is to redirect the above output to a file, and then load it into Excel. You can then use Excel to calculate averages/max/mins and std. devs (if you wish) trivially.
Ok I've found with 3 different scripts ^^
in the java code, for each function :
long time1 = System.currentTimeMillis();
// some code for function 1
long time2 = System.currentTimeMillis();
try {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(new File("log.txt"),true));
osw.write("function1,"+(time2 - time1)+"\n");
osw.close();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
a bash code to run the 500 times the two algorithms
#!/bin/bash
i=0
while [ $i -lt 500 ]
do
./algo1.ex
./algo2.ex
i=$(( $i+1 ))
done
an (or two actually, one for each algorithm) expect code to do the command during the execution
#!/usr/bin/expect -f
spawn java -jar algo1.jar
expect "enter your choice" {send "1\n"}
expect "enter a name :" {send "Peju, M.\n"}
expect "enter your choice" {send "2\n"}
expect "enter a name :" {send "Creasy, R. J.\n"}
expect "enter your choice" {send "0\n"}
exit
As I didn't know how to do it in bash, to count I used a python code
#!/usr/bin/python
# -*- coding: utf8 -*-
import sys
if __name__ == "__main__":
if sys.argv[1:]:
arg = sys.argv[1]
filin = open(arg, 'r')
line = filin.readline()
res= 0, 0, 0
int n = 1
while line !='':
t = line.partition(',')
if t[0] == "function1":
res = (res[0] + int(t[2]), res[1], res[2])
if t[0] == "function2":
res = (res[0], res[1] + int(t[2]), res[2])
if t[0] == "function3":
res = (res[0], res[1], res[2] + int(t[2]))
ligne = filin.readline()
n = n+1
print res
print (res[0]/(n/3.0), res[1]/(n/3.0), res[2]/(n/3.0))
filin.close()
and it works
but thanks for your propositions

Categories