【问题标题】:Error Retrieving Mail from Gmail with JavaMail + Scala使用 JavaMail + Scala 从 Gmail 中检索邮件时出错
【发布时间】:2014-02-21 17:47:29
【问题描述】:

我正在尝试使用 Scala 和 JavaMail + gimaps(Gmail 扩展)。我目前正在使用两者的 v1.5.1,scala 2.10.3,java JDK 1.7.0_45。一切都差不多了,我可以获得一个 GmailSSLStore,我可以将一个 GmailFolder 加载到一个名为 allMail 的变量中。

但是,当我调用 allMail.getMessages() 时,它并没有像我期望的那样返回 GmailMessage,而是返回正常的 IMAPMessages。知道为什么会这样吗?我单步执行了代码,看起来 GmailProtocol 可能没有正确使用,但我不知道为什么会这样。任何帮助将不胜感激!

这是在阿卡,顺便说一句。

  var store: GmailStore = _
  var allMail: GmailFolder = _

  override def preStart = {
    val props = System.getProperties()
    props.put("mail.debug", "true")
    props.put("mail.store.protocol", "gimaps")

    val session = Session.getDefaultInstance(props, null)
    store = session.getStore("gimaps").asInstanceOf[GmailStore]
    store.connect("test@gmail.com", "Password" )
    val folders = store.getDefaultFolder.list("*").map(m => m.asInstanceOf[GmailFolder])
    allMail = folders.filter(m => m.getAttributes.contains("\\All")).head
    allMail.open(Folder.READ_ONLY)
  }

//Some Code Elided

def getMail() = {
   val ms = allMail.getMessages()
   val fp = new FetchProfile()
   fp.add(GmailFolder.FetchProfileItem.MSGID)
   fp.add(GmailFolder.FetchProfileItem.THRID)
   fp.add(GmailFolder.FetchProfileItem.LABELS)
   allMail.fetch(ms, fp)
   val messages = ms.map(m => {
      m.asInstanceOf[GmailMessage]  // <--- This line crashes, m is IMAPMessage
   })
}

输出如下。请注意,我只是看到可能存在问题,为什么它在那里列出 JavaMail 1.4.4?依赖项在 Built.SBT 中设置得很清楚

  "com.sun.mail" % "javax.mail" % "1.5.1",
  "com.sun.mail" % "gimap" % "1.5.1"

控制台输出:

