I want to run a java program on my local PC which connects to a remote PC with ssh and executes some methods (java code, not bash scripts!) there. I found for example JSch which enables the ssh connection with and remote execution of code with something like
JSch jsch=new JSch();
Session session=jsch.getSession(user, host, 22);
session.setPassword(passwd);
Channel channel=session.openChannel("shell");
channel.setInputStream(System.in);
(from http://www.jcraft.com/jsch/examples/Shell.java.html)
or ssxcute which can be used with
ConnBean cb = new ConnBean("ip ", "username","password");
ssh = SSHExec.getInstance(cb);
ssh.connect();
CustomTask sampleTask = new ExecCommand("echo 123");
ssh.exec(sampleTask);
(from https://code.google.com/p/sshxcute/)
but what I want to do is something like
...
ssh.connect();
MyExecuteClass execClass = new MyExecuteClass();
ssh.exec(execClass.runLongJob(a, b, c));
MyReturn return = ssh.getReturnValue();
Is this possible? The objects a,b,c would have to be transmitted to the remote system, as well as all global variables, other classes, imports,... And the return value of the method must be returned somehow... If other objects are modified in the runLongjob method those changes have to be send back to the local PC as well.
Is there a solution for this?
What you want to do basically not only requires your objects to be serialized, transmitted and deserialized on the remote system, but also that a Java VM is present and started on the host and has the classes for your transmitted instances in its class path. I doubt you will find an out-of-the-box solution for that. You could use something like RMI to communicate with a running JVM on the remote host, though.
I don't know of any frameworks to do specifically what you describe. The closest thing that comes to mind is to use web services. They allow you to define service running on a remote server which answers requests. The requests and responses can contain complex data structures. There are mature libraries for developing web services in java.
See these:
Introduction to Web Services
Building Web Services with JAX-WS
Related
I'm programming a little server example with Sockets in Java.
Currently I'm using this for testing:
server= new Socket(InetAdress.getByName("127.0.0.1"),3333)
but my plan is to move it to my Raspberry Pi.
Unfortunately, I don't have a static IP address.
What is the proper way to update the IP address in the code?
I thought about storing it on a webserver and accessing it via an API, but that doesn't sound very secure, and it might slow down my code.
First off, your use of InetAdress.getByName() is redundant. Socket has a constructor that accepts a String as input:
server = new Socket("127.0.0.1", 3333)
That said, you should register a static domain name for your server, and set its DNS records to point at your server's IP. Then clients can use that domain name to connect to the server, instead of using the IP address directly:
server = new Socket("mydomain", 3333)
If your server does not have a static IP, there are plenty of free and cheap "Dynamic DNS" services available, which allow you to update your domain with your current IP address whenever it changes (typically using automated tools to simplify the detection-and-update process).
If the server is behind a router, many routers have built-in support for updating various DynDNS services for you. If your router supports this, you can configure it with your DynDNS account information so it can automatically update the domain whenever its WAN IP changes.
I have two servers, one that runs my program written in Java (Server A) and one that stores a graph (Server B) that must be continuously accessed by Server A. To access Server B you must ssh with a username and password using Server B's IP address.
As of now I have failed to find a method to continuously access a directory on a different server and I am wondering if anyone knows a method that lets me do this (or if it is not possible, if there is a workaround).
I have looked into SSH libraries, but they all seem to only give you access to the directory for a brief amount of time. I need continuos access because I write and read from the graph on Server B all the time.
I basically want to make a proxy directory on Server A that actually refers/links to the directory on Server B:
graphDb = new EmbeddedGraphDatabase("/192.168.1.**/media/graphDB");
Any help would be great.
Probably unrelated option:
If client and server are Linux machines, you can use rsync to synchronize files between them. In that way you have a copy of the files on server A. The rsync command could be executed from the Java program or periodically from a cronjob on server A.
You could write your own client/server service, so that the server service provide you with the means to send data over the network to. It tends to be a lot of work though.
You could write your self a "heart beat" service on the client that tests the SSH connection and reestablishes it if it closes
You could "test" the ssh connection before you writing/reading from the connection
You could do as AlperAkture suggests (and mount the directory as a remote drive)
I am trying to use RMI to open notepad in the remote system.
Is it possible to do that using RMI??
Or do I have to use SSH ??
Comparing RMI with SSH is a bit like comparing apples with oranges. RMI is more of a general purpose API for performing requests over the network, while SSH is a program used to establish a secure shell connection over which you can send shell commands.
To open Notepad on a remote host, you can use either RMI or SSH since both are capable of communicating over the network.
In either case, you'll need a server on the receiving end, that handles your commands and opens Notepad for you. If you use SSH, this will be readily available to you, in the form of an sshd daemon. In case you go for RMI I don't know of any predefined server implementation. I would recommend you to write up your own server serving your particular requests.
I have two secured linux servers. In one machine my Java application is running. I need to run Linux commands on second machine from first machine in Java. How might I do this?
Jsch (here) allows you to connect to a remote server using SSH and executes shell commands easily (and lot of other things like SCP, SFTP...). There is not a lot of documentation, but you have a few really helpful implementation examples here (and even an example of what you want to do here).
You can also combine Jsch with Expect4j and this way have a better control on the commands you want to execute (nice example here).
Essentially, you need to open an ssh connection to the other server from within your Java application. The OpenSSH site has some useful information on libraries that will give you ssh support in Java.
It looks like Ganymed SSH-2 for Java is the nicest of the pick there, but I haven't used any of them so you will need to look at what you need.
Once you have an ssh connection, you will be able to run commands just as if you logged in using any other ssh client.
You can do it a number of ways; however, nearly every way involves a network connection.
You could write a client-server pair of Java programs, with the client connection to a server and submitting the command.
You could write your Java to use an existing server, like sshd, telnetd, rsh, ftpd, or a pre-existing other server which allows commands at the remote end.
You could leverage an architecture which handles certain aspects of establishing a client-server pair, like RMI, SOAP, CORBA, etc.
In the end Java supports tons of networking options, so you have more ways of doing this than you think. Just make sure you don't do it in a web browser, as those JVMs are launched sandboxed, and you can't get out of the sandbox without some assistance.
It might be easier to check out Sockets, as you can do what you're trying to do without having to get any external libraries set up.
On the host machine, you want to set up a ServerSocket object, and from the client machine you open a Socket. I don't have time to type up a whole example, but check this out for a simple way to set up a server-host connection over the Internet in Java.
http://zerioh.tripod.com/ressources/sockets.html
Once you get that set up, you want to input your shell command from the ServerSocket on the computer that should execute the command, and do something around the lines of
String command = "get this from the ObjectInputStream attached to your ServerSocket";
Runtime run = Runtime.getRuntime();
Process pr = run.exec(command) ;
pr.waitFor() ;
BufferedReader buffer = new BufferedReader( new InputStreamReader( pr.getInputStream() ) ) ;
String line;
while ( ( line = buffer.readLine() ) != null )
{
System.out.println(line);
}
The tricky part is setting up a realiable host-client connection with the Sockets, but if you're doing something simple you should be fine with the example from the link above.
I am more than novice in Linux. Nevertheless, I need to create a Java Web Service hosting in apache server in a Linux system. The Web service must use ssh to connect to a remote machine, create a txt file, execute a prog.exe (compiled C program in MPI) and then retrieve and return a single output value. The only thing that I do not know is how to connect remotely with the Web Service. In a shell will use something like:
ssh username#remotemachine
and then we will get a prompt for password.
Is it possible to send the password along with the ssh command? I have read that it is possible to connect in one shot with public/private keys but this project is my Master Thesis one and as a result, the machines are these of the uni. So, I do not want to mess with the technicians because most of the times simple do not help at all.
Thanks very much
Most Ssh clients will recognize the following
ssh username#remotemachine -pw'YourPassword'
However, I used GanymedeSSH for Java and it had a method like this:
conn = new Connection(servername, 22);
conn.connect();
conn.authenticateWithPassword(username, password);
session = conn.openSession();
And as long as you keep reference to your session, you will be able to use it to execute commands on the remote machine.
You could use the library Jaramiko to get over the problem (instead of calling ssh externally).