【发布时间】:2016-09-23 15:00:00
【问题描述】:
我有一个要求,我需要通过 java 代码启动和停止 postgreSQL 服务。我写了下面的代码,但出现以下错误:
System error 5 has occurred.
Access is denied.
System error 5 has occurred.
Access is denied.
下面是我的代码:
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();
}
}
如果我以管理员身份启动我的 Eclipse,那么这可以正常工作。此外,如果我在命令提示符下运行启动和停止命令(以管理员身份打开,即右键单击命令提示符图标并单击“以管理员身份运行”),那么它们会成功执行。但是,如果我在普通命令提示符下运行命令(未以管理员身份打开),那么我也会在那里得到同样的错误。
请告知是否有任何解决方案或任何方法可以解决此问题。
【问题讨论】:
-
您需要授予运行程序的用户启动和停止服务的权限。这与 Java 或 Postgres 无关。这是一个 Windows 管理问题。
-
我正在使用两种方法来运行 star 和 stop 命令。第一个是,在上面的代码中,我正在创建一个批处理文件并编写两个命令并执行批处理文件。在第二种方法中,我将命令添加到一个数组列表中,并将数组列表传递给 processBuilder。
-
有没有什么办法可以通过java程序给予这样的特权?
-
这无关紧要。
net stop或net start需要普通用户通常没有的权限。给该用户特权,一切都很好。 -
如果用户没有启动和停止服务的权限,用户也没有能力授予该权限(如果用户有授予服务权限的特权,他/她无论如何都是管理员,并且已经拥有启动或停止服务的特权)。应用程序不应授予自己所需(或要求)的权限。这正是该服务器管理员的职责。
标签: java windows postgresql