Backing up MySQL database from java app - java

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.

Related

Is it possible to delay or overwrite windows cannot find 'acrord32.exe' error message in java

I need to use both executable files of Adobe reader to open documents.
acrord32.exe for the users using adobe acrobat reader and acrobat.exe for the users using adobe acrobat pro.
I have used system parameters to get done the job.
But my problem is that whenever I use the acrobat.exe version this error message is coming.
After clicking ok then my pdf file opens from acrobat.exe.
So I just want to delay/overwrite/remove this message by using java...
Here is my code
public static void openPDF(Container container, String fileName) throws Exception, PrintException {
SystemParameterHome paramHome = (SystemParameterHome) container.getHomeForEntityBean();
try {
String pdfParameter = "PDF_COMMAND";
SystemParameterObject pdfCommand = paramHome.findByPrimaryKey(pdfParameter);
String command = pdfCommand.getStringValue();
Process proc = Runtime.getRuntime().exec(command + " \"" + fileName + "\"");
int exitVal = proc.waitFor();
if(exitVal != 0) {
System.out.println("exit value in if: "+ exitVal);
pdfParameter = "PDF_COMMAND_64";
pdfCommand = paramHome.findByPrimaryKey(pdfParameter);
command = pdfCommand.getStringValue();
Runtime.getRuntime().exec(command + " \"" + fileName + "\"");
throw new PrintException("There was an error in printing. Please contact a system administrator.");
}else {
System.out.println("exit value in else "+ exitVal);
}
}
catch (Exception e) {
e.printStackTrace();
}

Ubuntu giving permissions from java

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

Get Motherboard Serial/ID On Linux Machine With Java For Anti-Piracy Usage

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())

Issues with running Runtime.getRuntime().exec

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!

Can't get motherboard serial number

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.

Categories