MessageRemovedIOException?
I'm writing a website that occasionally sends emails--in this case, as part of a new-user registration process. The relevant code looks like this:
Message msg =new MimeMessage (session);
When I deploy my application in Glassfish, this works wonderfully.
But when I run this code in an automated unit test, processing gets here, calls sun.misc.Launcher$AppClassLoader to load the MimeMessage class, and pukes with a stack trace headed like this:
java.lang.NoClassDefFoundError: com/sun/mail/util/MessageRemovedIOException
at pkg.MailUtil.sendMessage(MailUtil.java:27)
(MailUtil.java:27, of course, is the source line above.)
I don't have source for sun.misc.Launcher, but I've done some stepping through with the debugger and noticed that in the process of loading MimeMessage, it loads a number of other JavaMail-related classes as well. All of them are found until it gets to com.sun.mail.util.MessageRemovedIOException.
I've done string searches through all Glassfish's jars looking for that class without success.
So my questions are two:
A) Where is com.sun.mail.util.MessageRemovedIOException?
B) Why does it work in the Application Server but not in JUnit?
Thanks...
[1290 byte] By [
dnwiebea] at [2007-11-27 10:51:32]

# 1
It's possible you either:
- don't have com/sun/mail/util/MessageRemovedIOException in your classpath for the process running JUnit (although I think usually causes a different exception)
- or it's possible the class is either duplicated in the classpath, or the same package is in multiple jar files. For example, I have seen NoClassDefFoundError occur where one copy of a class was in a signed jar file while other classes (of the same package) are in an unsigned jar file. You can try removing signatures from the jar files in this case. The JRE generally likes a single package to be in a single jar file, in particular where signatures are involved.
Fixing this will require taking a detailed look at what is referenced by the classpath of your unit test.
# 2
> It's possible you either:
>
> - don't have
> com/sun/mail/util/MessageRemovedIOException in your
> classpath for the process running JUnit
That is precisely the case. The class is not in any of the jars that are part of the JUnit process.
We have solidly established that the class is not in the classpath. However, the question remains: where is the class? See below.
> - or it's possible the class is either duplicated in
> the classpath, or the same package is in multiple jar
> files.
No, that's not the case. I've used jar-scanning tools to make sure of it. It's nowhere in the JUnit-process classpath.
However!
It's also (certainty courtesy of those same jar-scanning tools) not anywhere in any jar file in any part of my JEE installation, including the Glassfish application server.
I figured the solution was easy: figure out where it's being found by the appserver, then put that jar in the classpath for JUnit. But it's not being found by the appserver, because it's not there.
My JUnit setup is using the same javaee.jar that's being used by the appserver, which is where all the JavaMail stuff is.
I've looked at the source code for the latest version of JavaMail, and have found no reference to MessageRemovedIOException in it; so I'm thinking that perhaps MessageRemovedIOException is an old class that has been overtaken by events, and was removed in the latest version of JavaMail; perhaps the version in javaee.jar is an old version that does reference MessageRemovedIOException in some latent way--perhaps importing it but never directly referencing it.
And perhaps the sun.misc.Launcher$AppClassLoader classloader is dumb enough to try to load classes that won't ever be used, while whatever classloader is used by Glassfish is smart enough not to: so JUnit tries to load it and fails, while Glassfish skips over it and succeeds.
What do you think?
# 3
You must be looking at the wrong version of the GlassFish source code.
The class is definitely there and has been for some time.
The class was added to JavaMail after the 1.4 release. You can get a
standalone version of mail.jar that contains it from the java.net maven
repository. See the JavaMail web site for a pointer.
# 4
> You must be looking at the wrong version of the
> GlassFish source code.
> The class is definitely there and has been for some
> time.
>
> The class was added to JavaMail after the 1.4
> release. You can get a
> standalone version of mail.jar that contains it from
> the java.net maven
> repository. See the JavaMail web site for a pointer.
Okay, well, that was the trick. I put mail.jar and activation.jar in the classpath ahead of javaee.jar, and it works now. The appserver must do something similar.
Thanks for your help.