目前,我正在编写将要侦听目录的代码。当使用.apk文件更新目录时,我会将带有此.apk文件的邮件发送到gmail帐户。我在我的程序中使用Jnotify和JAVA Mail。
我得到的错误是,
javax.mail.MessagingException: IOException while sending message;
nested exception is:
javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed; boundary="----=_Part_0_145238.1392728439484"
我查找了stackoverflow中给出的解决方案以获取帮助,但没有一个有用。
先谢谢
public void fileCreated(int wd, String rootPath, String name) {
print("created " + rootPath + " : " + name);
if (name.contains(".apk"))
SendEmail(name);
else
System.out.println("Not the APK file");
}
void SendEmail(String strname){
String Path = "D:/POC/Email/apk folder/"+strname;
System.out.println("Path->" + Path);
Properties props = new Properties();
props.put("mail.smtp.host","173.194.78.108");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.auth","true");
props.put("mail.smtp.port","465");
System.out.println("Properties has been set properly");
Session session = Session.getDefaultInstance(props,
new javax.mail.Authenticator(){
protected PasswordAuthentication getPasswordAuthentication(){
return new PasswordAuthentication("SenderEmailID@gmail.com", "senderPassword");
}
}
);
System.out.println("Session Created successfully");
try{
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("SenderEmailID@gmail.com"));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("ToReceiverEmailID@gmail.com"));
message.setSubject("Android : " + strname);
MimeBodyPart msgbody = new MimeBodyPart();
msgbody.setText("This is the message content which is sent using JAVA MAIL 1.4.5");
Multipart mulpart = new MimeMultipart();
mulpart.addBodyPart(msgbody);
//Attachement Starts here.
msgbody = new MimeBodyPart();
javax.activation.DataSource source = new FileDataSource(Path);
msgbody.setDataHandler(new DataHandler(source));
msgbody.setFileName(strname);
message.setContent(mulpart);
System.out.println("Attached the message going to start transporting the mail");
//If I've the code before sending the email is getting sent but without attachment.
//Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );
Transport.send(message);
System.out.println("Mail Sent successfully");
}
catch(MessagingException msg){
msg.printStackTrace();
}
catch(Exception e){
e.printStackTrace();
}
}
答案 0 :(得分:32)
JavaMail依赖于一些配置文件来将MIME类型映射到Java类(例如,multipart/mixed
到javax.mail.internet.MimeMultipart
)。使用应用程序的ClassLoader加载这些配置文件。如果ClassLoader无法正常运行,则无法找到这些配置文件。
您可以简单地添加以下行...来解决问题。
MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
mc.addMailcap("message/rfc822;; x-java-content- handler=com.sun.mail.handlers.message_rfc822");
答案 1 :(得分:18)
通过以下两个步骤可以解决此问题。
答案 2 :(得分:6)
在发送电子邮件之前添加当前线程是解决方案:
Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );
答案 3 :(得分:5)
我正在将Java 8项目转换为Java10。与此同时,我一直在更新所有依赖项。我遇到了类似的例外,上述解决方案都无法为我服务。
我的pom.xml中包含以下内容:
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.1</version>
</dependency>
我做了一些研究,发现了以下链接:
http://www.jguru.com/faq/view.jsp?EID=237257
所以我尝试将以下依赖项添加到我的pom.xml中:
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
解决了这个问题,我能够再次发送带有附件的邮件。
答案 4 :(得分:1)
如果这是一个android项目,那么proguard很可能会错误地删除未使用的类,请在proguard文件中添加以下几行来解决问题,而无需直接修改代码:
-keep class com.sun.mail.handlers.**
-dontwarn com.sun.mail.handlers.handler_base
答案 5 :(得分:1)
在OSGI下,以下变通办法允许javax.activation捆绑包从javax.mail捆绑包中加载“ META-INF / mailcap”资源:
Thread.currentThread().setContextClassLoader(javax.mail.Message.class.getClassLoader());
注意:此解决方法可能会限制字符集转换...
答案 6 :(得分:0)
告诉我有关运行代码的环境的更多信息。您使用的JDK是什么?你在应用服务器上运行吗?
JavaBeans Activation Framework(JAF)查找配置文件,该文件告诉如何将MIME类型映射到处理它们的Java类(DataContentHandlers)。它使用ClassLoader查找配置文件。如果ClassLoader出现问题,则可能找不到配置文件。
您可能想尝试here所述的解决方法,但当然最好为您确定问题的根本原因。
最后,您可能希望通过修复其中一些common JavaMail mistakes来简化您的程序。
答案 7 :(得分:0)
如果您的build.xml执行此操作: zipfileset src =“javamail-1.4.7 / mail.jar” excludes =“META-INF / ”**
然后你要删除配置信息。
答案 8 :(得分:0)
Som的答案(MailcapCommandMap
)与Liferay 7.1 ga1中的Spring war Portlet一起为我工作。但是,我不得不从mail.jar
中删除Tomcat的tomcat/lib/ext
并替换为javax.mail-1.6.2.jar
,然后确保依赖项的范围是项目的pom.xml中提供的:
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
<scope>provided</scope>
</dependency>
答案 9 :(得分:0)
Som的答案对我有用。但是,当我使用JavaMail DSN时,我不得不修改映射,并且还需要那些mailcap条目(包括在下面,包括Som的答案):
// Original answer from Som:
MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
// Additional elements to make DSN work
mc.addMailcap("multipart/report;; x-java-content-handler=com.sun.mail.dsn.multipart_report");
mc.addMailcap("message/delivery-status;; x-java-content-handler=com.sun.mail.dsn.message_deliverystatus");
mc.addMailcap("message/disposition-notification;; x-java-content-handler=com.sun.mail.dsn.message_dispositionnotification");
mc.addMailcap("text/rfc822-headers;; x-java-content-handler=com.sun.mail.dsn.text_rfc822headers");
事实证明,这是将DSN JAR添加到我的胖JAR中(使用shadowJar / Gradle)引起的问题:DSN jar中的META-INF / mailcap覆盖了核心。
答案 10 :(得分:0)
即使我也遇到过同样的问题。我尝试了不同版本的javamail,但没有用。问题是Transport.send()
正在使用默认Java jdk(在我的情况下为JAVA 8)中的MailCapCommandMap
类,该类加载了过时的mailcap文件。
因此,我使用了最新版本的JAVA,之后它使用了来自 activation 软件包的MailCapCommandMap
,该软件包加载了正确的mailcap文件。
如果将来有人遇到相同的问题,只需在可用的MailCapCommandMap
类中添加一个断点,以使您知道它正在使用哪个mailcap文件。
答案 11 :(得分:0)
在 Java 12 上运行 Java 8 S/MIME 解析代码时出现了类似的问题。
相关(缺失)DCH 用于自定义 MIME 类型 message/disposition-notification
。
与旧 Java 的原生 javax.activation.ObjectDataContentHandler
不同,
Java 9+ 的外部 javax.activation:activation
库似乎不能容忍“未知”MIME 类型;
早些时候,具有此类自定义内容类型的多部分“部分”(在 mailcap
元文件中找不到)
如果它们包含 byte[]
或 String
内容,仍然会被消费 - 但不再是了。
// old native
public void writeTo(Object obj, String mimeType, OutputStream os) throws IOException {
if (this.dch != null) {
this.dch.writeTo(obj, mimeType, os);
} else if (obj instanceof byte[]) {
os.write((byte[])((byte[])obj));
} else {
if (!(obj instanceof String)) {
throw new UnsupportedDataTypeException("no object DCH for MIME type " + this.mimeType);
}
OutputStreamWriter osw = new OutputStreamWriter(os);
osw.write((String)obj);
osw.flush();
}
}
// new javax.activation:activation
public void writeTo(Object obj, String mimeType, OutputStream os)
throws IOException {
if (dch != null)
dch.writeTo(obj, mimeType, os);
else
throw new UnsupportedDataTypeException(
"no object DCH for MIME type " + this.mimeType);
}
解决方案是为 message/disposition-notification
定义一个条目(它可以安全地解释为文本)
在 mailcap
文件中;技术上类似于@Som 的回答,但我们都喜欢无代码解决方案,对吗?
message/disposition-notification;;x-java-content-handler=com.sun.mail.handlers.text_plain
并将其捆绑到 JAR(类路径)中;例如使用 Maven:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>META-INF/mailcap</include>
</includes>
</resource>
</resources>
</build>
另外值得注意的是:在 JVM 上设置一个 -Djavax.activation.debug=true
系统属性,
极大地帮助跟踪与此类 mailcap
加载、处理、回退等相关的问题。