how to use property=value in CLI commons Library - java

I am trying to use the OptionBuilder.withArgName( "property=value" )
If my Option is called status and my command line was:
--status p=11 s=22
It only succeeds to identify the first argument which is 11 and it fails to identify the second argument...
Option status = OptionBuilder.withLongOpt("status")
.withArgName( "property=value" )
.hasArgs(2)
.withValueSeparator()
.withDescription("Get the status")
.create('s');
options.addOption(status);
Thanks for help in advance

You can access to passed properties using simple modification of passed command line options
--status p=11 --status s=22
or with your short syntax
-s p=11 -s s=22
In this case you can access to your properties simply with code
if (cmd.hasOption("status")) {
Properties props = cmd.getOptionProperties("status");
System.out.println(props.getProperty("p"));
System.out.println(props.getProperty("t"));
}
If you need to use your syntax strictly, you can manually parse your property=value pairs.
In this case you should remove .withValueSeparator() call, and then use
String [] propvalues = cmd.getOptionValues("status");
for (String propvalue : propvalues) {
String [] values = propvalue.split("=");
System.out.println(values[0] + " : " + values[1]);
}

Related

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
}

Need to filter, parse and sort multiple log files

I have a need to collect a subset of info from log files that reside on one-to-many log file servers. I have the following java code that does the initial data collection/filtering:
public String getLogServerInfo(String userName, String password, String hostNames, String id) throws Exception{
int timeout = 5;
String results = "";
String[] hostNameArray = hostNames.split("\\s*,\\s*");
for (String hostName : hostNameArray) {
SSHClient ssh = new SSHClient();
ssh.addHostKeyVerifier(new PromiscuousVerifier());
try {
Utils.writeStdOut("Parsing server: " + hostName);
ssh.connect(hostName);
ssh.authPassword(userName, password);
Session s = ssh.startSession();
try {
String sh1 = "cat /logs/en/event/event*.log | grep \"" + id + "\" | grep TYPE=ERROR";
Command cmd = s.exec(sh1);
results += IOUtils.readFully(cmd.getInputStream()).toString();
cmd.join(timeout, TimeUnit.SECONDS);
Utils.writeStdOut("\n** exit status: " + cmd.getExitStatus());
} finally {
s.close();
}
} finally {
ssh.disconnect();
ssh.close();
}
}
return results;
}
The results string variable looks something like this:
TYPE=ERROR, TIMESTAMP=10/03/2015 07:14:31 253 AM, HOST=server1, APPLICATION=app1, FUNCTION=function1, STATUS=null, GUID=null, etc. etc.
TYPE=ERROR, TIMESTAMP=10/03/2015 07:14:59 123 AM, HOST=server1, APPLICATION=app1, FUNCTION=function1, STATUS=null, GUID=null, etc. etc.
TYPE=ERROR, TIMESTAMP=10/03/2015 07:14:28 956 AM, HOST=server2, APPLICATION=app1, FUNCTION=function2, STATUS=null, GUID=null, etc. etc.
I need to accomplish the following:
What do I need to do to be able to sort results by TIMESTAMP? It is unsorted right now, because i am enumerating one to many files, and appending results to end of a string.
I only want a subset of "columns" returned, such as TYPE, TIMESTAMP, FUNCTION. I thought i could REGEX it in the grep, but maybe arrays would be better?
Results are simply being printed to console/report, as this is only printed for failed tests, and is there for troubleshooting purposes only.
I took the list of output that you provided and put it in a file, named test.txt, making sure that each "TYPE=ERROR etc. etc" was in a new line (I guess it's the same in your output, but it isn't clear).
Then I used cat test.txt | cut -d',' -f1,2,5 | sort -k2 to do what you want.
cut -d',' -f1,2,5 basically splits by comma and only reports tokens number 1,2,5 (TYPE,TIMESTAMP,FUNCTION). If you want more, you can add more numbers depending on what token you want
sort -k2 sorts according to the 2nd column (TIMESTAMP)
The output I get is:
TYPE=ERROR, TIMESTAMP=10/03/2015 07:14:28 956 AM, FUNCTION=function2
TYPE=ERROR, TIMESTAMP=10/03/2015 07:14:31 253 AM, FUNCTION=function1
TYPE=ERROR, TIMESTAMP=10/03/2015 07:14:59 123 AM, FUNCTION=function1
So what you should try and do, is to further pipe your command with |cut -d',' -f1,2,5 | sort -k2
I hope it helps.
After working on this some more, i come to find that one of the key/value pairs allows commas in the values, thus cut will not work. Here is the finished product:
My grep command stays the same, collecting data from all servers:
String sh1 = "cat /logs/en/event/event*.log | grep \"" + id + "\" | grep TYPE=ERROR";
Command cmd = s.exec(sh1);
results += IOUtils.readFully(cmd.getInputStream()).toString();
Put the string into an array, so i can process them line by line:
String lines[] = results.split("\r?\n");
I then used regex to get the data i needed, repeating the below for each line in the array, and for as many columns as needed. It's a bit of a hack, I probably could have done it better by simply replacing the comma in the offending key/value pair, then using SPLIT() and comma as delimeter, then looping for the fields i want.
lines2[i] = "";
Pattern p = Pattern.compile("TYPE=(.*?), APPLICATION=.*");
Matcher m = p.matcher(lines[i]);
if (m.find()) {
lines2[i] += ("TYPE=" + m.group(1));
}
Finally, this will sort by Timestamp, since it is 2nd column:
Arrays.sort(lines2);

