Combine commons-cli and password prompt in Java - java

I'm currently using import org.apache.commons.cli
Let's say I have a command line parser like:
private static commandLineParser(Options options, String[] strings) throws ParseException {
options.addOption("u", "username", true, "Login Username");
options.addOption("p", "password", true, "Login Password");
// Some other options
CommandLineParser parser = new DefaultParser();
return parser.parse(options, strings);
}
and my main function:
public static void main(String args[]) {
Options options = new Options();
CommandLine cmd = null;
try {
cmd = commandLineParser(options, args);
//some helpFormatter stuff to make the options human-readable
} catch (ParseException e) {
e.printStackTrace();
System.exit(2);
}
//calling my main program
doSomething(cmd)
}
For obvious reasons I want to omit the password from the command line, since it would be visible in both the history and the process list. However my main program expects an object of type CommandLine. Is there any way to parse a password with a similar behaviour as console.readPassword() or even call this function and add it to the CommandLine object?
I've already tried to search for a combination of commons-cli and password parsing but was not successful.

While there doesn't seem to be a way in commons-cli to add an option value to the CommandLine object, you can (hopefully) modify your doSomething(cmd) program to read from stdin.
If the password was provided on the commandline, accept it. If not, read from stdin on the fly.
For example:
private void doSomething(CommandLine cmd) {
String username = cmd.getOptionValue("username");
char[] password = (cmd.hasOption("password"))
? cmd.getOptionValue("password").toCharArray()
: System.console().readPassword("Enter password for %s user: ", username);
}

Related

Finding batch file using parameter in java

I have a batch file (test.bat) which has the command copy NUL test.txt. I have a java program, when i run it and when i enter a URL in the web browser e.g http://localhost:8080/runbatchfileparam, i get a result as either {"result":true} or {"result":false}. True means the java application has executed the batch file correctly (test.txt is created under the directory).
What i want to do now is, i want the java program to be able to take in parameters. E.g. User should be able to enter http://localhost:8080/runbatchfileparam/testabc.bat as the URL in web browser and the result should be {"result":true} if testabc.bat file is found and is executed (under desktop) and {"result":false} if the testabc.bat file is not found and not executed . (Note: All batch files are created under desktop filepath: C:/Users/attsuap1/Desktop)
I have edited my controller to take in a parameter and done the #PathVariable. In my codes, the fileName variable refers to the batch file name that i have created (test.bat, test123.bat) Command in test.bat: copy NUL test.txt Command in test123.bat: copy NUL test123.txt. However, i keep getting the result as {"result": false}. Which means the java program is not able to find the batch file and execute it.
Here are my codes:
RunBatchFile.java
public ResultFormat runBatch(String fileName) {
String var = fileName;
String filePath = "C:/Users/attsuap1/Desktop" + var;
try {
Process p = Runtime.getRuntime().exec(filePath);
int exitVal = p.waitFor();
return new ResultFormat(exitVal == 0);
} catch (Exception e) {
e.printStackTrace();
return new ResultFormat(false);
}
}
ResultFormat.java
private boolean result;
public ResultFormat(boolean result) {
this.result = result;
}
public boolean getResult() {
return result;
}
BatchFileController
private static final String template = "Sum, %s!";
#RequestMapping("/runbatchfileparam/{param}")
public ResultFormat runbatchFile(#PathVariable("param") String fileName ) {
RunBatchFile rbf = new RunBatchFile();
return rbf.runBatch(fileName);
}
Application.java
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
What do i have to edit or what should i add to the codes to achieve what i want?
After this line:
String filePath = "C:/Users/attsuap1/Desktop" + var;
Try to print the contents of filePath, i suspect that you come up with something like this:
C:/Users/attsuap1/Desktoptestabc.bat

Testing multiple environments with different data - best practice

