Apache Commons Net FTPClient - PUT instead of STOR? - java

I am using the Apache commons net FTPClient to distribute files as part of batch jobs. The client is encapsulated, but roughly I issue the following method calls (i have omitted error handling, stream handling etc. for brevity):
FTPClient client = new FTPClient();
client.connect("127.0.0.1", 22);
client.login("user", "password");
client.setFileType(FTP.BINARY_FILE_TYPE);
client.changeWorkingDirectory("path/");
client.storeFile("file1.txt", new ByteArrayInputStream("hello world".getBytes()));
client.disconnect();
When I issue the commands above, The following commands are sent to the FTP server:
USER zoor
PASS ********
TYPE I
CWD path/
PORT 127,0,0,1,229,72
STOR file1.txt
And this works fine. Now, however, I am in a situation where i need to send files to a legacy system which does not support CWD or STOR but instead relies on CD and PUT, respectively..
Now my question is, how do I make the FTPClient use these commands?
I could use the sendCommand method to send the CD command, but I am not sure how to do this properly (and correctly) with the PUT command (given that I must send the file data also).
NOTE: I realize that there are better ways than FTP to distribute files like this, but unfortunately, my hands are bound. The recipients are using FTP and are not willing to change.
UPDATE: The legacy system is an AS/400 machine.

It occurred to me that CD and PUT are not actually FTP commands and as such the question makes little sense.. The solution (because we need it to work ASAP) is that we transfer the files to our own FTP server, and call a script via SSH on that server that transfers the files to the AS/400 machine.

This should work, I understand you worked around the issue, but for sake of completeness, do you know if AS/400 needs any site commands to store the file.
What is the error your getting back?
I regularly send files to MVS / Z/OS and there are a few site commands that need to be sent first for storage and setup.
Site commands would look something like:
TRAIL
CYLINDERS PRIMARY=350 SECONDARY=300
RECFM=FB LRECL=1516 BLKSIZE=31836
CONDDISP=delete
Here's a little code that I use, ftp is essentially the FTPClient that you use in your example.
public boolean sendSiteCommand(String siteCmd){
if (null == siteCmd){
System.err.println("Warning, Null Parameter sent to sendSiteCommand, aborting...");
return false;
}
try{
return ftp.sendSiteCommand(siteCmd);
}catch (Exception e){
System.out.println("Error Occurred Sending Site Command to Remote System, aborting...");
e.printStackTrace(System.err);
return false;
}
}

If you truly need to upload a file as another command, you can always extend FTPClient and call the internal methods with a different command. They are built that you can give any string as the command to the already existing stores.
Example:
public static class OldFtpClient extends FTPClient {
public OutputStream putFileStream(String remote) throws IOException {
return _storeFileStream("PUT", remote);
}
}
Source of class can be found at https://github.com/apache/commons-net/blob/master/src/main/java/org/apache/commons/net/ftp/FTPClient.java .

Related

Running Unix command , after connecting through ftp using java

I am not authorized to use ssh/sftp( using private/public key). So ftp is my only choice.
The following piece of code works just fine for me, fetching the file from Unix box, but my motto is to log in to a UNIX box from windows, using java,then from my home directory go to a different directory and use grep, then copy that output back to my windows java program. I was looking for how to execute some Unix command in the box. as we do it in shell/python/ant...
new URL("ftp://user:password#url/sourcefile;type=i");
URLConnection con = url.openConnection();
BufferedInputStream in =
new BufferedInputStream(con.getInputStream());
FileOutputStream out =
new FileOutputStream("Targetfile");
If you have username and password then you can go for Jsch library.
Have a look at this or directly run it !!
http://www.jcraft.com/jsch/examples/Shell.java.html
Similarly you can all shell commands from this.
FTP is a file transfer protocol. It's not a general-purpose remote access protocol. It doesn't have built-in support for a client to run arbitrary commands on the FTP server.
FTP does have a command called SITE which permits running custom commands on the server. To use it, the FTP server's administrator would have to set up a custom command that meets your needs. Then you'd have to use a real FTP client library to invoke the site command on the remote server--calling openConnection() on an FTP URL won't let you invoke site commands.

