【问题标题】:Start and stop postgreSQL service through java code通过java代码启动和停止postgreSQL服务
【发布时间】: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 stopnet start 需要普通用户通常没有的权限。给该用户特权,一切都很好。
  • 如果用户没有启动和停止服务的权限,用户也没有能力授予该权限(如果用户授予服务权限的特权,他/她无论如何都是管理员,并且已经拥有启动或停止服务的特权)。应用程序不应授予自己所需(或要求)的权限。这正是该服务器管理员的职责。

标签: java windows postgresql


【解决方案1】:

在java中有一个以管理员身份运行windows cmd的选项

用以下代码替换您的代码“commands.add("cmd.exe");”并尝试

commands.add("runas /profile /user:ADMINUSERNAME \"cmd.exe");

【讨论】:

  • 通过此更改,我得到以下异常:java.io.IOException:无法运行程序“runas /profile /user:ADMINUSERNAME”cmd.exe”:CreateProcess error=2,系统找不到文件在 java.lang.ProcessBuilder.start(ProcessBuilder.java:1048) at frontend.guifx.pginstallation.StartAndStopPostgres.main(StartAndStopPostgres.java:25) 引起:java.io.IOException: CreateProcess error=2,系统找不到指定的文件
猜你喜欢
  • 2015-07-23
  • 1970-01-01
  • 2014-05-14
  • 2012-05-06
  • 1970-01-01
  • 2014-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多