How to read adb response from jar? - java

I am trying to batch some apps installations and I want to do it app by app.
I am trying to get the adb command response into my java program but I don't manage to understand why I don't get anything from an InputStream!
Here is my test code:
import java.io.IOException;
import java.io.InputStream;
public class main_adbStreamTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
Process pro = Runtime.getRuntime().exec("platform-tools\\adb.exe -s " + args[0] + ":5555 install -r " + args[1]); // + " >> " + SBCWLogger.getFileHandlerName()
//add installation verification
InputStream is = pro.getInputStream();
int i = 0;
while( (i = is.read() ) != -1) {
System.out.print((char)i);
}
//verification done
} catch (IOException e) {
e.printStackTrace();
}
}
}
I found this answer which is not working, and I do not manage to use pro.getInputStream() properly either.
I also tried most of the answers from here but none of those I tested worked. I successfully read the errors when I don't connect or when the install fails, but not the informational messages as Success at the end of an install. And that is what I want.
EDIT: the code below is working thanks to Onix' answer.
import java.io.IOException;
import java.io.InputStream;
public class main_adbStreamTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
Process pro = new ProcessBuilder("platform-tools\\adb.exe", "-s",args[0], "install", "-r", args[1]).start();
//add installation verification
InputStream is = pro.getInputStream();
int i = 0;
while( (i = is.read() ) != -1) {
System.out.print((char)i);
}
//verification done
} catch (IOException e) {
e.printStackTrace();
}
}
}
And to get the famous Success, just write the stream to a file and read the last row.

Try this
Process process = new ProcessBuilder("Full path to adb", "-s", args[0], "install", "-r", args[1]).start();
InputStream is = process.getInputStream();

Related

Java - Tomcat Does not Launch ProcessBuilder() -- Password encryption