reading java property value with spaces into one variable

Hello my problem is as follows:
i have a property fiel with a startconfig for external program to run from java:
# Standardauswahl falls keine PlayerType übergeben wurden
Default = 1
# Liste der gültigen PlayerTypes
PlayerTypes = Human,MCTS,TMM,Random,Value
StartConfig = \"C:\\Program Files\\Java\\jdk1.7.0_13\\bin\\javaw.exe\" -Dlog4j.configuration=file:///C:/Users/djdeejay/git/myGit/com.djdeejay.cowTrade.client.standaloneplayer.application/bin/log4j.xml -Dfile.encoding=Cp1252 -classpath [..... some parameter deleted.....] 0.0-RC1.jar;C:\\Users\\djdeejay\\git\\myGit\\de.thWildau.cowTrade.server\\lib\\slf4j-api-1.5.2.jar;C:\\Users\\djdeejay\\git\\myGit\\de.thWildau.cowTrade.server\\lib\\slf4j-log4j12-1.5.2.jar;C:\\Users\\djdeejay\\git\\myGit\\de.thWildau.cowTrade.server\\lib\\log4j-1.2.16.jar com.djdeejay.cowTrade.client.standaloneplayer.application.RandomPlayerApplication %1 %2 %3
when i load the properties as follows
cmd = this.serverSettings.getPlayerTypeSetting("StartConfig");
#Override
public String getPlayerTypeSetting(String key) {
return this.startPlayerTypeSettingsProp.getProperty(key);
}
java cutting startconfig after the first space:
Cannot run program """C:\Program" when its in doublequotes or Cannot run program ""C:\Program":
i have tried several variants with "", with escaping and so on nothing gives my needed result
how do i config getproperty to read until EOL?
cheers
As discussed in the comments, the getProperty call is alright. But the usage as a single string in Runtime.getRuntime().exec(cmd) uses the default whitespace Tokenizer to split the string into command and argument.
To do this yourself, first split the string manually and then pass it to Runtime#exec:
String startCmdLine = this.serverSettings.getPlayerTypeSetting("StartConfig");
int cmdEndPos = startCmdLine.indexOf("javaw.exe") + "javaw.exe".length();
String cmd = startCmdLine.substring(0, cmdEndPos);
String args = startCmdLine.substring(cmdEndPos);
Runtime.getRuntime().exec(new String[]{ cmd, args });
Though I really advise you to take advantage of the JAVA_HOME environment variable if you just want to start a known java binary. That way you can reduce that to a set of parameters in the property file.
Try replacing your spaces with: "\u0020"
Use this:
StringEscapeUtils.escapeXml(String input);
See doc here

Java System Parameter causing NoClassDefFoundError

I have a class which takes in various system parameters and prints them out:
public class Test_Class {
public static void main(String[] args){
String fooA = System.getProperty("fooA");
String fooB = System.getProperty("fooB");
String fooC = System.getProperty("fooC");
System.out.println("System Properties:\n"+fooA+"\n"+foob+"\n"+fooC+"\n");
}
}
Then, using IntelliJ, pass in the VM Parameters as such:
-DfooA="StringA" -DfooB="StringB" -DfooC="String C"
Upon running my program I get the following output:
System Properties:
StringA
StringB
String C
Now, if I run the same program through a UNIX server by running the following command:
java -DfooA="StringA" -DfooB="StringB" -DfooC="String C" com.foo.fooUtil.Test_Class
I get the following error:
Exception in thread "main" java.lang.NoClassDefFoundError: C
I have tried a bunch of different ways to pass in fooC, such as -DfooC=\"String C\", -DfooC='String C', -DfooC=\'String C\', basically any idea that came to mind. I have done some research and have been unable to find any solid solution.
For reference, I found the following link online where another person seems to have the same issue but, unfortunately, none of the suggestions work.
http://www.unix.com/shell-programming-scripting/157761-issue-spaces-java-command-line-options.html
How can I pass in a System Parameter with spaces in UNIX? Thank you.
Here is my approach: Why not use a .properties file for storing the system properties instead of passing them through command line? You can access the properties using:
Properties properties = new Properties();
try {
properties.load(new FileInputStream("path/filename"));
} catch (IOException e) {
...
}
And you may iterate as:
for(String key : properties.stringPropertyNames()) {
String value = properties.getProperty(key);
System.out.println(key + " => " + value);
}
Hope that helps!!!

Categories