与 WebApp 运行时相比,jUnit 加载另一个 Class

jUnit loads another Class compared to WebApp runtime

我正在开发一项功能,其中 Cron 作业将通过 javax.mail 触发连接,并扫描某个 IMAP 帐户的所有传入邮件。

它是 Liferay Portlet 的一部分,使用 JSF-2 和 Maven 构建,并部署在 Tomcat 服务器上。

我已经构建了一个成功执行此场景的 jUnit 测试,运行 与从 Cron 作业调用的函数完全相同。我通过执行 maven build package 目标来完成此测试,并且我的 Maven 与我的 Tomcat.

使用相同的 JVM

但是在服务器中部署 WebApp 并且 Cron 触发器启动后,我收到了这个错误:

    org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: java.lang.NoClassDefFoundError: com/sun/mail/util/MailLogger]
    at org.quartz.core.JobRunShell.run(JobRunShell.java:224)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:557)
Caused by: java.lang.NoClassDefFoundError: com/sun/mail/util/MailLogger
    at javax.mail.Session.initLogger(Session.java:226)
    at javax.mail.Session.<init>(Session.java:210)
    at javax.mail.Session.getDefaultInstance(Session.java:321)
    at javax.mail.Session.getDefaultInstance(Session.java:361)

所以我猜想在 Tomcat 运行时或 Servlet 上下文或石英流或其他任何东西下,com/sun/mail/util/MailLogger 的分辨率与 jUnit 的分辨率不同。

为什么会发生这种情况,我如何确保在所有情况下都加载正确的 Class?

通过跟踪错误,我发现从 tomcat/ext/lib 加载了不同版本的 javax.mail,并在服务器为 运行 并启动流程时覆盖了我的版本在服务器上下文中。

最后,我设法解决了这个问题,方法是将我的 javax.mail-api 依赖项从

更改为
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>javax.mail-api</artifactId>
            <version>1.5.4</version>
        </dependency>

    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>javax.mail-api</artifactId>
        <version>1.4.4</version>
        <scope>provided</scope>
    </dependency>

我切换到较旧的 javax.mail-api 版本,与服务器版本兼容,并且我还在使用运行时提供的库