I need to be able to run the same tests on different environments (max 3) but with different data for each one.
I have a test method:
#Test (groups = "core", description = "Login: Valid log in")
public void validLogin() {
User user = UserData.user_2();
loginPage.logOn(user);
}
In the UserData class I have:
public static User user_2() {
return new User().newUser("user2", "password");
}
"user2" does not exist on all environments. I may not be able to change the data that is available on all of the environments to match the test data.
The tests will be executed either using Maven and TestNg so I can send in the parameter for the execution environment.
My initial thought is to use:
public static User user_2() {
switch(env) {
case "env1": return new User().newUser("user2", "password"); break;
case "env2": return new User().newUser("user2Z", "password"); break;
case "env3": return new User().newUser("user2X", "password"); break;
}
I have a limited number of data classes and methods (<100) but several thousand tests.
What is the best way of setting up and handling the data required for testing against the different environments?
When it comes to different users ,
You always wish that all my test cases should remain as it is and with minimal change.
So this is what i follow.
I create a file lets say username.properties file in eclipse.
username=xyz#gmail.com
password=passswd1
You can create multiple users here with name i.e.
rohan=rohan#gmail.com
rohan's password: rohan
Now we need to call this file in our class.
See below example.
Main test
SignInPage.SendkeysMethodForSignInPAgeForPropertyFile(driver, By.cssSelector("input[id='Email']") , "username" );
SignInPage.SendkeysMethodForSignInPAgeForPropertyFile(driver, By.cssSelector("input[id='Passwd'][type='password']"), "password");
So here username will be taken from properties file.
This will go to SendkeysMethodForSignInPAgeForPropertyFile which is:
public class SignInPage {
public void SendkeysMethodForSignInPAgeForPropertyFile(WebDriver driver, By by, String Text) {
WebUtils.SendkeysForPropertyFile(driver,by, Text);
}
}
Which will go to SendkeysForPropertyFile method as:
public static void SendkeysForPropertyFile(WebDriver driver, By by, String Text) {
ReadFileData File = new ReadFileData();
Properties Values = File.ReadFile();
WebElement Element = driver.findElement(by);
Element.clear();
if (Text == "username"){
Element.sendKeys(Values.getProperty("username"));
}
else {
Element.sendKeys(Values.getProperty("password"));
}
Which will read from ReadFileData() class which is:
public class ReadFileData {
public Properties ReadFile() {
File file = new File("D:\\Selenium\\Gmail_Web_UI\\Loginproperty.properties");
FileInputStream fileInput = null;
try {
fileInput = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Properties prop = new Properties();
//load properties file
try {
prop.load(fileInput);
} catch (IOException e) {
e.printStackTrace();
}
return prop;
}
This helps to keep our username and password safe in a single file.
Reply to me for further query. Happy Learning :-)

Java add key to regedit doesn't add any kay and doesn't show any error message

I'm following this trying to put my program at startup on windows systems after login:
Starting a Java application at startup
But it doesn't work. My code:
static final String REG_ADD_CMD = "reg add \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\" /v \"{0}\" /d \"{1}\" /t REG_EXPAND_SZ";
private void exec(String[] args) throws Exception
{
if (args.length != 2)
throw new IllegalArgumentException("\n\nUsage: java SetEnv {key} {value}\n\n");
String key = args[0];
String value = args[1];
String cmdLine = MessageFormat.format(REG_ADD_CMD, new Object[] { key, value });
System.out.println("cmd line: "+cmdLine);
Runtime.getRuntime().exec(cmdLine);
}
#Override
public void autostartupInstalation() {
try {
String[] args = {"javaLL" , "javaw -Xmx200m -jar "+ super.installPathFile};
exec(args);
} catch (Exception ex) {
MainClass.getMainClass(InstallerWindows.class.getName()).log(Level.SEVERE, null, ex);
}
I'm using windows 7, and executed under a cmd or admin cmd.
What could be the problem?
It doesn't show any error code or exception.
Also showing my process, when i finalize the program, starts a proces called reg.exe that i don't know what is. For every instance of the program that I finalize start one of this proces.

Catch Java Exception with PHP shell_exec

Is there any way to catch a java exception from a JAR call by a php script? I have (!) to use some external JAVA libraries, which throws Exceptions. The Question is how can i extract valuable information for developers and show some explanation to the customer?
PHP Script
try{
$cmd = "java -jar myjar.jar";
$output = shell_exec(escapeshellcmd($cmd));
}
catch(Javaexception $e){
//do some error handling ....
}
Java Jar
//....
public class Main{
public static void main(String[] args){
throw new Exception("Testexception");
}
}
//...
shell_exec only returns a String or Null, so you can't catch the Java Exception like that, try to create your own Exception and "catch it" with a if
$cmd = "java -jar myjar.jar";
$output = shell_exec(escapeshellcmd($cmd));
if($output == 'expected output') throw new MyException();
Basic answer: not directly.
You can use exit statuses to communicate processing status from the Java application.
In Java:
public class Main{
public static void main(String[] args){
try {
// work
} catch (MyException e) {
// handle error
// write exception to file or STDOUT
System.exit(1);
}
}
}
In PHP you can get the exit status via return_var in exec call:
string exec ( string $command [, array &$output [, int &$return_var ]] )
You can also write Exception details to STDOUT or file and process its content in the PHP when status code is non 0.

JavaScript to Java Applet using DeployJava.js to run commandline

I am pretty new to Java. I want to create a Java Applet that will allow my JavaScript to pass a commandline to the Java Applet. This will only ever be run on my development machine - no need to remind me what a security issue that is. The use-case is that I have an introspector for my ExtJS app that allows me to display the classes. I want to be able to click a class, pass the relevant pathname to the Applet and have that file open in Eclipse for editing.
I am using Win7x64, jre 1.7
So, to get Eclipse to open the file from the commandline the command is:
D:\Eclipse\eclipse.exe --launcher.openFile C:\mytestfile.js
This works.
I have written the Applet, self signed it and tested the say() method using the code shown below. That works. However when I run the executecmd() method, I don't get any output. If I comment out the whole try/catch block so that I am simply returning the cmd string passed in, the method works. Therefore, I suspect that I have the try catch incorrectly setup and since my Java skills and knowledge of the exceptions are primitive I am lost.
Can anyone help me please? At least to get some output returned, if not how to actually run the command line passed in?
And, I am passing the whole command line because when I have this working I would like to share it (since the Ext introspector is really useful). Other developers will be using different editors so this way they can use it by passing their specific commandline.
Thanks!
Murray
My HTML test page:
<html>
<head>
<meta charset="UTF-8">
<title>Test Run</title>
<script src="http://www.java.com/js/deployJava.js"></script>
<script>
var attributes = { id:'testapp', code:'systemcmd.Runcmd', archive:'runcmd.jar', width:300, height:50} ;
var parameters = {} ;
deployJava.runApplet(attributes, parameters, '1.6');
</script>
</head>
<body>
<p>Hello</p>
<script type="text/javascript">
//alert(testapp.say("Hello test")); // This works
var command = "D:\Eclipse\eclipse.exe --launcher.openFile C:\mytestfile.js";
alert(testapp.executecmd(command)); // Nothing returned at all.
</script>
</body>
</html>
My class:
package systemcmd;
import java.applet.Applet;
import java.io.IOException;
import java.security.AccessController;
//import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
public class Runcmd extends Applet {
private static final long serialVersionUID = -4370650602318597069L;
/**
* #param args
*/
public static void main(String[] args) {
}
public String say(String arg)
{
String msg[] = {null};
msg[0] = "In Say. You said: " + arg;
String output ="";
for(String str: msg)
output=output+str;
return output;
}
public String executecmd(final String cmd) throws IOException
{
final String msg[] = {null};
String output ="";
msg[0] = "In executecmd, cmd="+cmd;
try {
try {
AccessController.doPrivileged(
new PrivilegedExceptionAction() {
public Object run() throws IOException { //RuntimeException,
msg[1] = " Pre exec()";
Runtime.getRuntime().exec(cmd);
msg[2] = " Post exec()";
return null;
}
}
);
} catch (PrivilegedActionException e) {
msg[3] = " Caught PrivilegedActionException:"+ e.toString();
throw (IOException) e.getException();
}
}
catch (Exception e) {
msg[4] = " Command:" + cmd + ". Exception:" + e.toString();
}
msg[5] = " End of executecmd.";
for(String str: msg)
output=output+str;
return output;
}
}
Set Eclipse as the default consumer for .java files and use Desktop.open(File) which..
Launches the associated application to open the file.
Ok, #Andrew. Some progress, thank you!
I set the default program for *.js files to Eclipse and if I double click a file it opens in Eclipse. All good.
I then had success running the following using RunAs Java Application - the test file opened in Eclipse. Getting closer!
public class Runcmd extends Applet {
File file;
private static Desktop desktop;
private static final long serialVersionUID = -4370650602318597069L;
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
System.out.println("hello");
if (Desktop.isDesktopSupported()) {
desktop = Desktop.getDesktop();
}
File file = new File("C:\\sites\\test.js");
// This works if I execute it from the Eclipse RunsAs Java Application.
// ie the file is opened in Eclipse for editing.
// And, if I specify a non-existant file, it correctly throws and prints the error
try {
desktop.open(file);
} catch (Exception ioe) {
ioe.printStackTrace();
System.out.println("Error: " + ioe.toString());
}
}}
However, when I added the following method and ran it via the DeployJava.js (as per my original post above), I get the following output returned with the error appearing whether or not the jar is self signed.
Started: , Desktop is supported , Error:
java.security.AccessControlException: access denied
("java.awt.AWTPermission" "showWindowWithoutWarningBanner")
public static String openfile(String arg) {
String output = "Started: ";
File file = new File("C:\\sites\\test.js");
if (Desktop.isDesktopSupported()) {
desktop = Desktop.getDesktop();
output = output + ", Desktop is supported ";
}
try {
desktop.open(file);
} catch (Exception ioe) {
output = output + ", Error: " + ioe.toString();
}
return output + arg;
}
So, what do I need to add to get around the apparent security issue? I have read the docs and the tutorials and I am going around in circles! There seems to be a lot of conflicting advice. :-(
Thanks again,
Murray

Categories