Start and stop postgreSQL service through java code - java

I have one requirement where I need to start and stop postgreSQL service through java code. I have written below code but I am getting below error:
System error 5 has occurred.
Access is denied.
System error 5 has occurred.
Access is denied.
Below is my code:
package frontend.guifx.pginstallation;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import common.core.Logger;
import frontend.guifx.util.ConstPG;
public class StartAndStopPostgres {
public static String version = "9.5";
public static void main(String[] args){
try {
System.out.println("Execution starts");
copyPostgreSqlConfFileAndRestartPg();
System.out.println("Execution finished");
} catch (IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void copyPostgreSqlConfFileAndRestartPg() throws IOException, InterruptedException {
// TODO Auto-generated method stub
Path path = Paths.get("data/PGLogs");
//if directory exists?
if (!Files.exists(path)) {
try {
Files.createDirectories(path);
} catch (IOException e) {
//fail to create directory
e.printStackTrace();
}
}
Logger.print(StartAndStopPostgres.class, new String[] { "Copying postgresql.conf file ........" });
Path source = Paths.get("data/postgresql.windows.conf");
String copyConfFileTo = getInstallationPath(version);
copyConfFileTo = copyConfFileTo.substring(0, copyConfFileTo.lastIndexOf("\\"));
Path outputDirectoryPath = Paths.get(copyConfFileTo+File.separator+"data");
Files.copy(source, outputDirectoryPath.resolve(outputDirectoryPath.getFileSystem().getPath("postgresql.conf")), StandardCopyOption.REPLACE_EXISTING);
Logger.print(StartAndStopPostgres.class, new String[] { "Tunning datbase starts........" });
Runtime rt = Runtime.getRuntime();
final File file = new File(System.getProperty("java.io.tmpdir") + File.separator + ConstPG.CREATE_RESTART_PG_BAT_FILE);
PrintWriter writer = new PrintWriter(file, "UTF-8");
writer.println("net stop postgresql-x64-"+version);
writer.println("net start postgresql-x64-"+version);
writer.close();
String executeSqlCommand = file.getAbsolutePath();
Process process = rt.exec(executeSqlCommand);
/*final List<String> commands = new ArrayList<String>();
commands.add("cmd.exe");
commands.add("/C");
commands.add("net stop postgresql-x64-9.5");
commands.add("net start postgresql-x64-9.5");
ProcessBuilder b = new ProcessBuilder(commands);
Process process = b.start();*/
//public static final String PG_RESTART_PG_LOG_FILE = PG_LOGS+"/pgRestartProcess.log";
File createPgRestartProcessFile = new File(ConstPG.PG_RESTART_PG_LOG_FILE);
redirectProcessExecutionOutput(process, createPgRestartProcessFile);
int exitVal = process.waitFor();
Logger.print(StartAndStopPostgres.class, new String[] { "EXIT VALUE after tunning the PostgreSql database :::::::::::::::::::::" + exitVal + " Logs written to file at: " + createPgRestartProcessFile.getAbsolutePath() });
}
public static String getInstallationPath( String version) {
//public static final String PROGRAMME_FILES = "C:\\Program Files\\";
// public static final String PROGRAMME_FILES_X86 = "C:\\Program Files (x86)\\";
// public static final String POSTGRESQL = "PostgreSQL";
// public static final String PSQL_PATH = "\\bin\\psql.exe";
//Const values used below are as above
String psql = findFile(ConstPG.PROGRAMME_FILES, ConstPG.POSTGRESQL + "\\" + version + ConstPG.PSQL_PATH);
if (psql == null) {
psql = findFile(ConstPG.PROGRAMME_FILES_X86, ConstPG.POSTGRESQL + "\\" + version + ConstPG.PSQL_PATH);
}
if(psql != null){
psql = psql.substring(0, psql.lastIndexOf("\\"));
}
return psql;
}
public static String findFile(String directoryName, String fileName) {
File directory = new File(directoryName);
// get all the files from a directory
File[] fList = directory.listFiles();
String absolutePath;
if (fList != null) {
for (File file : fList) {
if (file.isFile()) {
absolutePath = file.getAbsolutePath();
if (absolutePath.contains(fileName))
return (absolutePath);
} else if (file.isDirectory()) {
absolutePath = findFile(file.getAbsolutePath(), fileName);
if (absolutePath != null)
return (absolutePath);
}
}
}
return (null);
}
private static void redirectProcessExecutionOutput(Process process, File processFile) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line = null;
FileWriter fw = new FileWriter(processFile.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
while ((line = reader.readLine()) != null) {
Logger.print(StartAndStopPostgres.class, new String[] { line });
bw.write(line);
bw.newLine();
}
bw.close();
}
}
If I start my eclipse as an Administrator then this works fine. Also if I run start and stop commands on command prompt (which is opened as an Administrator i.e. right click on command prompt icon and click 'run as Administrator') then they execute successfully. But if I run the commands on normal command prompt (which is not opened as a administrator) then I get the same error there as well.
Please advise if there is any solution or any approach to solve this problem.

In java there is a option to run windows cmd as administrator
replace your code "commands.add("cmd.exe");" with below code and try
commands.add("runas /profile /user:ADMINUSERNAME \"cmd.exe");

Related

JAVA - not able to update data in file that is "resources" folder

I am a little perplexed by the behavior I see in my proof-of-concept test program.
My Java application uses a file that is placed in "resource" folder in the Java project. The application will occasionally read numeric data from it, use it, increment the number and write it back to the same file for the next cycle.
The following test application mimics the above (wanted) behavior:
public class ReadWriteFile {
private static final String TEMP_EMAIL_ID_DATAFILE_PATH = "main/resources/TempEmailId.dat";
public static void main(String[] args) throws ParseException {
try {
int id = readTempId();
System.out.println("Current value = " + id);
writeTempId(id+5);
System.out.println("Updated value = " + readTempId());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static int readTempId() throws IOException {
InputStream is = ReadWriteFile.class.getClassLoader().getResourceAsStream(TEMP_EMAIL_ID_DATAFILE_PATH);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
int currentValue = 0;
while ((line = br.readLine()) != null) {
currentValue = Integer.parseInt(line);
}
br.close();
return currentValue;
}
public static void writeTempId(int currentId) throws IOException {
BufferedWriter bw = new BufferedWriter(new FileWriter("src" + File.separator + TEMP_EMAIL_ID_DATAFILE_PATH));
bw.write(Integer.toString(Math.abs(currentId)));
bw.flush();
bw.close();
return;
}
}
When I run the test, the following is seen:
Current value = 100000054
Updated value = 100000054
My gut feeling is that the use of
ReadWriteFile.class.getClassLoader().getResourceAsStream(TEMP_EMAIL_ID_DATAFILE_PATH);
is causing the issue. I am using this to access the file within the JAVA project.
Can it be true?
Also, note that for creating the BufferedWriter object, I have to pre-pend the Java constant with "src/" - else the file could not be found :(
Thanks.
Resources are intended to be read-only. The only way they could become writable is if they were extracted into the file system, but that's not how they are intended to be used and is not portable as resources are normally in a jar. Write to a file instead
This should work:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.text.ParseException;
public class ReadWriteFile {
private static final String TEMP_EMAIL_ID_DATAFILE_PATH = "TempEmailId.dat";
public static void main(String[] args) throws ParseException, URISyntaxException {
try {
int id = readTempId();
System.out.println("Current value = " + id);
writeTempId(id+5);
System.out.println("Updated value = " + readTempId());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static int readTempId() throws IOException {
InputStream is = ReadWriteFile.class.getClassLoader().getResourceAsStream(TEMP_EMAIL_ID_DATAFILE_PATH);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
int currentValue = 0;
while ((line = br.readLine()) != null) {
currentValue = Integer.parseInt(line);
}
br.close();
return currentValue;
}
public static void writeTempId(int currentId) throws IOException, URISyntaxException {
URL resource = ReadWriteFile.class.getClassLoader().getResource(TEMP_EMAIL_ID_DATAFILE_PATH);
File file = new File(resource.toURI());
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
bw.write(Integer.toString(Math.abs(currentId)));
bw.flush();
bw.close();
return;
}
}
The 2 key lines for writing to file was doing it as such:
URL resource = ReadWriteFile.class.getClassLoader().getResource(TEMP_EMAIL_ID_DATAFILE_PATH);
File file = new File(resource.toURI());

which is the equivalent command for execute a curl command in windows java?

An equivalent command for something like this I don't know which is the correct form to call a batch command
def proc =["/bin/sh", "-c","curl https://stackoverflow.com"]
proc.waitFor()
StringBuffer outputStream = new StringBuffer()
proc.waitForProcessOutput(outputStream, System.err)
String output = outputStream.toString()
Why don't you consider using java.net.URL instead?
Sample code is here
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Hello{
public static void main(String []args){
try
{
URL url = new URL("http://stackoverflow.com");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"))) {
for (String line; (line = reader.readLine()) != null;) {
System.out.println(line);
}
}
}
catch (Exception e)
{
System.out.println("error occured");
}
}
}
instead if you want to invoke the curl command from java use the below
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class ShellFromJava {
public static ArrayList<String> command(final String cmdline,
final String directory) {
try {
Process process =
new ProcessBuilder(new String[] {"bash", "-c", cmdline})
.redirectErrorStream(true)
.directory(new File(directory))
.start();
ArrayList<String> output = new ArrayList<String>();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
while ( (line = br.readLine()) != null )
output.add(line);
if (0 != process.waitFor())
return null;
return output;
} catch (Exception e) {
//Warning: doing this is no good in high-quality applications.
//Instead, present appropriate error messages to the user.
//But it's perfectly fine for prototyping.
return null;
}
}
public static void main(String[] args) {
testHandler("curl http://stackoverflow.com");
}
static void testHandler(String cmdline) {
ArrayList<String> output = command(cmdline, ".");
if (null == output)
System.out.println("\n\n\t\tCOMMAND FAILED: " + cmdline);
else
for (String line : output)
System.out.println(line);
}
}
You can spawn a process from Java:
public class useProcess {
public static void main(String[] args) throws Exception {
String params[] = {"/bin/sh", "-c", "curl", "https://stackoverflow.com"};
Process myProcess = Runtime.getRuntime().exec(params);
myProcess.waitFor();
}
}

Java .jar fails to start because of loading jcombobox data from file

I am beginner with Java and I have tried to make my app better.
So I have a method to fill the jcombobox with items from text file.
The method is
private void fillComboBox(JComboBox combobox, String filepath) throws FileNotFoundException, IOException {
BufferedReader input = new BufferedReader(new FileReader(filepath));
List<String> strings = new ArrayList<String>();
try {
String line = null;
while ((line = input.readLine()) != null) {
strings.add(line);
}
} catch (FileNotFoundException e) {
System.err.println("Error, file " + filepath + " didn't exist.");
} finally {
input.close();
}
String[] lineArray = strings.toArray(new String[]{});
for (int i = 0; i < lineArray.length - 1; i++) {
combobox.addItem(lineArray[i]);
}
}
And I am using it correctly
fillComboBox(jCombobox1, "items");
the text file with items is in my root directory of netbeans project.
It works perfectly when running the app from netbeans. But when I build the project and create .jar file. It does not run. I tried to run it from comand line.
This is what I got.
java.io.FileNotFoundException: items(System cannot find the file.)
How to deal with this? I didnt found anything. I dont know where is problem since it works nice in netbeans. Thank you very much for any help.
Is the .jar file in the same root directory?
Your exported .jar file might be working from a different directory, and not be able to find the text file.
Try placing the exported Jar in the same directory as the text file.
My example:
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;
public class test {
public static void main(String[] args) throws FileNotFoundException, IOException{
JComboBox box = new JComboBox();
fillComboBox(box, "C:\\path\\test.txt");
JOptionPane.showMessageDialog(null, box);
}
private static void fillComboBox(JComboBox combobox, String filepath) throws FileNotFoundException, IOException {
BufferedReader input = new BufferedReader(new FileReader(filepath));
List<String> strings = new ArrayList<String>();
try {
String line = null;
while ((line = input.readLine()) != null) {
strings.add(line);
}
} catch (FileNotFoundException e) {
System.err.println("Error, file " + filepath + " didn't exist.");
} finally {
input.close();
}
String[] lineArray = strings.toArray(new String[] {});
for (int i = 0; i < lineArray.length - 1; i++) {
combobox.addItem(lineArray[i]);
}
}
}

Read from file inside Eclipse Project

I want to make an application that splits a big text file inside inputfolder into several small XML files to be put inside outputfolder.
This is project outline:
The following code works fine when it comes to getting a file from an outside folder, but when I modified it to read from a folder inside the project, it gave me this error:
Exception in thread "main" java.lang.NullPointerException
at com.zakaria.cut.XmlCutter.cut(XmlCutter.java:45)
at com.zakaria.cut.Main.main(Main.java:8)
[XmlCutter.java]
package com.zakaria.cut;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.text.MessageFormat;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
public class XmlCutter {
private static final String OUTPUT_FILE_NAME = "/file";
//private static String USER_HOME = System.getProperty("user.home");
private static final String INPUT_FOLDER = "../inputfolder";
private static String OUTPUT_FOLDER = "../outputfolder";
private static Logger LOG = Logger.getLogger("XmlCutter");
private static long COUNTER = 0;
public XmlCutter() {
super();
// TODO Auto-generated constructor stub
}
public void cut() {
Handler h = new ConsoleHandler();
h.setLevel(Level.FINE);
LOG.addHandler(h);
LOG.setLevel(Level.FINE);
File inputDir = new File(INPUT_FOLDER);
File[] filesInInputDir = inputDir.listFiles();
for (File f : filesInInputDir) {
if ((f.getName()).endsWith(".txt")) {
LOG.fine((MessageFormat.format(
"Found a text file {0}. Processing docs...",
f.getName())));
processFile(f);
}
}
}
private static void processFile(File f) {
StringBuilder out = new StringBuilder();
char prev = '#';
try {
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(f), "UTF8"));
char[] buf = new char[1];
while (br.read(buf) >= 0) {
out.append(buf[0]);
if (prev == '<' && buf[0] == '?') {
LOG.finest((MessageFormat.format(
"Start of XML PI Found: {0}{1}", prev, buf[0])));
if (out.length() > 2) {
flushToFile(out.substring(0, out.length() - 2));
}
out.setLength(2);
}
prev = buf[0];
}
LOG.finest("Writing final file");
flushToFile(out.toString());
br.close();
} catch (IOException e) {
LOG.fine(e.getMessage());
}
LOG.fine(MessageFormat.format("Generated {0} XML Documents", COUNTER));
}
private static void flushToFile(String s) {
File f = new File(OUTPUT_FOLDER + OUTPUT_FILE_NAME + (++COUNTER)
+ ".xml");
LOG.finest(MessageFormat.format("Writing file: {0}", f.getName()));
try {
FileOutputStream fos = new FileOutputStream(f);
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF8");
osw.write(s);
osw.flush();
} catch (IOException e) {
LOG.fine(e.getMessage());
}
}
}
[Main.java]
package com.zakaria.cut;
public class Main {
public static void main(String[] args) {
XmlCutter cutter = new XmlCutter();
cutter.cut();
}
}
The problem, I guess, is definitely here:
private static final String INPUT_FOLDER = "../inputfolder";
private static String OUTPUT_FOLDER = "../outputfolder";
How can I fix it?
Do you know what folder the program is executing from? My guess is the relative links are pointing to the wrong spot? Have you tried hard coding the paths and see if they work? If they do you might have to look at the your execution folder and then change the relative paths accordingly?

Switching to specific window using PID (Process ID)

I'm working on a Java Selenium program which uses Runtime class.
There are multiple instances of Internet Explorer windows that are open.
I need to "Bring Front" only one specific window for the selenium suite to run without errors.I have retrieved the specific iexplore instance using tasklist command.
Now I have the PID of the process.
Process p = Runtime.getRuntime().exec("tasklist /FI \"WindowTitle eq Google\"");
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
int count=1;
while ((line = in.readLine()) != null) {
System.out.println(count + " " + line);
count++;
}
How to bring a process to the front (make it the active window) through Runtime command line using its PID?
EDIT:
Is there a way to switch to an application window from command prompt using the PID of the application?
To switch to an application window from command prompt you can use Windows Script Host's AppActivate function. It accepts either ProcessID or window's title as its argument. Here is a simple script:
set WshShell = CreateObject("WScript.Shell")
WshShell.AppActivate Wscript.Arguments(0)
Then call the script by using cscript AppActivate.vbs 1234
I tried to apply the advice above into a complete solution
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.apache.commons.io.FileUtils.writeStringToFile;
import static org.apache.commons.lang3.math.NumberUtils.toInt;
public class WindowSwither {
private static final Pattern TASKLIST_CSV_PATTERN = Pattern.compile("\".*?\",\"(\\d+)\".*");
private int pidActive = 0;
private final List<Integer> pidList = new ArrayList<>();
public WindowSwither(String exeName) throws IOException {
Process p = Runtime.getRuntime().exec("tasklist /FI \"ImageName eq " + exeName + ".exe\" /FO CSV");
for (String line : showProcessOut(p)) {
Matcher m = TASKLIST_CSV_PATTERN.matcher(line);
if (m.find()) {
pidList.add(toInt(m.group(1)));
}
}
}
public void next() throws IOException {
if (pidList.size() == 0) {
System.out.println("List empty! Ignored.");
return;
}
if (pidActive == 0) {
pidActive = pidList.get(0);
System.out.println("[0] " + pidActive);
} else {
Iterator<Integer> it = pidList.iterator();
while (it.hasNext()) {
Integer pid = it.next();
if (pid == pidActive) {
break;
}
}
if (it.hasNext()) {
pidActive = it.next();
System.out.println("[+] " + pidActive);
} else {
pidActive = pidList.get(0);
System.out.println("[0] " + pidActive);
}
}
activate(pidActive);
}
private static void activate(int pid) throws IOException {
String pathname = System.getProperty("java.io.tmpdir") + "WindowSwintcherAppActivate.vbs";
File file = new File(pathname);
if (!file.exists()) {
String content = "set WshShell = CreateObject(\"WScript.Shell\")\n" +
"WshShell.AppActivate Wscript.Arguments(0)";
writeStringToFile(file, content, StandardCharsets.UTF_8);
}
Runtime.getRuntime().exec("cscript " + pathname + " " + pid);
}
private List<String> showProcessOut(Process p) throws IOException {
List<String> list = new ArrayList<>();
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream(), "cp866"));
String line;
while ((line = in.readLine()) != null) {
list.add(line);
}
return list;
}
}
Main class
public class EnumerateWindows {
public static void main(String[] args) throws IOException, InterruptedException {
WindowSwither swither = new WindowSwither("notepad");
swither.next();
Thread.sleep(1000);
swither.next();
Thread.sleep(1000);
swither.next();
Thread.sleep(1000);
swither.next();
Thread.sleep(1000);
}
}

Categories