Java, how to create new directory in remote host.

I'm working on Android app.
how can i create a new directory in a remote host in java?
I tried this but it doesn't work:
String newFolder = "http://www.mysite.it/public/newfolder";
File outFile = new File(newFolder);
if(!outFile.exists()){
boolean b = outFile.mkdirs();
}
Thank you so much!
It can not be done this way. You need to send a command to your server and create the directory from your server.
Then you can send an acknowledgement back to your client
First of all: The folder is remote.
When using File you are accessing the local file system.
To connection to a remote host, you will need a URLConnection, HTTPUrlConnection or sockets.
So the file constructed using your string won't represent a valid file.
Creating folders on a remote host require the use of protocols such as ssh or ftp.
As an example:
URL url = new URL("ftp://mirror.csclub.uwaterloo.ca/index.html");
URLConnection urlConnection = url.openConnection();
would open a ftp - connection to host mirror.csclub.uwaterloo.ca requesting a file named index.html.
command - line ftp clients can send commands for creating folders to the remote host, e.g.
ftp anonoumos#somehost.com
# mkdir folderName
so you would have to send this command to your ftp host. For ssh it's basically the same procedure.
Both requires a basic client, though.
There are existing solutions around in the Java World, but I don't know of any for Android.
So while uploading a file to a host via ftp is pretty straight forward, (take a look at this example http://www.codejava.net/java-se/networking/ftp/upload-files-to-ftp-server-using-urlconnection-class), sending commands via ftp seems to be a lot more complicated task.
org.apache.commons.net.ftp.FTPClient e.g. supports sending commands via it's doCommand - method, but I don't know if you get it to work on android.

store a file into a ftp server using apache commons doesn't work

I am trying to store a file into a ftp server using apache commons java library. I am using commons-net-3.0.1.jar. The problem is when ever i try to push the file into server, the call
StoreFile()
returns false always. It doesn't throw any exception. nothing at all,just reply false silently. If i try to push the file manually i.e using normal "ftp" client in linux systems (I meant connecting to ftp server using ftp command and storing the file using put command), then it puts the file into server.
I have no idea of how to debug it even. Can you please let me know how i can get to know the problem and its solution.
I checked the server logs, when ever i am trying to post through java the log says 425 response code failed to establish connection. But when i use manually it shows 226 response.
Note: FTP is not a reliable protocol to upload/download data to/from a server with code. If you need a reliable solution, FTP is not for you. Try ssh instead.
To answer your question: Add a ProtocolCommandListener to your SocketClient (FTP extends this). Then you can at least print the messages in ProtocolCommandListener() and protocolReplyReceived()

Connect to Unix File System using Java Program

I want to establish a connection with my UNIX file system using java program.. So that I can make some File I/O operations and normally I can connect using Putty.
How can I do the same using java program
I have the Host name, username,password and Port number
Help appreciated :)
You need several things:
A server that takes commands (create directory, list directory, write data to a file, read data from a file) over the network. This server should listen to port1 on localhost
You need to configure putty to forward port2 on your local computer to port1 on the server.
A local client which allows you to connect to port2 on your local computer. Putty will tunnel any data send to port2 to port1 on the remote server and vice versa.
Or you get WinSCP which uses the SSH protocol (just like Putty) and maybe already does what you want.
There's a pure Java implementation of SSH/SCP available: http://www.cleondris.ch/opensource/ssh2/
You can use its SCPClient or SFTPv3Client classes to work on the remote file system.
Documentation is available at http://www.cleondris.ch/opensource/ssh2/javadoc.
If you want to do it from Java, you can use Apache Commons VFS. It provides a common approach to dealing with files on all of the supported file systems. SFTP is one of the supported types which is most likely what you would need if you have been connecting with PuTTY.
You need SSH client. There are various pure java SSH clients. Google "java ssh client" and try any one of them. I used Jsch http://www.jcraft.com/jsch/ and it worked fine for me.

How can I execute Linux commands on a remote machine using Java?

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.

Categories