java.lang.ClassCastException:com.sun.mail.handlers.multipart_mixed 无法转换为 javax.activation.DataConten

Posted

技术标签:

【中文标题】java.lang.ClassCastException:com.sun.mail.handlers.multipart_mixed 无法转换为 javax.activation.DataContentHandler【英文标题】:java.lang.ClassCastException: com.sun.mail.handlers.multipart_mixed cannot be cast to javax.activation.DataContentHandler 【发布时间】:2019-08-19 13:36:54 【问题描述】:

线part.writeTo(out); 抛出java.lang.ClassCastException

com.sun.mail.handlers.multipart_mixed 不能转换为 javax.activation.DataContentHandler

private static void getBodyAsRFC822(
        MimePart part, boolean ignoreHeaders, ByteArrayOutputStreamout) 
    try 
        out.reset();

        if (ignoreHeaders) 
            OutputStream os = MimeUtility.encode(out, part.getEncoding());
            part.getDataHandler().writeTo(os);
            os.close();
         else 
            part.writeTo(out);
            out.close();
        
    
    catch (Exception e) 
        _log.error(e);
    

这是我的 build.gradle

compileOnly group: 'com.liferay', name: 'com.liferay.portal.instance.lifecycle', version: '2.0.0'
compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel", version: "2.46.0"
compileOnly group: "org.osgi", name: "org.osgi.core", version: "6.0.0"
compileOnly group: "org.osgi", name: "org.osgi.service.component.annotations", version: "1.3.0"

compileInclude group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
compileInclude group: 'org.apache.mina', name: 'mina-core', version: '2.0.16'
compileInclude group: 'javax.mail', name: 'mail', version: '1.4'
compileInclude group: "javax.servlet", name: "servlet-api", version: "2.5"

但是multipart_mixed implements DataContentHandler,所以它应该是可转换的。为什么不呢?

【问题讨论】:

这似乎是一个类加载问题。检查您在 portlet 或 hook 或任何其他组件中拥有的库 在哪里?在我的 buld.gradle 中? 我们来聊天吧。如果我们用意大利语交谈,对所有其他开发人员来说都是不正确的 我明天联系你,谢谢 好的,同时看看这里***.com/questions/21645071/… 【参考方案1】:

当一个子类显然不能被类型转换为它的合法超类时,你就会有重复的类,由不同的类加载器加载。找到您加载激活(超类)类的位置,消除除一个以外的所有类(通常您需要消除您自己的项目带来的一个类)并使用框架中提供的一个。

异常消息命名了有问题的类,但省略了参与游戏的类加载器,这就是为什么该消息在第一次尝试理解它时没有多大意义。只要您了解多个类加载器,即javax.activation.DataContentHandler 的多个实例,就更有意义了。

编辑:使用 build.gradle 中的 compileInclude 语句,您可以有效地将所有依赖项捆绑到您自己的 jar 文件中。但是框架有自己的这些类的版本,虽然它们都有相同的名称,但它们现在将是不同的版本(不仅仅是数字),通过不同的类加载器加载。如果您明显依赖于在 OSGi 运行时中永远找不到的东西,则应该只使用 compileInclude。相反,请使用 compileOnlycompile 作为默认值,并将其他依赖项与您的模块一起部署到运行时。

查看this article,了解您所做工作的详细说明。

【讨论】:

在哪里可以找到激活(超类)? 我不知道,但你应该能找到它两次 基本上,我能做什么? 如果可以的话,看看我的 build.gradle.. 我可以用“compileInclude group: 'javax.mail', name: 'mail', version: '1.4'”来改变“compileInclude group: 'javax.mail',名称:'javax.mail-api',版本:'1.5.6'”并且异常消失了,但应用程序之前没有这样做.. compileInclude 会将依赖项打包在你的模块中,并且很可能javax.mail(以及javax.activation)已经由OSGi容器提供(Liferay在这个案例)。因此compileOnly 应该没问题:在编译时你需要依赖,而在运行时你依赖Liferay 或其他组件通过OSGi 容器提供的javax.mail 的版本。根据经验,您很少会在自己的模块中捆绑依赖项。 compileInclude 将在您的模块中包含 javax.mailactivation

以上是关于java.lang.ClassCastException:com.sun.mail.handlers.multipart_mixed 无法转换为 javax.activation.DataConten的主要内容,如果未能解决你的问题,请参考以下文章