DEBUG: JavaMail version 1.4.4
DEBUG: URL jar:file:/C:/Users/Patrick/.ivy2/cache/com.sun.mail/gimap/jars/gimap-1.4.7.jar!/META-INF/javamail.providers
DEBUG: successfully loaded resource: jar:file:/C:/Users/Patrick/.ivy2/cache/com.sun.mail/gimap/jars/gimap-1.4.7.jar!/META-INF/javamail.providers
DEBUG: URL jar:file:/C:/Source/GIT/Core/sync/lib/gimap-1.5.1.jar!/META-INF/javamail.providers
DEBUG: successfully loaded resource: jar:file:/C:/Source/GIT/Core/sync/lib/gimap-1.5.1.jar!/META-INF/javamail.providers
DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
DEBUG: Tables of loaded providers
DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun Microsystems, Inc], com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], com.sun.mail.gimap.GmailSSLStore=javax.mail.Provider[STORE,gimaps,com.sun.mail.gimap.GmailSSLStore,Oracle], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun Microsystems, Inc], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc], com.sun.mail.gimap.GmailStore=javax.mail.Provider[STORE,gimap,com.sun.mail.gimap.GmailStore,Oracle], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc]}
DEBUG: Providers Listed By Protocol: {imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc], gimap=javax.mail.Provider[STORE,gimap,com.sun.mail.gimap.GmailStore,Oracle], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun Microsystems, Inc], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun Microsystems, Inc], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc], gimaps=javax.mail.Provider[STORE,gimaps,com.sun.mail.gimap.GmailSSLStore,Oracle]}
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
DEBUG: getProvider() returning javax.mail.Provider[STORE,gimaps,com.sun.mail.gimap.GmailSSLStore,Oracle]
DEBUG: mail.imap.fetchsize: 16384
DEBUG: mail.imap.statuscachetimeout: 1000
DEBUG: mail.imap.appendbuffersize: -1
DEBUG: mail.imap.minidletime: 10
DEBUG: trying to connect to host "imap.gmail.com", port 993, isSSL true
* OK Gimap ready for requests from 173.164.155.206 zl9mb39448964pac
A0 CAPABILITY
* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN
A0 OK Thats all she wrote! zl9mb39448964pac
DEBUG IMAP: AUTH: XOAUTH
DEBUG IMAP: AUTH: XOAUTH2
DEBUG IMAP: AUTH: PLAIN
DEBUG IMAP: AUTH: PLAIN-CLIENTTOKEN
DEBUG: protocolConnect login, host=imap.gmail.com, user=test@gmail.com, password=<non-null>
A1 AUTHENTICATE PLAIN
+ 
AHRlc3RAc3luYXRhLmNvbQBTeW5hdGExIQ==
* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH
A1 OK test@gmail.com Test Account authenticated (Success)
A2 CAPABILITY
* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH
A2 OK Success
A3 LIST "" "*"
* LIST (\HasNoChildren) "/" "INBOX"
* LIST (\Noselect \HasChildren) "/" "[Gmail]"
* LIST (\HasNoChildren \All) "/" "[Gmail]/All Mail"
* LIST (\HasNoChildren \Drafts) "/" "[Gmail]/Drafts"
* LIST (\HasNoChildren \Important) "/" "[Gmail]/Important"
* LIST (\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail"
* LIST (\HasNoChildren \Junk) "/" "[Gmail]/Spam"
* LIST (\HasNoChildren \Flagged) "/" "[Gmail]/Starred"
* LIST (\HasNoChildren \Trash) "/" "[Gmail]/Trash"
A3 OK Success
DEBUG: connection available -- size: 1
A4 EXAMINE "[Gmail]/All Mail"
* FLAGS (\Answered \Flagged \Draft \Deleted \Seen $Phishing $NotPhishing)
* OK [PERMANENTFLAGS ()] Flags permitted.
* OK [UIDVALIDITY 11] UIDs valid.
* 4 EXISTS
* 0 RECENT
* OK [UIDNEXT 590] Predicted next UID.
* OK [HIGHESTMODSEQ 148419]
A4 OK [READ-ONLY] [Gmail]/All Mail selected. (Success)
DEBUG IMAP: IMAPProtocol noop
A5 NOOP
A5 OK Success
A6 CLOSE
[ERROR] [02/21/2014 09:37:38.404] [ConnectionSystem-akka.actor.default-dispatcher-4] [akka://ConnectionSystem/user/MainConnectionManager/googleAppsConnectionManager-5305184d4500004500e8fe66/gmailManager/$a] com.sun.mail.imap.IMAPMessage cannot be cast to com.sun.mail.gimap.GmailMessage
java.lang.ClassCastException: com.sun.mail.imap.IMAPMessage cannot be cast to com.sun.mail.gimap.GmailMessage
    at com.test.sync.google.GmailSyncer$$anonfun$firstSync$1$$anonfun$2.apply(GmailSyncer.scala:90)
    at com.test.sync.google.GmailSyncer$$anonfun$firstSync$1$$anonfun$2.apply(GmailSyncer.scala:89)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
    at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:108)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
    at scala.collection.mutable.ArrayOps$ofRef.map(ArrayOps.scala:108)
    at com.test.sync.google.GmailSyncer$$anonfun$firstSync$1.applyOrElse(GmailSyncer.scala:89)
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala:498)
    at akka.actor.ActorCell.invoke(ActorCell.scala:456)
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:237)
    at akka.dispatch.Mailbox.run(Mailbox.scala:219)
    at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:386)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

A6 OK Returned to authenticated state. (Success)
DEBUG: added an Authenticated connection -- size: 1
A7 LOGOUT
* BYE LOGOUT Requested
A7 OK 73 good day (Success)
DEBUG: IMAPStore connection dead
DEBUG: IMAPStore cleanup, force false
DEBUG: IMAPStore cleanup done

【问题讨论】:

    标签: scala gmail jakarta-mail


    【解决方案1】:

    我猜你的类路径中有 JavaMail 1.4.4 和 JavaMail 1.5.1。尽管它从 JavaMail 1.5.1 中找到了“gimaps”提供程序,但它使用的是 1.4.4 中的 IMAP 类,并且这些类没有允许 gimaps 提供程序扩展它并提供特定于 Gmail 的支持的挂钩。

    【讨论】:

    • 看起来是这种情况,如果我将 1.5.1 的两个 jar 放入 lib 中,它就会开始工作。后续问题是,如何使用 sbt 和没有硬库依赖项来实现它?但是,谢谢!
    【解决方案2】:

    好的,我们终于真正想通了,我希望这可以帮助其他人。

    基本上,Lift 对 Java Mail 1.4.4 有传递依赖,但是,它与我们引用的包装不同(javax.mail、javamail、1.4.4 与 sun.com.mail、javax.mail、1.5 .1)。所以,我几乎把它归类为一个错误,但是有重叠的罐子和重叠的包名称,但 SBT 并没有将它识别为真正的依赖冲突。根据 JVM 的心情,将加载 1.4.4 jar 或 1.5.1 jar,这意味着当我们认为我们正在调用 1.5.1 库时,我们会时不时地看到 NoMethodFound 异常,但实际上正在加载 1.4.4 库。

    我们只是通过搜索依赖解析日志来调试这个问题,但在我们可以使用 ivy 依赖报告查看哪个库依赖于旧的 Java Mail 组件之后,我们也了解到。

    【讨论】:

      猜你喜欢
      • 2011-03-14
      • 1970-01-01
      • 2011-07-19
      • 2012-10-10
      • 2012-04-17
      • 2015-12-24
      • 2014-03-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多