I created a "SecureUtils" method which will launch a .bat file to hash a password and return it as a string in Java. This method works very well on its own (with a main() to test it), but as soon as it is called in the webapp by Tomcat, the password is not hashed and I get the string "error"
First, here is my SecureUtils class:
package com.example.webtodolist;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class SecureUtils { public static String hash(String operation, int Chars_to_be_deleted) {
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("cmd.exe", "/c", operation);
String password_encrypted ="error";
try {
Process process = processBuilder.start();
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) {
output.delete(0,Chars_to_be_deleted);
password_encrypted = output.toString();
//System.exit(0);
return password_encrypted;
}
}
catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return password_encrypted;
}
public static String encrypt(String password_clear) throws Exception {
String cmd = System.getProperty("user.dir")+"/apache-tomcat/bin/digest.bat -a sha-512 -i 10 -s 8 -h org.apache.catalina.realm.MessageDigestCredentialHandler ";
int Chars_to_be_deleted = password_clear.length()+1;
String operation=cmd+password_clear;
return hash(operation,Chars_to_be_deleted);
}
public static void main(String[] argv) throws Exception {
System.out.println(encrypt("hugo"));
}
}
And when i run this file with the configuration 'Current file, i get my result (which is correct) :
3bf5f46ed747d0bc$10$e07a85579f5c2447f5a1192b121eca6b8e18c4116373f9e44436c52abf8eb578006a8f5eeaf92c9668db0a0cf7405081b12a1eaef780e446cedaf69f63aa5781
Now, with the 'TomCat Configuration profile, when the function is called I always get:
error.
Here my RegisterServlet.java :
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String username= request.getParameter("inputUsername");
String password = SecureUtils.encrypt(request.getParameter("inputPassword"));
boolean b = userDBUtil.addUser(new User(username,password));
String m;
if (b) m="A new user has been created";
else m="ERROR";
request.setAttribute("message", m);
request.getRequestDispatcher("/register.jsp").forward(request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I don't think tomcat is running a process in the background.
Do you know how I can use the
org.apache.catalina.realm.MessageDigestCredentialHandler
method to encrypt my passwords with this configuration (context.xml) without a bat file?
<CredentialHandler className="org.apache.catalina.realm.MessageDigestCredentialHandler"
algorithm="SHA-512"
iterations="10"
saltLength="8"
/>
Or is it possible to solve this problem by keeping this method ?

JNA library not restarting the java in Windows 10

Can anyone please help me .
I have one java file that calls C++ code (which interacts with hardware device, i.e. a scanner to login into the application, that means on login window user does not have to enter username/password, just have to scan the badge). I am launching the java through .bat file in Windows 10. My java program is a JavaFx project. It does have a menu item as "Switch User", "Logout". That means if the user clicks on "Switch User", then application should exits and restart should happen (i.e. the login window).
Now When I launch the .bat file first time, the java is called perfectly and it calls my .dll file (which has C++ code) and scans the badge perfectly. If I click on Switch User, the java application exits, but it does not re-launch again. I can see the re-launch command in the command window, but it hangs from there.
Note: This working fine in Windows 7.
At this point of time, I don't have control over the C++ code. But if I required, I can request the concerned team.
Here is my code to call the C++, .dll
ScanReader.java
import com.sun.jna.Library;
import com.sun.jna.Native;
public class ScanReader {
private File dllFile;
public interface LoadDLL extends Library {
LoadDLL INSTANCE = (LoadDLL) Native.loadLibrary("ScanReaderCPP", LoadDLL.class);
int readCard();
}
public void loadDll(String name) throws IOException {
InputStream in = ScanReader.class.getResourceAsStream("/" + name);
byte[] buffer = new byte[1024];
int read = -1;
if (in == null ) return;
dllFile = new File(new File(System.getProperty("java.io.tmpdir")), name);
FileOutputStream fos = new FileOutputStream(dllFile);
while ((read = in.read(buffer)) != -1) {
fos.write(buffer, 0, read);
}
fos.close();
in.close();
System.setProperty("jna.library.path", dllFile.getParent());
}
public String readCard() {
try {
loadDll("ScanReader.dll");
} catch (IOException e1) {
e1.printStackTrace();
}
LoadDLL loadDLL = LoadDLL.INSTANCE;
cnum = loadDLL.readCard();
dllFile.delete();
loadDLL = null;
return String.valueOf(cnum);
}
}
RelaunchUtil.java
public class RelaunchUtil {
public static void restart() throws IOException {
try {
final String launchCommand = "C:\\MY_BATCH_FILES\\my_project.bat";
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
try {
Runtime.getRuntime().exec(launchCommand);
} catch (IOException e) {
e.printStackTrace();
}
}
});
System.exit(-1);
} catch (Exception e) {
e.printStackTrace();
throw new IOException("Error while trying to restart the application", e);
}
}
}
ScanReaderCPP.cpp
int ScanReaderCPP::readCard() {
HANDLE ghSemaphore;
DWORD dwWaitResult;
BOOL bContinue = TRUE;

Starting appium server through Java

I am using MAC terminal to start appium server. In terminal I have executed command appium & to start the server which is working.
I have installed appium server through terminal using npm -g install appium
However when I am trying to execute the same code using Java then server is not starting.
Code:
Runtime.getRuntime().exec(new String[]{"/bin/sh","appium &"})
Error:
No such file or directory.
I have also tried to create shell script with appium command. When I invoke the shell script through Java, it says that command not found.
Code to invoke shell script command.
Process p = new ProcessBuilder(new String[]{"/bin/sh","-c","sh appium.sh"})
On invoking in Java, it gives error "appium.sh:Error on line1 - appium command not found"
When I invoked the same shell script through the terminal, appium server started successfully.
You can use below code for Starting appium server using java code and use service_url while intializing appium driver .Example is taken from THIS POST
import java.io.File;
import io.appium.java_client.service.local.AppiumDriverLocalService;
import io.appium.java_client.service.local.AppiumServiceBuilder;
public class AppiumServerStartStop {
static String Appium_Node_Path="C:\\Program Files (x86)\\Appium\\node.exe";
static String Appium_JS_Path="C:\\Program Files (x86)\\Appium\\node_modules\\appium\\bin\\appium.js";
static AppiumDriverLocalService service;
static String service_url;
public static void appiumStart() throws Exception{
service = AppiumDriverLocalService.buildService(new AppiumServiceBuilder().
usingPort(2856).usingDriverExecutable(new File(Appium_Node_Path)).
withAppiumJS(new File(Appium_JS_Path)));
service.start();
Thread.sleep(25000);
service_url = service.getUrl().toString();
}
public static void appiumStop() throws Exception{
service.stop();
}
}
public static void startAppiumServer() {
try {
Thread.sleep(3000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
final String appiumNodeFilePath = APPIUM_NODE_FILE_PATH;
final String appiumJavaScriptServerFile = APPIUM_JAVA_SCRIPT_SERVER_FILE_PATH;
final String appiumServerPortNumber = APPIUM_SERVER_PORT_NUMBER;
final String appiumServerConfigurations = "--no-reset --local-timezone --port "+ appiumServerPortNumber+ " -bp "+(Integer.parseInt(appiumServerPortNumber)+1);
(new Thread(){
public void run(){
String startCommand ="\"" + appiumNodeFilePath + "\" \""+ appiumJavaScriptServerFile + "\" "+ appiumServerConfigurations;
System.out.println("Server start command: "+startCommand);
executeCommand(startCommand);
}
}).start();
try {
Thread.sleep(25000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void executeCommand(String command) {
String s = null;
try {
Process p = Runtime.getRuntime().exec(command);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
System.out.println("Appium Server Output Logs:\n");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
System.out.println("Appium Server Error Logs:\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
} catch (IOException e) {
System.out.println("exception: ");
e.printStackTrace();
}
}
APPIUM_NODE_FILE_PATH="C:\Program Files (x86)\Appium\node.exe";
APPIUM_JAVA_SCRIPT_SERVER_FILE_PATH="C:\ProgramFiles(x86)\Appium\node_modules\appium\bin\appium.js
If you are interested to learn how it should be implemented, check appium-java-client AppiumDriverLocalService class.
And since you are using java in most cases its better to use AppiumDriverLocalService instead implementing your own solution:
AppiumDriverLocalService service = AppiumDriverLocalService.
buildDefaultService();
service.start() // to start appium server
...
service.getUrl() // to get URL of running server
...
service.isRunning() // to check if appium server is alive
...
service.stop() // to stop appium server

Trying to retrieve python version from java

I'm trying to retrieve the version of python form java using ProcessBuilder.
The command i'm using is:
{process = new ProcessBuilder("C:\\Python27\\python.exe", "-V")}
This command does not return anything.
I'm almost sure this is the correct syntax to retrieve the python version,
{process = new ProcessBuilder("C:\\Python27\\python.exe", "-h")}
returns the python help as expected, but python -V does not return the python version.
package com.x.x.precheck.python;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Test {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Process process = null;
try {
process = new ProcessBuilder("C:\\Python27\\python.exe", "-V")
.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
System.out.printf("Output of running %s is:", Arrays.toString(args));
try {
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
It's because, strangely enough, the python2.7 version is displayed in stderr. in python version 3.4 this behaviour will change see http://bugs.python.org/issue18338
so instead of
InputStream is = process.getInputStream();
you should call
InputStream stderr = process.getErrorStream ();
I tested your code with other programs.It all works fine.for example i gave octave instead of the python and It printed out.Its weird.

how to use a supplied username and password to read a file in Java

I need to read a bunch of binary files from a Java script running on Windows.
However, the folder that the files are in has limited permissions. I (i.e. my Windows username) have permissions to read them, but the user that Java runs as (this is part of a web application) does not. If I pass my own username and Windows network password into Java at runtime, is there a way I can read those files using my own permissions rather than the web user's?
(Note that this is NOT happening over the web; this is a one-time import script running in the context of a web application.)
You could create a network share and then connect via jCIFS
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
import jcifs.smb.SmbException;
import jcifs.smb.SmbFileInputStream;
public class Example
{
public static void main(String[] args)
{
SmbFileInputStream fis = null;
try
{
fis = new SmbFileInputStream("smb://DOMAIN;USERNAME:PASSWORD#SERVER/SHARE/filename.txt");
// handle as you would a normal input stream... this example prints the contents of the file
int length;
byte[] buffer = new byte[1024];
while ((length = fis.read(buffer)) != -1)
{
for (int x = 0; x < length; x++)
{
System.out.print((char) buffer[x]);
}
}
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (SmbException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if (fis != null)
{
try
{
fis.close();
}
catch (Exception ignore)
{
}
}
}
}
}
If the files are on a network-share you could use the net tool. With
runtime.exec("net use ...")
to open and close the share. I guess that should work

Categories