目录
1.背景
2.分析问题
3.解决
4.重启
当我们搭建好james server后,所有操作都执行成功,foxmail作为客户端测试时,发送完文件,另一账号就是仍然收不到邮件, 而且编码使用javam mail 的IAMPFolder.appendMessages()也不能成功,非常纳闷,我也尝试了很久,尝试到怀疑人生,网上提问也未解决,详细请看https://bbs.csdn.net/topics/392368913,最终还是在自己的努力下解决了。
在james服务端查看james-server.log日志发现报了如下错误:
ERROR 01:00:08,002 | james.mailprocessor | Exception calling ToSenderFolder: Unable to access mailbox.
javax.mail.MessagingException: Unable to access mailbox.;
nested exception is:
org.apache.james.mailbox.exception.MailboxException: Unable to parse message
at org.apache.james.transport.mailets.delivery.MailboxAppender.append(MailboxAppender.java:73)
at org.apache.james.transport.mailets.delivery.MailboxAppender.append(MailboxAppender.java:53)
at org.apache.james.transport.mailets.ToSenderFolder.doService(ToSenderFolder.java:84)
at org.apache.james.transport.mailets.ToSenderFolder.service(ToSenderFolder.java:73)
at org.apache.james.mailetcontainer.impl.camel.CamelProcessor.process(CamelProcessor.java:72)
at org.apache.camel.processor.DelegateSyncProcessor.process(DelegateSyncProcessor.java:63)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:416)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.ChoiceProcessor.process(ChoiceProcessor.java:111)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:416)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:416)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:570)
at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:503)
at org.apache.camel.processor.MulticastProcessor.process(MulticastProcessor.java:215)
at org.apache.camel.processor.Splitter.process(Splitter.java:98)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:416)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:51)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.UnitOfWorkProducer.process(UnitOfWorkProducer.java:73)
at org.apache.camel.impl.ProducerCache$2.doInProducer(ProducerCache.java:375)
at org.apache.camel.impl.ProducerCache$2.doInProducer(ProducerCache.java:343)
at org.apache.camel.impl.ProducerCache.doInProducer(ProducerCache.java:233)
at org.apache.camel.impl.ProducerCache.sendExchange(ProducerCache.java:343)
at org.apache.camel.impl.ProducerCache.send(ProducerCache.java:184)
at org.apache.camel.impl.DefaultProducerTemplate.send(DefaultProducerTemplate.java:124)
at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:137)
at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:144)
at org.apache.james.mailetcontainer.impl.camel.CamelMailetProcessor.service(CamelMailetProcessor.java:72)
at org.apache.james.mailetcontainer.lib.AbstractStateCompositeProcessor.service(AbstractStateCompositeProcessor.java:98)
at org.apache.james.mailetcontainer.lib.AbstractStateMailetProcessor.toProcessor(AbstractStateMailetProcessor.java:165)
at org.apache.james.mailetcontainer.impl.camel.CamelMailetProcessor.access$1100(CamelMailetProcessor.java:52)
at org.apache.james.mailetcontainer.impl.camel.CamelMailetProcessor$MailetContainerRouteBuilder$StateChangedProcessor.process(CamelMailetProcessor.java:223)
at org.apache.camel.processor.DelegateSyncProcessor.process(DelegateSyncProcessor.java:63)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:416)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)
at org.apache.camel.processor.ChoiceProcessor.process(ChoiceProcessor.java:111)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:416)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:416)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:570)
at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:503)
at org.apache.camel.processor.MulticastProcessor.process(MulticastProcessor.java:215)
at org.apache.camel.processor.Splitter.process(Splitter.java:98)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:416)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:51)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.UnitOfWorkProducer.process(UnitOfWorkProducer.java:73)
at org.apache.camel.impl.ProducerCache$2.doInProducer(ProducerCache.java:375)
at org.apache.camel.impl.ProducerCache$2.doInProducer(ProducerCache.java:343)
at org.apache.camel.impl.ProducerCache.doInProducer(ProducerCache.java:233)
at org.apache.camel.impl.ProducerCache.sendExchange(ProducerCache.java:343)
at org.apache.camel.impl.ProducerCache.send(ProducerCache.java:184)
at org.apache.camel.impl.DefaultProducerTemplate.send(DefaultProducerTemplate.java:124)
at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:137)
at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:144)
at org.apache.james.mailetcontainer.impl.camel.CamelMailetProcessor.service(CamelMailetProcessor.java:72)
at org.apache.james.mailetcontainer.lib.AbstractStateCompositeProcessor.service(AbstractStateCompositeProcessor.java:98)
at org.apache.james.mailetcontainer.impl.JamesMailSpooler$1.run(JamesMailSpooler.java:178)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: org.apache.james.mailbox.exception.MailboxException: Unable to parse message
at org.apache.james.mailbox.store.StoreMessageManager.appendMessage(StoreMessageManager.java:440)
at org.apache.james.transport.mailets.delivery.MailboxAppender.appendMessageToMailbox(MailboxAppender.java:85)
at org.apache.james.transport.mailets.delivery.MailboxAppender.append(MailboxAppender.java:71)
... 83 more
Caused by: java.io.IOException: 系统找不到指定的路径。
at java.io.WinNTFileSystem.createFileExclusively(Native Method)
at java.io.File.createTempFile(Unknown Source)
at java.io.File.createTempFile(Unknown Source)
at org.apache.james.mailbox.store.StoreMessageManager.appendMessage(StoreMessageManager.java:311)
... 85 more
发现是james服务本身报错,定位到位置为
org.apache.james.mailbox.store.StoreMessageManager.appendMessage(StoreMessageManager.java:311)
定位源码文件为StoreMessageManager 311行位置处的
file = File.createTempFile("imap", ".msg");
此行意思为创建临时文件,单独编写代码测试,创建文件成功,输出为
C:\Users\Win10\AppData\Local\Temp\imap4466304417383536360.msg
测试代码如下:
package createTempFile;
import java.io.File;
import java.io.IOException;
public class test {
public static void main(String[] args) {
try {
File file = File.createTempFile("imap", ".msg");
if (null != file) {
System.out.println(file.getPath());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
输出:
考虑到日志中提到:
ERROR 01:00:08,002 | james.mailprocessor | Exception calling ToSenderFolder: Unable to access mailbox.
javax.mail.MessagingException: Unable to access mailbox.;
可能是用户权限问题造成不能成功创建文件。原来james收到邮件后创建临时消息,并在成功存储后进行删除,那到底是什么原因呢,经过多方查询,终于在james issues官网上查到bug原文地址:https://issues.apache.org/jira/browse/JAMES-1514
其中解决方法为 petr在14年7月的回答:
pjotrovsky Petr added a comment - 04/Jan/14 14:56
HI, it`s a JDK issue on Windows: the win-service is running as a local account and apparently can not access the user`s temp directory for temp-files creation.
The easiest workaround is to set the java tempdir explicitely:
-open /con/wrapper.conf
-add a WRITABLE temp directory on top of additional system properties:
1.Java Additional Parameters
wrapper.java.additional.15=-Djava.io.tmpdir=J:\tmp
I haven`t played with windows-service accounts since my main target are ux-systems...
这是在windows上的jdk问题,windows上的服务作为本地用户运行,但是不能访问用户本省的temp文件目录进行临时文件的创建,最直接的方法是创建自己的java tempdir。
修改wrapper.java.additional.15=-Djava.io.tmpdir后的wrapper.conf如下所示:
此处由于启动是从bin目录启动,经测试写绝对路径会启动不起来,我这里是写的相对路径../tmp
#********************************************************************
# Wrapper Properties
#********************************************************************
# Java Application
wrapper.java.command=java
wrapper.working.dir=.
# Java Main class. This class must implement the WrapperListener interface
# or guarantee that the WrapperManager class is initialized. Helper
# classes are provided to do this for you. See the Integration section
# of the documentation for details.
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
set.default.REPO_DIR=../lib
set.APP_BASE=.
# Java Classpath (include wrapper.jar) Add class path elements as
# needed starting from 1
wrapper.java.classpath.1=%REPO_DIR%/wrapper.jar
wrapper.java.classpath.2=../conf
wrapper.java.classpath.3=%REPO_DIR%/*
wrapper.java.classpath.4=../conf/lib/*
# Java Library Path (location of Wrapper.DLL or libwrapper.so)
wrapper.java.library.path.1=lib
# Java Additional Parameters
#wrapper.java.additional.1=
#---------------------修改下面这一行------------------------------------------------------
wrapper.java.additional.15=-Djava.io.tmpdir=../tmp
wrapper.java.additional.14=-Djames.message.usememorycopy=false
wrapper.java.additional.13=-Dmail.mime.address.strict=false
wrapper.java.additional.12=-Dmail.mime.decodeparameters=true
wrapper.java.additional.11=-Dmail.mime.encodeparameters=true
wrapper.java.additional.10=-Dmail.mime.base64.ignoreerrors=true
wrapper.java.additional.9=-Dmail.mime.multipart.allowempty=true
wrapper.java.additional.8=-Dmail.mime.uudecode.ignoremissingbeginend=true
wrapper.java.additional.7=-Dmail.mime.uudecode.ignoreerrors=true
wrapper.java.additional.6=-Dmail.mime.ignoreunknownencoding=true
wrapper.java.additional.5=-Dmail.mime.multipart.ignoremissingboundaryparameter=true
wrapper.java.additional.4=-Dmail.mime.multipart.ignoremissingendboundary=true
wrapper.java.additional.3=-Dcom.sun.management.jmxremote.authenticate=false
wrapper.java.additional.2=-Dcom.sun.management.jmxremote=true
wrapper.java.additional.1=-XX:+HeapDumpOnOutOfMemoryError
# Initial Java Heap Size (in MB)
#wrapper.java.initmemory=3
wrapper.java.initmemory=128
# Maximum Java Heap Size (in MB)
#wrapper.java.maxmemory=64
wrapper.java.maxmemory=512
# Application parameters. Add parameters as needed starting from 1
wrapper.app.parameter.1=org.apache.james.app.spring.JamesAppSpringMain
wrapper.app.parameter.2=start
#********************************************************************
# Wrapper Logging Properties
#********************************************************************
# Format of output for the console. (See docs for formats)
wrapper.console.format=PM
# Log Level for console output. (See docs for log levels)
wrapper.console.loglevel=INFO
# Log file to use for wrapper output logging.
wrapper.logfile=../log/wrapper.log
# Format of output for the log file. (See docs for formats)
wrapper.logfile.format=LPTM
# Log Level for log file output. (See docs for log levels)
wrapper.logfile.loglevel=INFO
# Maximum size that the log file will be allowed to grow to before
# the log is rolled. Size is specified in bytes. The default value
# of 0, disables log rolling. May abbreviate with the 'k' (kb) or
# 'm' (mb) suffix. For example: 10m = 10 megabytes.
wrapper.logfile.maxsize=0
# Maximum number of rolled log files which will be allowed before old
# files are deleted. The default value of 0 implies no limit.
wrapper.logfile.maxfiles=0
# Log Level for sys/event log output. (See docs for log levels)
wrapper.syslog.loglevel=NONE
#********************************************************************
# Wrapper Windows Properties
#********************************************************************
# Title to use when running as a console
wrapper.console.title=Apache James :: Server :: App
#********************************************************************
# Wrapper Windows NT/2000/XP Service Properties
#********************************************************************
# WARNING - Do not modify any of these properties when an application
# using this configuration file has been installed as a service.
# Please uninstall the service before modifying this section. The
# service can then be reinstalled.
# Name of the service
wrapper.ntservice.name=james
# Display name of the service
wrapper.ntservice.displayname=Apache James :: Server :: App
# Description of the service
wrapper.ntservice.description=An advanced email server
# Service dependencies. Add dependencies as needed starting from 1
wrapper.ntservice.dependency.1=
# Mode in which the service is installed. AUTO_START or DEMAND_START
wrapper.ntservice.starttype=AUTO_START
# Allow the service to interact with the desktop.
wrapper.ntservice.interactive=false
configuration.directory.in.classpath.first=../conf
wrapper.java.library.path=../lib
configuration.directory.in.classpath.last=../conf/lib/*
修改完后,删除james生成的var目录,重新执行run.bat james start启动尝试,修复成功!