We got a serious problem in our system which is processing mails from IMAP and saving it as EML. Thing is, everything works in production but not on dev machine anymore, therefore we cannot make any fixes or further development. This is kind of strange, because also this example does not work:
package com.test;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Store;
public class ReadMail {
public static void main(String args[]) throws Exception {
String host = "mail";
String user = "xxx";
String password = "zzz";
Properties properties = System.getProperties();
Session session = Session.getDefaultInstance(properties);
Store store = session.getStore("imap");
store.connect(host, user, password);
Folder folder = store.getFolder("a");
folder.open(Folder.READ_ONLY);
Message[] message = folder.getMessages();
for (int i = 0; i < message.length; i++) {
System.out.println("------------ Message " + (i + 1) + " ------------");
System.out.println(message[i].getSentDate());
System.out.println(message[i].getFrom()[0]);
System.out.println(message[i].getSubject());
try (OutputStream out = new FileOutputStream("something"+i+".eml")) { // fix the name of course
message[i].writeTo(out);
}
}
folder.close(true);
store.close();
}
}
In writeTo it makes endless loop and creates file which grows until the disk is full. This is from com.sun.mail.imap.IMAPMessage
/**
* Write out the bytes into the given OutputStream.
*/
public void writeTo(OutputStream os)
throws IOException, MessagingException {
if (bodyLoaded) {
super.writeTo(os);
return;
}
InputStream is = getMimeStream();
try {
// write out the bytes
byte[] bytes = new byte[16*1024];
int count;
while ((count = is.read(bytes)) != -1)
os.write(bytes, 0, count);
} finally {
is.close();
}
}
It will never exit from the while clause. Should it be some error on the Postfix side? The mail is multipart MIME message and the EML created are just multiple copies of EML. Only difference between prod and dev machine is HW. JDK8 is the same. Any hints?
Java mail API used:
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.6</version>
</dependency>
UPDATE SOLVED: ESET Nod32 Antivirus software intercept the IMAP traffic in that way, that the buffer never returns -1! After disabling ESET Mail, everything works.
Related
This is a followup of this question. The correct answer leads to an attempt to use the SFTPClient class in the Apache Commons library.
I can connect. The next step is to upload a file. There is a lot of reference material with sample source code. I used this one as my guide. It's not secure FTP, but it's simple to follow. This is the java code I was attempting to emulate:
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
public class FTPUploadFileDemo {
public static void main(String[] args) {
String server = "www.myserver.com";
int port = 21;
String user = "user";
String pass = "pass";
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect(server, port);
ftpClient.login(user, pass);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// This was considered unnecessary because I was sending n ASCII file
// APPROACH #1: uploads first file using an InputStream
File firstLocalFile = new File("D:/Test/Projects.zip");
String firstRemoteFile = "Projects.zip";
InputStream inputStream = new FileInputStream(firstLocalFile);
System.out.println("Start uploading first file");
boolean done = ftpClient.storeFile(firstRemoteFile, inputStream);
inputStream.close();
and some more code that's not relevent,
This is my ColdFusion equivalent:
localFilename = "d:\dw\dwtest\dan\textfiles\randomText.txt";
remoteFileName = "randomText.txt";
javaFtpClient = CreateObject("java",
"org.apache.commons.net.ftp.FTPSClient").init("SSL", JavaCast("boolean",true));
// note that I am using a secure client
javaInputFile = createObject("java", "java.io.File").init(localFilename);
javaInputStream = createObject("java", "java.io.FileInputStream").init(javaInputFile);
// connect and login
javaFtpClient.connect(JavaCast("string","something"),990);
loginStatus = javaFtpClient.login('valid username','valid password');
writeoutput("login status " & loginStatus & "<br>");
javaFtpClient.enterLocalPassiveMode();
uploadStatus = javaFtpClient.storeFile(remoteFileName, javaInputStream);
writeOutput("upload status " & uploadStatus & "<br>"); javaInputStream.close();
// logout and disconnect
javaFtpClient.logout();
javaFtpClient.disconnect();
writeoutput("done" & "<br>");
The output shows a successful login and an unsuccessful file upload. The lack of file was confirmed using FileZilla.
Can anybody see why the file was not uploaded?
The command javaFtpClient.execProt("P") is required. Setting PROT to "P" sets the Data Channel Protection Level to private.
I'm trying to use the printWorkingDirectory() from Apache Commons FTP but it's only returning null. I can't navigate directories, list files, etc.
Log in pass all is success but how ever I try I can not change current directory.
I use this following code:
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
public class FTPDownloadFileDemo {
public static void main(String[] args) {
String server = "FTP server Address";
int port = portNo;
String user = "User Name";
String pass = "Pasword";
FTPClient ftpClient = new FTPClient();
String dir = "stocks/";
try {
ftpClient.connect(server, port);
ftpClient.login(user, pass);
System.out.println( ftpClient.printWorkingDirectory());//Always null
//change current directory
ftpClient.changeWorkingDirectory(dir);
boolean success = ftpClient.changeWorkingDirectory(dir);
// showServerReply(ftpClient);
if (success)// never success
System.out.println("Successfully changed working directory.");
System.out.println(ftpClient.printWorkingDirectory());// Always null
} 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();
}
}
}
}
This is rather old question that deserves an answer. This issue is likely a result of using FTPClient when secure connection is required. You may have to switch to FTPSClient if that is, indeed, the case. Further, output the response from the server with the following code snippet to troubleshoot the issue if secure client doesn't solve the it:
ftpClient.addProtocolCommandListener(
new PrintCommandListener(
new PrintWriter(new OutputStreamWriter(System.out, "UTF-8")), true));
Also, a server can reject your login attempt if your IP address is not white listed. So, being able to see the logs is imperative. The reason you see null when printing current working directory is because you are not logged in. Login method will not throw an exception but rather return a boolean value indicating if the operation succeeded. You are checking for success when changing a directory but not doing so when logging in.
boolean success = ftpClient.login(user, pass);
I faced the same, but I came across with a simple step.
Just added this.
boolean success = ftpClient.changeWorkingDirectory(dir);
ftpClient.printWorkingDirectory(); //add this line after changing the working directory
System.out.println(ftpClient.printWorkingDirectory()); //wont be getting null
Here I have the code and the console output
FTPClient.changeWorkingDirectory - Unknown parser type: "/Path" is current directory
I know I replied too soon ;-P, but I saw this post recently. Hope this helps to future searchers ;-)
I am trying to download a file from a server. The server has a guest account without a login or password.
The code was adapted from http://www.dreamincode.net/forums/topic/32031-ftp-in-java-using-apache-commons-net. The reply code is 220, which means "Service ready for new user", but the size of the downloaded file is 0 Bytes. The size of the file on the server is 845 Bytes.
Thank you for your time.
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.SocketException;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
public class FtpTest {
public static FTPClient ftp = new FTPClient();
public static void main(String []args) throws IOException{
String ftpStr = "ftp.ncbi.nih.gov";
String path = "ftp.ncbi.nih.gov/genomes/MapView/Mus_musculus/non_sequence/README";
try {
ftp.connect(ftpStr);
} catch (SocketException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
int reply = ftp.getReplyCode();
System.out.println(reply); //Output: 220
System.out.println("Connected");
File file = new File("README");
FileOutputStream dfile = new FileOutputStream(file);
ftp.retrieveFile(path,dfile);
ftp.disconnect();
System.out.println("Finished");
}
}
To access an FTP server with a guest account (without username or password), you should use the username anonymous with an empty password.
I know this is two years late, but I had the same issue. The variable remote in: public boolean retrieveFile(String remote, OutputStream local) throws IOException
expects a file name, not the the full address to the file. So you should pass "README" instead of path. Before doing that, you should change the working directory of your ftp client to "genomes/MapView/Mus_musculus/non_sequence"
I am getting this error when tried to read mail using JavaMail. please let me know how to resolve this error. I have added activation.jar and mail.jar into eclipse.
DEBUG POP3: server doesn't support TOP, disabling it
javax.mail.AuthenticationFailedException: Command is not valid in this state.
at com.sun.mail.pop3.POP3Store.protocolConnect(POP3Store.java:174)
at javax.mail.Service.connect(Service.java:291)
at javax.mail.Service.connect(Service.java:172)
at library.VerifyEmail.main(VerifyEmail.java:40)
Below is the code I am trying:
package library;
import java.io.IOException;
import java.util.Properties;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import com.sun.mail.pop3.POP3Store;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.search.SubjectTerm;
import javax.activation.*;
import java.io.*;
public class VerifyEmail {
public static void main(String[] args) throws Exception {
// SUBSTITUTE YOUR ISP's POP3 SERVER HERE!!!
String host = "myhost";
// SUBSTITUTE YOUR USERNAME AND PASSWORD TO ACCESS E-MAIL HERE!!!
String user = "myuser";
String password = "mypass";
// Get a session. Use a blank Properties object.
Session session = Session.getInstance(new Properties());
try {
// Get a Store object
Store store = session.getStore("pop3");
store.connect(host, user, password);
// Get "INBOX"
Folder fldr = store.getFolder("INBOX");
fldr.open(Folder.READ_WRITE);
int count = fldr.getMessageCount();
System.out.println(count + " total messages");
// Message numebers start at 1
for(int i = 1; i <= count; i++) {
// Get a message by its sequence number
Message m = fldr.getMessage(i);
// Get some headers
Date date = m.getSentDate();
Address [] from = m.getFrom();
String subj = m.getSubject();
String mimeType = m.getContentType();
System.out.println(date + "\t" + from[0] + "\t" +
subj + "\t" + mimeType);
}
}catch (MessagingException ioex) {
ioex.printStackTrace();
}
}
}
When you're getting the javax.mail.AuthenticationException it means that your application is unable to authenticate to the mail server.
One possible reason for this might be that an SSL certificate of the mail server is missing from the client keystore.
According to microsoft: For exchange 2010, by default, the server would need the client use ssl for pop3.
Without ssl the server responds with "ERR command is not valid in this state."
Here's how to use javamail with ssl - Javamail and Gmail Pop3 SSL
DEBUG POP3: server doesn't support TOP, disabling it
this message can be disable by updating the java mail jar version to 1.4.4
i try the tutorial Get Attachment File Name from Java2s.com.
What i'm doing is to read email from the Outlook Web Access Light.
If i put the url address of the Outlook Web Access Light, i have the error:
Exception in thread "main" javax.mail.NoSuchProviderException: No provider for http
at javax.mail.Session.getProvider(Session.java:455)
at javax.mail.Session.getStore(Session.java:530)
at javax.mail.Session.getFolder(Session.java:602)
at MainClass.main(MainClass.java:19)
Java Result: 1
I don't understand the line :
("protocol://username#host/foldername");
here is the code:
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Part;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.URLName;
import javax.mail.internet.InternetAddress;
public class MainClass {
public static void main(String[] args) throws Exception {
URLName server = new URLName("protocol://username#host/foldername");
Session session = Session.getDefaultInstance(new Properties(), new MailAuthenticator());
Folder folder = session.getFolder(server);
if (folder == null) {
System.out.println("Folder " + server.getFile() + " not found.");
System.exit(1);
}
folder.open(Folder.READ_ONLY);
Message[] messages = folder.getMessages();
for (int i = 0; i < messages.length; i++) {
System.out.println(messages[i].getSize() + " bytes long.");
System.out.println(messages[i].getLineCount() + " lines.");
String disposition = messages[i].getDisposition();
if (disposition == null){
; // do nothing
}else if (disposition.equals(Part.INLINE)) {
System.out.println("This part should be displayed inline");
} else if (disposition.equals(Part.ATTACHMENT)) {
System.out.println("This part is an attachment");
String fileName = messages[i].getFileName();
System.out.println("The file name of this attachment is " + fileName);
}
String description = messages[i].getDescription();
if (description != null) {
System.out.println("The description of this message is " + description);
}
}
folder.close(false);
}
}
class MailAuthenticator extends Authenticator {
public MailAuthenticator() {
}
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("username", "password");
}
}
Thank you for your support
have a nice day
Given the error message I really think javaMail is expecting for protocol one of "smtp:" or "imap:" or "pop3:", because it is the way it constructs its session.
I don't think it will ever work with a web access, you have to get the address of the pop3/imp/smtp server the web interface connects to.
I'm not sure but "protocol://username#host/foldername" seems to describe a format rather than a real url, i.e. it tells you to add a protocol, a user name, a host and a folder like "http://Thomas#stackoverflow.com/need-help-about-get-attachment-file-name-tutorial-from-java2s-com" (just an example of how it might look like, this particular url is not likely to work/exist/whatever :) ).