File path is not recognized when executing an external command from a Java application

Note that I got stuck when I implemented XML signature in Java.

Execute keytool -import keystore command from Java application

But not imported. .. .. The following three methods are related at the time of execution, and they are executed in the order of importProcessExec ⇒ getImportCommand ⇒ processExec.

sample.java


    /**
     *Execute the certificate import command.
     *
     * @param certFilePath Certificate file
     * @param destAlias Distinguished name
     * @param keyStoreFilePath Keystore file
     * @param certificatePass Certificate password
     * @param keyStorePass Keystore password
     * @return true:Successful completion, false:Abnormal termination
     * @throws InterruptedException
     */
    private boolean importProcessExec(File keyStoreFile, String destAlias, File certFile,
            String certificatePass,
            String keyStorePass) throws InterruptedException {
        //Command to import certificate
        List<String> command = getImportCommand(keyStoreFile, destAlias, certFile, certificatePass,
                keyStorePass);
        //Import command execution
        return processExec(command);
    }

    /**
     *Get the certificate import command.
     *
     * @param certFilePath Certificate file
     * @param destAlias Distinguished name
     * @param keyStoreFilePath Keystore file
     * @param certificatePass Certificate password
     * @param keyStorePass Keystore password
     * @return resultList import command
     */
    private List<String> getImportCommand(File keyStoreFile, String destAlias, File certFile,
            String certificatePass, String keyStorePass) {
        //Command to import certificate
        String command = "keytool -importkeystore -keystore %keyStoreFilePath% -srckeystore %certFilePath% -srcstoretype PKCS12 -srcalias 1 -destalias %destalias% -srcstorepass %certificatePass% -deststorepass %keyStorePass%";

        //Split the command into a string array
        String[] commandList = command.split(" ");

        List<String> resultList = new ArrayList<String>();

        for (String cmd : commandList) {
            switch (cmd) {
            case "%keyStoreFilePath%":
                cmd = cmd.replace("%keyStoreFilePath%", includeDoubleQuotes(keyStoreFile.getPath()));
                break;
            case "%certFilePath%":
                cmd = cmd.replace("%certFilePath%", includeDoubleQuotes(certFile.getPath()));
                break;
            case "%destalias%":
                cmd = cmd.replace("%destalias%", destAlias);
                break;
            case "%certificatePass%":
                cmd = cmd.replace("%certificatePass%", certificatePass);
                break;
            case "%keyStorePass%":
                cmd = cmd.replace("%keyStorePass%", keyStorePass);
                break;
            }
            resultList.add(cmd);
        }

        return resultList;
    }

    /**
     *Run an external process.
     *
     * @param command Command contents
     * @return true:Successful completion, false:Abnormal termination
     */
    private boolean processExec(List<String> command) {
        //Processing result
        boolean result = false;

        try {
            ProcessBuilder processBuilder = new ProcessBuilder(command);
            Process Process = processBuilder.start();

            //Wait until the process ends normally
            if (Process.waitFor() == 0) {
                result = true;
                log.info("Process Success: " + command.toString());
            } else {
                log.warn("Process Failed: " + command.toString());
            }

            //Standard output
            String strInput;
            BufferedReader ipbr = new BufferedReader(new InputStreamReader(Process.getInputStream()));
            while((strInput = ipbr.readLine()) != null) {
                log.info(strInput);
            }
            ipbr.close();

            //Error output
            String strErr;
            BufferedReader erbr = new BufferedReader(new InputStreamReader(Process.getErrorStream()));
            while((strErr = erbr.readLine()) != null) {
                log.info(strErr);
            }
            erbr.close();

            //InputStream in the background after using ProcessBuilder, OutputStream,ErrorStream is opened.
            //Close all streams to avoid running out of resources.
            Process.getInputStream().close();
            Process.getOutputStream().close();
            Process.getErrorStream().close();
        } catch (InterruptedException | IOException e) {
            //TODO auto-generated catch block
            e.printStackTrace();
        }

        return result;
    }

    /**
     *Enclose the string in double quotes.
     *
     * @param str string
     * @return A string enclosed in double quotes
     */
    private String includeDoubleQuotes(String str) {
        return "\"" + str + "\""; 
    }

[Cause] The certificate file path is enclosed in "" ".

Method: In includeDoubleQuotes, the certificate file path is enclosed in "" ", and the command executed from the Java application

keytool -importkeystore -keystore "/.../XXXX.keystore" -srckeystore "/.../XXXX.p12" -srcstoretype PKCS12 -srcstorepass root -deststorepass changeit

Seems to have not been executed normally. It worked correctly by excluding the function that added "" ".

The development environment was Windows, and the location of the certificate was under Program Files. The file path contains a half-width space, and the command could not be executed normally unless the file path of the certificate was enclosed in "" ", so I tried to bite the function and add" "".

You need to be careful about the processing of such an external process execution system. For example, it may be dangerous if you do not create a virtual environment of linux on windows, deploy it there and check the operation. .. ..

Recommended Posts

File path is not recognized when executing an external command from a Java application
[Unresolved] An exception occurs when an SSH connection is executed using JSch from a Java 6 application.
When calling println etc. from an external Java class file in Processing
Send a command to Spigot from an external process
When a Java file created with the Atom editor is garbled when executed at the command prompt
Run a batch file from Java
Access Teradata from a Java application
Java Calendar is not a singleton.
When calling sshpass from Java with shell etc., it seems that it is necessary to have a path.
Even though the property file path is specified in the -cp option, it is not recognized as a classpath.
Cause of is not visible when calling a method of another class in java
Connect to Aurora (MySQL) from a Java application
[Java] Get a random value from an array
When I call the file with Class # getResource from the jar file, it becomes Not Found and it is a crappy memorandum
[Ruby] When executing rb file when Rails / Sinatra is not used, i18n gets angry with ʻen is not a valid locale (I18n :: InvalidLocale)'
[Ruby on rails] When executing the heroku command, bash: heroku: command not found is displayed. [Rails tutorial]
How to jump from Eclipse Java to a SQL file
[Java] How to extract the file name from the path
Load an external jar from a Spring Boot fat jar
Java11: Run Java code in a single file as is