I've got a JBoss Scheduled process (JBoss 5.0.0.GA, org.jboss.varia.scheduler.Scheduler
) that's running in production. It does its job. It has no unit tests. And I need to change it.
The job at hand is to connect to the company's Exchange server via IMAP, scan a specific folder for new messages, and do something to the messages that it finds.
So my first goal is to write some simple unit tests for it, and the first thing I want to do is just get a count of messages in the folder. The code to do so, including printing out the count of messages in the folder, is already in the production code. In creating my SSCCE for this post, I've essentially just removed the "and do something to the messages that it finds" part, along with a minor amount of obfuscation and simplification.
So now, the code:
package com.mycompany.utils;
import org.apache.log4j.Logger;
import org.jboss.varia.scheduler.Schedulable;
import java.util.Date;
import java.util.Properties;
import javax.mail.Folder;
import javax.mail.Session;
import javax.mail.Store;
public class BouncedEmailSimple implements Schedulable {
private static final Logger logger = Logger.getLogger("com.mycompany.utils");
@Override
public void perform(Date pTimeOfCall, long pRemainingRepetitions) {
String popHost = "192.168.1.55";
String smtpHost = "192.168.1.55";
String popUser = "username";
String popPasswd = "password";
Session session = null;
Folder folder = null;
Store store = null;
try {
Properties sysProperties = System.getProperties();
sysProperties.put("mail.smtp.host", smtpHost);
session = Session.getInstance(sysProperties, null);
session.setDebug(false);
logger.info("Started Bounce Email Simple process.");
logger.info("user:" + popUser);
logger.info("smtp:" + smtpHost);
logger.info("pop:" + popHost);
store = session.getStore("imap");
store.connect(popHost, popUser, popPasswd);
logger.info("store:" + store);
folder = store.getDefaultFolder();
logger.info("1");
if (folder == null) {
logger.error("No Default Mail Folder");
throw new Exception("No Default Mail Folder");
}
logger.info("2");
folder = folder.getFolder("Bounces");
logger.info("3");
if (folder == null) {
logger.error("Bounce Mail folder not available");
throw new Exception("Bounce Mail folder not available");
}
logger.info("4");
folder.open(Folder.READ_WRITE);
logger.info("5");
int totalMessages = folder.getMessageCount();
logger.info("6");
if (totalMessages == 0) {
folder.close(false);
store.close();
return;
}
logger.info("7");
logger.info("Messages to process = [" + totalMessages + "]");
logger.info("8");
System.out.println("Ended Bounce Email Simple processes.");
} catch (Exception ex) {
logger.error("BouncedEmailSimple Server Failure");
logger.error("Error = [" + ex.getMessage() + "]");
try {
if (folder.isOpen()) {
folder.close(false);
}
} catch (Exception ex3) {
ex3.printStackTrace();
}
ex.printStackTrace();
} finally {
try {
if (store.isConnected()) {
store.close();
}
} catch (Exception ex4) {
ex4.printStackTrace();
}
}
}
}
And the unit test case:
package com.mycompany.utils;
import org.junit.Test;
import java.util.Date;
import static org.junit.Assert.fail;
public class BouncedEmailSimpleTest {
@Test
public void actualTest() {
try {
BouncedEmailSimple bes = new BouncedEmailSimple();
bes.perform(new Date(), 0);
} catch (Exception e) {
e.printStackTrace();
fail();
}
}
}
When I run it, the output is:
$ cat junit/TEST-com.mycompany.utils.BouncedEmailSimpleTest.txt
Testsuite: com.mycompany.utils.BouncedEmailSimpleTest
Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0.603 sec
------------- Standard Output ---------------
- Started Bounce Email Simple process.
- user:devsupport
- smtp:192.168.1.55
- pop:192.168.1.55
- store:imap://username@192.168.1.55
- 1
- 2
- 3
- 4
------------- ---------------- ---------------
Testcase: actualTest took 0.43 sec
Caused an ERROR
com/sun/mail/util/MessageRemovedIOException
java.lang.NoClassDefFoundError: com/sun/mail/util/MessageRemovedIOException
at com.sun.mail.imap.IMAPFolder.open(IMAPFolder.java:809)
at com.mycompany.utils.BouncedEmailSimple.perform(Unknown Source)
at com.mycompany.utils.BouncedEmailSimpleTest.actualTest(Unknown Source)
Caused by: java.lang.ClassNotFoundException: com.sun.mail.util.MessageRemovedIOException
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
I have mail.jar
(version 1.3.something) on my classpath for my unit test, and this version of mail.jar does not contain the above class. However, I have also downloaded JavaMail version 1.4.4, which does have the above class, and included 1.4.4 (and also excluded 1.3.something) on the classpath. That produces a different error that I can't access right now (I'm no longer at my work computer where this post was started...) However, it seems that there's something more fundamental at play here, or at least more specific to JBoss than I am positive of at this point. The version of mail.jar
on JBoss's classpath also doesn't contain the class above, so I'm more than thoroughly confused.
Any ideas?
When I came in to work this morning, I added back the JavaMail 1.4.4 jars to my classpath (and removed the 1.3.something jars), ran my test again, and it worked. I'm writing this off to "something changed with the Exchange server overnight."