how to remove permanently message with javamail and imap - java

I use imap for reading message from mail server. I want when i read message, the message delete from mail server.
I use javaMail library and set delete flag to true and i can not see message from web panel but when i get count of message, the count of message dose not changed.
my mail server is Zimbra.
int count = inbox.getMessageCount();//for example count=100
inbox[i].setFlag(Flags.Flag.DELETED, true);
count = inbox.getMessageCount();// count=100

You need to expunge the messages after marking them deleted for them actually to be removed from the folder. In the meantime, they just sit around with a \Deleted flag, and most IMAP clients will hide them.
Calling expunge (JavaDoc) should be as simple as inbox.expunge(). This will cause any messages you've marked deleted, or possibly marked deleted in another session, to be removed, and will renumber the existing message sequence numbers in all other messages.
If your server supports UIDPLUS and you need more control, IMAPFolder.expunge() supports expunging a specific list of DELETED messages.

if (inbox.isOpen()) {
Message[] messages = inbox.getMessages();
for (int i = 0; i < messages.length; i++) {
System.out.println( messages[i]);
messages[i].setFlag(Flags.Flag.DELETED, true);
}
if (inbox.isOpen()) {
inbox.expunge();
}
}
Thanks #Max

Related

How to discard messages from queue using Java/JMS?

We have an application that synchronously reads 4MB messages from an IBM Websphere queue (version 7.5) using JMS. Under certain circumstances, I want to discard messages from the queue without reading them. I am trying to figure out if there is a way to do this programatically without reading the entire 4MB message, which takes several seconds (there could be hundreds of messages that need to be discarded). In the absense of a discard() method (or similar), here is what I have tried:
BytesMessage msg = (BytesMessage)queueReceiver.receiveNoWait();
bytesRead = msg.readBytes(msgBytes, 1024); // just read 1024 bytes
queueReceiver.close();
The above code is no quicker than retrieving the entire 4MB message from the queue (by reading into a larger buffer). This leads me to believe that the receiveNoWait() call is downloading the entire message into an internal buffer before the readBytes() call is made. The only other information I can provide is that the queue is set to "auto acknowledge" when the session is started:
queueSession = queueConnection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
If I were to change this to CLIENT_ACKNOWLEDGE and acknowlege the message using msg.acknowledge(), would that have the desired effect? Or is there something I am missing?
Thanks for any help,
Doug
There is no other way, a message must be consumed to take remove it from a queue.
Changing to CLIENT_ACKNOWLEDGE from AUTO_ACKNOWLEDGE will not make any difference as the acknowledge is way to tell the messaging provider to remove a message from queue. The AUTO_ACKNOWLEDGE option tells the JMS client to automatically send a confirmation to provider to remove a message whereas CLIENT_ACKNOWLEDGE is used by the application to explicitly tell the provider to remove message(s).
You could probably take a look at setting an expiry time on messages that you don't plan to consume. Messages with an expiry time set, will not be available for delivery after the expiry time is over. Read through JMSExpiration property of a message.
Given this some more thought and there is potentially one other way here; MQ has the concept of PCF messages - simply this is being able to send an administrative command as a message to a queue manager.
JMS can send these messages - so one open would be to send a CLEAR_QUEUE command when you know you don't want any more messages.
It's quite a broad approach - clearing the entire queue but it depends on what your criteria are for removing messages.
I can see the use case however for selectively removing messages - maybe worth raising a 'request for enhancement' RFE on the IBM developerWorks site?
As far as I know, JMS cannot read part of a message. You can only do that with C or Java (non-JMS).
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = MQC.MQGMO_NO_WAIT + MQC.MQGMO_FAIL_IF_QUIESCING;
MQMessage getMsg = new MQMessage();
try
{
/* get the message with only 1 byte of message data */
_inQ.get(getMsg, gmo, 1);
}
catch (MQException e)
{
System.err.println(e.getLocalizedMessage() );
}

Reading messages using JavaMail (POP3)

I'm trying to read messages with attachments from gmail using POP3 (I can't change it to IMAP). I have a problem because when I read attachment first time I'm unable to read this one again. It means that when I call method:
Message[] messages = inboxfolder.getMessages();
next time it returns only new messages. It is important to me, because when something goes wrong during first reading it is impossible to get some messages from server.
I've found that message is set as seen after:
Multipart multipart = (Multipart) messageWithAttach.getContent();
BodyPart bodyPart = multipart.getBodyPart(i);
Is it possible to often gets all messages, or messages I've marked as seen (I know that POP3 doesn't support flags from JavaMail)?

