I used the following code for getting the motherboard serial number. But I got the o/p Result is empty. What mistake did I make in this code?
File file = File.createTempFile("realhowto",".vbs");
file.deleteOnExit();
FileWriter fw = new java.io.FileWriter(file);
String vbs =
"Set objWMIService = GetObject(\"winmgmts:\\\\.\\root\\cimv2\")\n"
+ "Set colItems = objWMIService.ExecQuery _ \n"
+ " (\"Select * from Win32_BaseBoard\") \n"
+ "For Each objItem in colItems \n"
+ " Wscript.Echo objItem.SerialNumber \n"
+ " exit for ' do the first cpu only! \n"
+ "Next \n";
fw.write(vbs);
fw.close();
Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
BufferedReader input =
new BufferedReader
(new InputStreamReader(p.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
result += line;
}
if(result.equalEgnoreCase(" ") {
System.out.println("Result is empty");
} else {
System.out.println("Result :>"+result);
}
input.close();
}
I can confirm that the VBS side of this works fine on my machine; however, the output I got was:
MB-1234567890
which doesn't seem particularly unique or helpful. Still, if this is what you're after, try the following. Paste the VBS into a .vbs file and run it using cscript <myfile>.vbs:
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery _
("Select * from Win32_BaseBoard")
For Each objItem in colItems
Wscript.Echo objItem.SerialNumber
exit for ' do the first cpu only!
Next
If that works, it's the Java that's at fault (and I suspect it's not capturing the process output for some reason). Otherwise, it's the VBS script failing you.
There are some more hints and tips on this thread which might give you some different strategies.
Process p = Runtime.getRuntime().exec("wmic baseboard get serialnumber");
or
Process p = Runtime.getRuntime().exec("wmic /node:"HOST" bios get serialnumber");
instead of HOST , give ur hostname, which can be arrived at typing hostname in cmd prompt.
Related
I'm trying to backup my MySQL database from my Java app.
Here's the code:
String executeCmd = "mysqldump.exe -u " + dbUser + " -p" + dbPass;
executeCmd += " --all-databases > " + savePath;
System.out.println(executeCmd);
Runtime.getRuntime().exec(executeCmd);
But it do nothing. If I copy output of System.out.println and paste it into cmd it works fine. Can someone say what's wrong in Java?
I strongly suggest that you read this canonical article on JavaWorld about Runtime.getRuntime(). The long story short, you have two major problems with your code. First, you are not waiting for the process to complete, and second you are not handling the output from that process. Taking the following code partially from the above article, we can write a version which should work:
try {
Runtime rt = Runtime.getRuntime();
String executeCmd = "mysqldump.exe -u " + dbUser + " -p" + dbPass;
executeCmd += " --all-databases > " + savePath;
Process proc = rt.exec(executeCmd);
InputStream stderr = proc.getErrorStream();
InputStreamReader isr = new InputStreamReader(stderr);
BufferedReader br = new BufferedReader(isr);
String line = null;
System.out.println("<ERROR>");
while ( (line = br.readLine()) != null)
System.out.println(line);
System.out.println("</ERROR>");
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);
}
catch (Throwable t) {
t.printStackTrace();
}
If, as you say, the call to mysqldump is successful from the same machine where you are running this code, then there should be no error warnings. If there are any errors, then above snippet should put you in a good position to see what they are, and deal with them.
Try to use waitFor(), something like this.
public boolean backupDB(String dbName, String dbUserName, String dbPassword, String path) {
String executeCmd = "mysqldump.exe -u " + dbUserName + " -p "+dbPassword+" --all-databases > " + path;
Process runtimeProcess;
try {
runtimeProcess = Runtime.getRuntime().exec(executeCmd);
int processComplete = runtimeProcess.waitFor();
if (processComplete == 0) {
System.out.println("Backup created successfully");
return true;
} else {
System.out.println("Could not create the backup");
}
} catch (Exception ex) {
ex.printStackTrace();
}
return false;
}
Solved. Problem was in executeCmd.
It works this way:
String executeCmd = "mysqldump.exe -u " + dbUser + " -p" + dbPass+" dbName -r " + savePath;
I don't understand why it don't work with --all-databases, but problem solved. THX for all.
I am trying to call a shell script from a Java class and I want the output of the shell script to be stored in a log file.
My code looks something like this
String cmd = "/bin/sh /ws/priyapan-rcd/US248547/label_update.sh "+ branch_name + " "
+ product_type + " "
+ new_branch_name + " "
+ new_branch_label;
System.out.println("cmd is" +cmd);
Runtime rt = Runtime.getRuntime();
Process p = rt.exec(cmd);
try {
p.waitFor();
} catch (Exception e) {
logger.error("{}", e);
}
//Gets the exit status to determine if label update was successful.
exitValue = p.exitValue();
// Sleeping for 500 milliseconds to give the script enough time to create the log files
Thread.sleep(500);
System.out.println("about to create the log file");
File LabelUpdateLog = new File("/ws/priyapan-rcd/workspace/labelupdate_"+train_id+".log");
//File LabelUpdateLog = new File("/users/ccmbuild/deactivation_cerebro/LabelUpdate_"+train_id+".log");
System.out.println("log file created");
logger.debug("{}", LabelUpdateLog);
all the print statements are getting executed but the log file is not generated.
can anyone please suggest the reason
i think this script is not getting called inside my class /ws/priyapan-rcd/US248547/label_update.sh
any idea why?someone please suggest
You keep your code as is just change in command like
String cmd = "/bin/sh /ws/priyapan-rcd/US248547/label_update.sh "+ branch_name + " "
+ product_type + " "
+ new_branch_name + " "
+ new_branch_label +" >> LogFile.log";
If you want to create file on relative path then change your command accordingly.
String cmd = "/bin/sh /ws/priyapan-rcd/US248547/label_update.sh "+ branch_name + " "
+ product_type + " "
+ new_branch_name + " "
+ new_branch_label +" >> /ws/priyapan-rcd/workspace/labelupdate_"+train_id+".log";
Two main things:
The constructor of the File class does not create on disk the file. It's just a file descriptor. If you want to create that file, you have to either call labelUpdateLog.createFile()
In your code I do not see where you try to write the "output of the shell script". You need to read the output stream of the process if you really want to get the output of the script.
By the way, the example in the Javadoc of ProcessBuilder simply states how to execute a command and save output to a log file.
ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2");
pb.directory(new File("myDir"));
File log = new File("log");
pb.redirectErrorStream(true);
pb.redirectOutput(Redirect.appendTo(log));
Process p = pb.start();
This is one of a few Bash scripts I create in my pipeline. My Difficulty is I would like to make the created file executable without the user having to enter into the terminal "sudo chmod 777 /file/path/"
String Trans_ref =
"#!/bin/bash \n" +
"mkdir -p "+Output+"/"+Sample+"_RSEM \n" +
"cd "+Output+"/"+Sample+"_RSEM \n" +
"PATH=$PATH:"+RSEMprep+" \n" +
"export PATH=$PATH \n" +
""+RSEMprep+"/rsem-prepare-reference --no-polyA --bowtie "+Output+"/Trans_CDHIT.fast Trans_CDHIT.RSEM \n" +
""+RSEMprep+"/rsem-calculate-expression --paired-end -p "+CPU+" "+Output+"/SRR617145_1.fastq "+Output+"/SRR617145_2.fastq Trans_CDHIT.RSEM Trans_CDHIT.genes.results \n"+
""+Trinprep+"/util/misc/count_features_given_MIN_FPKM_threshold.pl "+Output+"/"+Sample+"_RSEM/RSEM.genes.results > "+Output+"/"+Sample+"_RSEM/cumul_counts.txt \n"+
""+Trinprep+"/util/filter_fasta_by_rsem_values.pl --rsem_output= "+Output+"/"+Sample+"_RSEM/RSEM.isoforms.results --fasta="+Output+"/Trans_CDHIT.fasta -t 100 --output="+Output+"/"+Sample+"_RSEM/Trans_RSEMfilters.fasta \n" +
""+Trinprep+"/util/bowtie_PE_separate_then_join.pl --seqType fq --left "+Output+"/"+Sample+"_1.fasta --right "+Output+"/"+Sample+"_2.fasta --target "+Output+"/Trans_CDHIT.fasta --aligner bowtie --SS_lib_type FR -- -p 4 --all --best --strata -m 300 \n";
System.out.println(Trans_ref);
FileUtils.writeStringToFile(new File(Output+"/TranRSEM"), Trans_ref);
StringBuffer Trim = new StringBuffer();
String cmd = (Output+"/TranRSEM");
Process p;
try{
p = Runtime.getRuntime().exec(new String[]{"/bin/sh","-c", cmd});
p.waitFor();
BufferedReader reader1 =
new BufferedReader(new InputStreamReader(p.getInputStream()));
System.out.println("Merg Finished");
} catch (Exception e) {
e.printStackTrace();
}
many thanks
There are a couple ways, but the best would be to use SetExecutable
once you created the file. It would look something like this.
if (file.exists()) {
boolean bval = file.setExecutable(true);
..... set the owner's execute permission
} else {
...... File does not exist;
}
if (file.exists()) {
boolean bval = file.setExecutable(true, false);
..... set everybody's execute permission
} else {
...... File does not exist;
}
Hope this helps
I am using this code to get Motherboard ID in windows :
public static String getMotherboardSN() {
String result = "";
try {
File file = File.createTempFile("realhowto", ".vbs");
file.deleteOnExit();
FileWriter fw = new java.io.FileWriter(file);
String vbs = "Set objWMIService = GetObject(\"winmgmts:\\\\.\\root\\cimv2\")\n"
+ "Set colItems = objWMIService.ExecQuery _ \n"
+ " (\"Select * from Win32_BaseBoard\") \n"
+ "For Each objItem in colItems \n"
+ " Wscript.Echo objItem.SerialNumber \n"
+ " exit for ' do the first cpu only! \n" + "Next \n";
fw.write(vbs);
fw.close();
Process p = Runtime.getRuntime().exec(
"cscript //NoLogo " + file.getPath());
BufferedReader input = new BufferedReader(new InputStreamReader(p
.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
result = line;
}
input.close();
} catch (Exception e) {
e.printStackTrace();
}
return result.trim();
}
Trying this code in ubuntu server throws an exception :
java.io.IOException: Cannot run program "cscript": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
at java.lang.Runtime.exec(Runtime.java:615)
at java.lang.Runtime.exec(Runtime.java:448)
at java.lang.Runtime.exec(Runtime.java:345)
at tcs.util.MiscUtils.getMotherboardSN(MiscUtils.java:31)
at tcs.util.Validator.validate(Validator.java:13)
at test.Shoot.main(Shoot.java:31)
Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:135)
at java.lang.ProcessImpl.start(ProcessImpl.java:130)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1021)
I have googled about it but found no solution for linux . I also tried solutions here Printing my Mac's serial number in java using Unix commands and still no luck.
I am aware that there are solutions written in C/C++ but using JNI is not an option because we have no experience in it and cant meet the deadline on time.
any suggestions will be appreciated,
use "cscript" command with absolute path
FULL_PATH/cscript //NoLogo " + file.getPath())
example: /home/myprojext/cscript //NoLogo " + file.getPath())
I'm using process = Runtime.getRuntime().exec(cmd,null,new File(path));
to execute some SQL in file (abz.sql)
Command is:
"sqlplus "+ context.getDatabaseUser() + "/"
+ context.getDatabasePassword() + "#"
+ context.getDatabaseHost() + ":"
+ context.getDatabasePort() + "/"
+ context.getSid() + " #"
+ "\""
+ script + "\"";
String path=context.getReleasePath()+ "/Server/DB Scripts";
It is executing that file but not getting exit. Hence I tried using:
Writer out = new OutputStreamWriter(process.getOutputStream());
out.append("commit;\r\n");
out.append("exit \r\n");
System.out.println("---------"+out);
out.close();
This it complete block that I m using:
if(context.getConnectionField()=="ORACLE")
{
String cmd=
"sqlplus "+ context.getDatabaseUser() + "/"
+ context.getDatabasePassword() + "#"
+ context.getDatabaseHost() + ":"
+ context.getDatabasePort() + "/"
+ context.getSid() + " #"
+ "\""
+ script +"\"";
String path=context.getReleasePath()+ "/Server/DB Scripts";
process = Runtime.getRuntime().exec(cmd,null,new File(path));
out = new OutputStreamWriter(process.getOutputStream());
out.append("commit;\r\n");
out.append("exit \r\n");
System.out.println("---------"+out);
out.close();
Integer result1 = null;
while (result1 == null) {
try {
result1 = process.waitFor();
}
catch (InterruptedException e) {}
}
if(process.exitValue() != 0)
return false;
return true;
}
The code shown fails to read the error stream of the Process. That might be blocking progress. ProcessBuilder was introduced in Java 1.5 and has a handy method to redirectErrorStream() - so that it is only necessary to consume a single stream.
For more general tips, read & implement all the recommendations of When Runtime.exec() won't.
I can see a few issues here. The version of 'exec' that you are using will tokenize the command string using StringTokenizer, so unusual characters in the password (like spaces) or the other parameters being substituted are accidents waiting to happen. I recommend switching to the version
Process exec(String[] cmdarray,
String[] envp,
File dir)
throws IOException
It is a bit more work to use but much more robust.
The second issue that there are all kinds of caveat about whether or not exec will run concurrently with the Java process (see http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Process.html). So you need to say which operating system you're on. If it does not run concurrently then your strategy of writing to the output stream cannot work!
The last bit of the program is written rather obscurely. I suggest ...
for (;;) {
try {
process.waitFor();
return process.exitValue() == 0;
} catch ( InterruptedException _ ) {
System.out.println( "INTERRUPTED!" ); // Debug only.
}
}
This eliminates the superfluous variable result1, eliminates the superfluous boxing and highlights a possible cause of endless looping.
Hope this helps & good luck!