-3

I am currently trying to retrieve JSON files from an Unix server.

I used JSch to do my connection, which works fine. Now my challenge is to send a command (more or less a few cd and ls, so a very simple one) to the server.

The thing is I am getting an error, and I'm stuck.

Here is the code of the servlet:

import java.io.IOException;
import java.io.PrintWriter;

import static java.lang.System.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import java.lang.Runtime;

@WebServlet("/ConnexionRecette")
public class ConnexionRecette extends HttpServlet {

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String user = "xxxx";
        String password = "xxxxxx!";
        String host = "xxxxxx";
        int port = 22;

        // String remoteFile = "xxxxxxxxxx";

        PrintWriter out = response.getWriter();
        response.setContentType("text/html");
        out.println("<html>");
        out.println("<head><title>Connect to serv test</title></head>");
        out.println("<body>");
        out.println("<br>print avant try");

        try {
            JSch jsch = new JSch();
            Session session = jsch.getSession(user, host, port);
            session.setPassword(password);
            session.setConfig("StrictHostKeyChecking", "no");
            out.println("<br>Establishing Connection...");
            session.connect();
            out.println("<br>Connection established.");
            out.println("<br>Crating SFTP Channel.");
            ChannelSftp sftpChannel = (ChannelSftp) session.openChannel("sftp");
            sftpChannel.connect();
            out.println("<br>SFTP Channel created.");
            out.println("<br> ********** Ok on serv, end of connection code, end of try. **********");


            Runtime runtime = Runtime.getRuntime();
            String[] args = { "cd .."};
            final Process process = runtime.exec(args);
        BufferedReader output = getOutput(process);
        BufferedReader error = getError(process);
        String line = "";


        while((line = output.readLine()) != null) {
            out.println(line);
        }

        while((line = error.readLine()) != null) {
            out.println(line);
        }
        process.waitFor();

    } catch (IOException e) {
        out.println("<br>Print in catch IO");
        out.println("<br>*********************<br>");
        e.printStackTrace();
        out.println("<br>*********************<br>");

    } catch (InterruptedException e) {
        out.println("<br>Print in catch Interrupted");
        out.println("<br>*********************<br>");
        out.println("<br>*********************<br>");
        e.printStackTrace();

    }
        out.println("<br>print après le try catch");
        out.println("</body>");
        out.println("</html>");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doGet(request, response);
    }

}

The error when calling the servlet:

Cannot run program "ssh": CreateProcess error=2, Le fichier spécifié est introuvable

java.io.IOException: Cannot run program "cd ..": CreateProcess error=2, Le fichier spécifié est introuvable
at java.lang.ProcessBuilder.start(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at ConnexionRecette.doGet(ConnexionRecette.java:92)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1100)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:687)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)

Caused by: java.io.IOException: CreateProcess error=2, Le fichier spécifié est introuvable at java.lang.ProcessImpl.create(Native Method) at java.lang.ProcessImpl.(Unknown Source) at java.lang.ProcessImpl.start(Unknown Source)

Thanks in advance!

Matieu
  • 39
  • 2
  • 10
  • None of the code that you posted appears to attempt to run the ssh program. Are you sure you posted the relevant source code? Which specific line of code is producing the error? – Kenster Sep 14 '16 at 16:31
  • [CreateProcess](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx) is _Win_ specific. Hmm, I doubt that _JSch_ may call _ssh_ internally... – CristiFati Sep 14 '16 at 16:38
  • Also, you do realize that you can `cd ../xxx/xxxx/xxx/JSON/xxxx` all in one shot, rather than your extremely inefficient sequence of separate `cd` commands, right? In addition, I don't think prefixing that whole thing with `sudo su -` is going to do what you think it does... – twalberg Sep 14 '16 at 17:37
  • Show us exception callstack. – Martin Prikryl Sep 14 '16 at 18:18
  • About the sudo su - : i need to switch in root when i connect to the server, if not i won't have access to the folder i need, and for the whole command i didn't know, not really expert in Unix Shell.. – Matieu Sep 15 '16 at 07:16
  • But you didn't add the exception callstack. – Martin Prikryl Sep 15 '16 at 08:21
  • So I updated the code, StackTrace is now here. I changed the shell command with a new and very basic one, just for the example. I get the HTTP 500 error now. – Matieu Sep 15 '16 at 09:23
  • Possible duplicate of [Run a command over SSH with JSch](http://stackoverflow.com/questions/2405885/run-a-command-over-ssh-with-jsch) – Martin Prikryl Sep 15 '16 at 09:54
  • OK, only now I've noticed the nonsense you are trying to do. You are running the `ssh` locally, you do not use the JSch at all. See the linked question for correct code. – Martin Prikryl Sep 15 '16 at 09:55

1 Answers1

0

java.io.IOException: Cannot run program "cd ..": CreateProcess error=2, Le fichier spécifié est introuvable

cd is not a program. It is an internal command that is used to change the current directory of a running shell.

Each running process has a current directory. It cannot be changed by launching an external program. If you want to change the current directory of your code then you should use a library function provided by the language you are using. I don't know Java but if you search your documentation for chdir or changeDirectory I'm sure you find the correct way to do it.

On the other hand, if you want to change the current directory on the remote connection you just opened then you should either issue the command through the sftpChannel object or, more probably, use one of its methods to change the remote directory. (Again, this is just programming common sense, I don't know anything about Java or sftpChannel).

axiac
  • 68,258
  • 9
  • 99
  • 134