I have a backup process by FTP, it works with org.apache.commons.net.ftp.FTPClient library.
I found that some file are partially uploaded and I did not found any upload error, sometimes just retrying I solved the problem.
This is my FTP connection code, I'm using passive mode and keepalive:
public FTPClient ftpConnect(){
FTPClient ftp = new FTPClient();
int retries=3;
int timeout=5000;
URL url;
try {
url = new URL(REMOTE_URL);
if(!url.getProtocol().equals("ftp"))
throw new MalformedURLException();
} catch (MalformedURLException e1) {
throw new SystemException("Invalid protocol");
}
ftp.setConnectTimeout(timeout);
ftp.setDataTimeout(timeout);
for (int i = 1; i <= retries; i++) {
try {
ftp.connect(url.getHost(),url.getPort()>0?url.getPort():21);
ftp.setSoTimeout(timeout);
ftp.enterLocalPassiveMode();
ftp.setKeepAlive(true);
int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
throw new ConnectException("FTP server refused connection");
}
if(StringUtils.isNotBlank(url.getUserInfo())){
String[] arr=URLDecoder.decode(url.getUserInfo(), "UTF-8").split(":");
String user=arr[0];
String pass=arr.length>0?arr[1]:"";
if (!ftp.login(user,pass)) {
ftp.logout();
throw new SecurityException("FTP server login not valid");
}
}
ftp.changeWorkingDirectory(url.getPath());
break;
} catch (SocketException e ) {
log.error("Socket Error, retry nr {}",i);
if(i==retries) throw new SystemException("Socket error, max retries reached");
} catch (IOException e) {
throw new SystemException("Connection Error");
} catch (SecurityException e) {
throw new SystemException("Invalid authentication");
}
}
return ftp;
}
I would like to know how cand I solve this partial upload and above all how can I get an error in these cases.
Related
how can I fetch movie.list.gz folder from the link
1: ftp://ftp.funet.fi/pub/mirrors/ftp.imdb.com/pub/, I have used a code to access the FTP server for fetching data but it asks for port no. which I don't know. Can anyone please tell how to fetch data from the above link in java. I am developing a Web Application which will display all the movie names present in IMDB database.
CODE:
String server = "ftp://ftp.funet.fi/pub/mirrors/ftp.imdb.com";
int port = 21;
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect(server);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// APPROACH #1: using retrieveFile(String, OutputStream)
String remoteFile1 = "/pub/movie.list.gz";
File downloadFile1 = new File("F:/softwares/mov.list.gz");
OutputStream outputStream1 = new BufferedOutputStream(new FileOutputStream(downloadFile1));
boolean success = ftpClient.retrieveFile(remoteFile1, outputStream1);
outputStream1.close();
if (success) {
System.out.println("File #1 has been downloaded successfully.");
}
} catch (IOException ex) {
System.out.println("Error: " + ex.getMessage());
ex.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
When i try to list files from my location using ftpClient.listFiles("folder"); it shows
org.eclipse.debug.core.DebugException: com.sun.jdi.ClassNotLoadedException: Type has not been loaded occurred while retrieving component type of array.
Can some one guide me what i am doing wrong.
I use apache-commons-net-3.3
My code is
FTPClientConfig ftpClientConfig = new FTPClientConfig(FTPClientConfig.SYST_NT);
FTPClient ftpClient = new FTPClient();
ftpClient.configure(ftpClientConfig);
ftpClient.connect(hostName, Integer.valueOf(portNumber));
ftpClient.enterLocalPassiveMode();
ftpClient.login(username, password);
// Error throws here
FTPFile[] files = ftpClient.listFiles("folder");
This Exception is thrown when a user gave a Wrong or Encrypted Username Or Password.
Apache is not throwing the correct exception.
public void ConnectToFtp(String serverAdd,String username,String password){
try {
ftpclient.connect(serverAdd);
boolean login = ftpclient.login(username,password);
reply = ftpclient.getReplyCode();
if(FTPReply.isPositiveCompletion(reply)){
System.out.println("Connected Success");
}else {
System.out.println("Connection Failed");
ftpclient.disconnect();
}
if (login) {
System.out.println("Connection established...");
FTPFile[] ftpFiles = ftpclient.listFiles();
for (FTPFile ftpFile : ftpFiles) {
if (ftpFile.getType() == FTPFile.DIRECTORY_TYPE) {
System.out.printf("FTPFile: %s; %s%n",
ftpFile.getName(),
FileUtils.byteCountToDisplaySize(ftpFile.getSize()));
}
}
}
boolean logout = ftpclient.logout();
if (logout) {
System.out.println("Connection close...");
} else {
System.out.println("Connection fail...");
}
} catch (SocketException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
ftpclient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I am new to FTP. I have a problem with my FTPSClient program. Only control channel is encrypted. I need both the control and data channel to be encrypted.
public boolean login(String usrName,char[] passwd){
try {
ftpClient = new FTPSClient(protocol,false); // SSL FTP
ftpClient.connect(strHost);
int reply = ftpClient.getReplyCode(); // After connection attempt, you should check the reply code to verify success.
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
log.error("FTP server refused connection.");
return false;
}
ftpClient.setBufferSize(1000);
if (!ftpClient.login(strUsrName,new String(passwd))){
ftpClient.logout();
bLoginStatus = false;
return false;
}
else
bLoginStatus = true;
if(iMode == LOCAL_ACTIVE_MODE)
ftpClient.enterLocalActiveMode();
else if(iMode == LOCAL_PASSIVE_MODE)
ftpClient.enterLocalPassiveMode();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch(Throwable t){
t.printStackTrace();
}finally {
if (bLoginStatus == false && ftpClient.isConnected()){
try{
ftpClient.disconnect();
}
catch (IOException f){
// do nothing
}
}
}
if(ftpClient.isConnected())
return true;
else
return false;
}
You need to tell the client to also encrypt the data connection, you can do this (if i recall correctly) with the PROT command:
client.execPBSZ(0);
client.execPROT("P");
I would like to create a method that will test different things and throw an error depending on the issue (and then exit the program).
I am not really familiar with throwing exception... Is this method a good way to program it?
private static void testConnexions() throws IOException, Exception {
File file = null;
Socket socket;
try {
// Test access to the repository:
file = new File(pdfRepository);
if (!file.canRead())
throw new SecurityException();
if (!file.canWrite())
throw new SecurityException();
if (!file.exists())
throw new SecurityException();
if (!file.isDirectory())
throw new SecurityException();
// Connection to Filenet:
connexion = new FilenetConnexion(filenetURI, objectStoreName,
stanza, dossierRacine, userName, password);
connexion.connect();
// Connection to a socket:
socket = new Socket(serveurCV, portCV);
// Initialize the JavaMail Session:
Properties props = System.getProperties();
if (serveurSMTP != null)
props.put("mail.smtp.host", serveurSMTP);
Session session = Session.getInstance(props, null);
} catch (SecurityException e) {
e.getMessage();
e.printStackTrace();
} catch (UnknownHostException e) {
e.getMessage();
e.printStackTrace();
} catch (IOException e) {
e.getMessage();
e.printStackTrace();
} catch (Exception e) {
e.getMessage();
e.printStackTrace();
}
}
I would like to catch a message detailed enough to know if the repository can't be written in, or if the System.getProperties() got an error, etc.
Thank you in advance for your help!
EDIT:
Here is the solution I chose among all your contributions, hoping it can help someone:
private static void testConnexions() {
File file = null;
Socket socket;
// Test access to the repository:
try {
file = new File(pdfRepository);
if (!file.canRead())
throw new SecurityException(pdfRepository + " can't be read.");
if (!file.canWrite())
throw new SecurityException(pdfRepository + " can't be written.");
if (!file.exists())
throw new SecurityException(pdfRepository + " doesn't exist.");
if (!file.isDirectory())
throw new SecurityException(pdfRepository + " isn't a folder.");
} catch (SecurityException e) {
logger.error(e.getMessage());
System.exit(1);
}
// Connection to FileNet
try {
connexion = new FilenetConnexion(filenetURI, objectStoreName,
stanza, dossierRacine, userName, password);
connexion.connect();
} catch (Exception e) {
logger.error("Impossible to connect to FileNet. " + e.getMessage());
System.exit(2);
}
// Connection to FrontalSocket
try {
socket = new Socket(serveurCV, portCV);
} catch (UnknownHostException e) {
logger.error("Impossible to connect to FrontalSocket. " + e.getMessage());
System.exit(3);
} catch (IOException e) {
logger.error("Impossible to connect to FrontalSocket. " + e.getMessage());
System.exit(3);
}
// Initialize the JavaMail session
try {
Properties props = System.getProperties();
if (serveurSMTP != null)
props.put("mail.smtp.host", serveurSMTP);
else{
logger.error("The SMTP host name is null");
System.exit(4);
}
Session session = Session.getInstance(props, null);
} catch (Exception e) {
logger.error("Impossible to connect to SMTP server. " + e.getMessage());
System.exit(4);
}
}
You can do this several ways, choose which one fits your scenario best:
Throw different exceptions based on each error scenario. It is easy to subclass Exception and create the distinction this way.
Throw the same exception with a specific error message depending on the error scenario.
An example of case 1:
First define your own exceptions:
public class CannotReadException extends Exception {
// This is a separate class in your project
}
public class CannotWriteException extends Exception {
// This is a separate class in your project
}
Then throw and catch them:
try {
// Test access to the repository:
file = new File(pdfRepository);
if (!file.canRead())
throw new CannotReadException();
if (!file.canWrite())
throw new CannotWriteException();
...
} catch (CannotReadException e) {
// Do stuff for the specific error
} catch (CannotWriteException e) {
// Do stuff for the specific error
}
or, case 2:
try {
// Test access to the repository:
file = new File(pdfRepository);
if (!file.canRead())
throw new SecurityException( "cannot read" );
if (!file.canWrite())
throw new SecurityException( "cannot write" );
...
} catch (SecurityException e) {
// Get to your specific message using e.getMessage();
}
I can suggest in this case to throw a user define exception and pass a message detailed enough to know the responsible for that error.
public class MyException extends Exception {
//override the needed methods.
}
then throw you own defined exception with a detaied message.
try {
// Test access to the repository:
file = new File(pdfRepository);
if (!file.canRead())
throw new MyException("The fine has no read permission");
Following is my java function to write a csv file in ftp location.The file gets created to ftp location but the file size is 0 bytes and file is empty.Kindly help as I am stuck
public int WriteFileToFtp(String FileName, String FileData) {
//get these details for the version??
//??
FTPClient ftp= new FTPClient();
try {
InputStream is = new ByteArrayInputStream(FileData.getBytes("ISO-8859-1"));
ftp.connect(ftpIP);
boolean isConnection = ftp.login(userName,password);
if(!isConnection){
logger.error("Connection failed");
return -1;
}
ftp.enterLocalActiveMode();
ftp.setFileType(FTP.BINARY_FILE_TYPE);//setting fileType
//?? go to directory using the circle code
if(ftpDirectoryToBeUpdate!=null && ftpDirectoryToBeUpdate.trim().length()>0)
{
logger.error("Changing directory for write="+ftpDirectoryToBeUpdate+" lcd="+ftp.printWorkingDirectory());
ftp.changeWorkingDirectory(ftpDirectoryToBeUpdate);
logger.error("Changed directory for write="+ftpDirectoryToBeUpdate+" lcd="+ftp.printWorkingDirectory());
}else
{
logger.error("Changed directory for write failed lcd="+ftp.printWorkingDirectory());
logger.error("DirectoryToReadFrom="+ftpDirectoryToBeUpdate);
}
ftp.storeFile(FileName,is) ;
logger.error(ftp.getReplyString());
is.close();
if(ftp.isConnected())
ftp.disconnect();
} catch (SocketException e) {
//logger.error(LoggerKeyWord.ERROR_ALERT + " FTP WRITE ERROR");
logger.error(e,e);
e.printStackTrace();
return -1;
} catch (IOException e) {
// logger.error(LoggerKeyWord.ERROR_ALERT + " FTP WRITE ERROR");
logger.error(e,e);
e.printStackTrace();
return -1;
}
try {
if(ftp.isConnected())
ftp.disconnect();
} catch (IOException e) {
logger.error (e,e);
e.printStackTrace();
return -1;
}
return 1;
}
have you tried closing input stream before saving the file?