How do I uniquely identify a Java Mail Message using IMAP?

IMAP Message in Java Mail is identified by it's relative position number which starts from 1.
refer,
http://docs.oracle.com/javaee/1.4/api/javax/mail/Message.html#getMessageNumber()
Message number is a temporary details.
Is there a way to permanently uniquely identify a mail/message which accessing a mailbox via IMAP using Java Mail API which holds true across sessions ?
Look at the UIDFolder interface, which exposes the IMAP UID capability.
You can get a unique identifier for a message using the following code as an example
Folder folder = imapStore.getFolder("INBOX"); // get reference for inbox folder
UIDFolder uf = (UIDFolder)folder; // cast folder to UIDFolder interface
folder.open(Folder.READ_ONLY); // open folder
Message messages[] = folder.getMessages(); // get all messages
Long messageId = uf.getUID(messages[0]); // get message Id of first message in the inbox
Adding this because I think this will help
If you want to loop over the messages and get uids the above code does not do got performance as you have to loop and get uid, easy way to get that with the messages is below
Folder emailFolder = store.getFolder("INBOX");
emailFolder.open(Folder.READ_ONLY);
UIDFolder uf = (UIDFolder)emailFolder;
Message messages[] = emailFolder.getMessages();
FetchProfile profile = new FetchProfile();
//profile.add(FetchProfile.Item.ENVELOPE);
profile.add(FetchProfile.Item.FLAGS);
//profile.add(FetchProfile.Item.CONTENT_INFO);
profile.add(UIDFolder.FetchProfileItem.UID);
emailFolder.fetch(messages, profile);
this will get the messages with the uid
after this if you loop and do uf.getUID(messages[i]); you will get the uid but this time it will be faster.

javamail: Setting custom flags on imap mail and searching for mails with custom flags

Is it possible to set custom flags on IMAP mail messages using java mail without overwriting existing flags? Eg, I need to set a flag "processed" on processed messages without changing its state to SEEN / DELETED or without mail clients interfering with this "processed" flag.
Then I need to find all mail that doesn't have the "processed" flag and process them after which they are also flagged as "processed".
Thanks!
Flags processedFlag = new Flags("processed");
folder.setFlags(msgs, processedFlag, true);
// or
msg.setFlags(processedFlag, true);
Not all IMAP servers will support these "user flags", but most will. To find messages without this flag:
Message[] msgs = folder.search(new FlagTerm(processedFlag, false));

How to mark messages that are received by an java application using javax Mail Api?

I want to create an application that gets all e-mails from an e-mail account using imap.
When I first run the application I get all mails, than if I run it again I want to mark the messages that was read before so I can receive only new messages.
I found that Message Object contains Flags(System Flags and User defined flags), but I can't manage to set one user defined flag.
It is possible to mark the messages received by my application on the e-mail account, or I have to retain all message ids and every time when I get messages from imap I have to compare their id with retained ids and get only the messages that has different ids?
Some IMAP servers don't permit you to set user-defined flags. Most do, however. Via JavaMail, you'd do the following:
Flags flags = new Flags("fetched");
message.setFlags(flags, true);
Those flags aren't permanent, however -- another IMAP client could clear them just as easily as you set them. (Though they probably won't.)
Another option is to track the UIDs of the messages you've seen. You can get them via ImapFolder.getUID(Message). It's more straightforward than tracking Message-ID headers, which are much more costly to fetch and, since they're strings, occupy more memory in your app.
Yet another option is to use POP and track UIDLs.
Yes it is possible to mark the messages as read, and when the next time you want to read the messages you can only read the new messages.
Use the following code:
Folder emailFolder = emailStore.getFolder("INBOX");
Message messages[] = emailFolder.search(new FlagTerm(new Flags(Flag.SEEN), false));
System.out.println("no of messages=" + messages.length);
for (int i = 0; i < messages.length; i++) {
Message message = messages[i];
//here write your code to read the message and whatever you wanna do//
//now at the end of the message(remember at the end of the message u read using code) write the following code//
message.setFlag(Flag.SEEN, true);
}//end of for loop

Categories