2

I'm using saaj to get attachments with my java servlet (hosted with apache and tomcat).

When trying to call message.getAttachments(); (where message is SOAPMessage object):

  • If the attachment is small (few KB) - it works

  • If the attachment is big (few MB) - it throws the following exception:

     java.lang.RuntimeException: org.jvnet.mimepull.MIMEParsingException: java.io.IOException: The system cannot find the path specified
        at com.sun.xml.messaging.saaj.soap.MessageImpl.getAttachments(MessageImpl.java:826)
        at MyCode.MyServlet.doPost(MyServlet.java:215)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
        at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
        at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:283)
        at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:767)
        at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:697)
        at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:889)
        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690)
        at java.lang.Thread.run(Unknown Source)
    Caused by: org.jvnet.mimepull.MIMEParsingException: java.io.IOException: The system cannot find the path specified
        at org.jvnet.mimepull.MemoryData.createNext(MemoryData.java:93)
        at org.jvnet.mimepull.Chunk.createNext(Chunk.java:59)
        at org.jvnet.mimepull.DataHead.addBody(DataHead.java:82)
        at org.jvnet.mimepull.MIMEPart.addBody(MIMEPart.java:192)
        at org.jvnet.mimepull.MIMEMessage.makeProgress(MIMEMessage.java:235)
        at org.jvnet.mimepull.MIMEMessage.parseAll(MIMEMessage.java:176)
        at org.jvnet.mimepull.MIMEMessage.getAttachments(MIMEMessage.java:101)
        at com.sun.xml.messaging.saaj.packaging.mime.internet.MimePullMultipart.parseAll(MimePullMultipart.java:118)
        at com.sun.xml.messaging.saaj.packaging.mime.internet.MimePullMultipart.parse(MimePullMultipart.java:129)
        at com.sun.xml.messaging.saaj.packaging.mime.internet.MimeMultipart.getCount(MimeMultipart.java:199)
        at com.sun.xml.messaging.saaj.soap.MessageImpl.initializeAllAttachments(MessageImpl.java:1384)
        at com.sun.xml.messaging.saaj.soap.MessageImpl.getAttachments(MessageImpl.java:824)
        ... 22 more
    Caused by: java.io.IOException: The system cannot find the path specified
        at java.io.WinNTFileSystem.createFileExclusively(Native Method)
        at java.io.File.createTempFile(Unknown Source)
        at java.io.File.createTempFile(Unknown Source)
        at org.jvnet.mimepull.MemoryData.createNext(MemoryData.java:87)
        ... 33 more
    

How can I solve this issue?

Thanks!

Michael-O
  • 18,123
  • 6
  • 55
  • 121
Matan
  • 680
  • 2
  • 14
  • 24
  • 1
    According to the exception the large file cannot be found, are you sure the file exists and you use the correct path? – Veger Dec 20 '12 at 12:23
  • I think that the implementation uses temp files in order to handle large attachments. I think that it tries to write it to a non-exist location. I just dont know where is it. The attachment comes from the net (with soap) – Matan Dec 20 '12 at 12:37

2 Answers2

2

The sourcecode of MimePull, which produces the Exception, says this:

if (!config.isOnlyMemory() && dataHead.inMemory >= config.memoryThreshold) {
         try {
             String prefix = config.getTempFilePrefix();
             String suffix = config.getTempFileSuffix();
             File dir = config.getTempDir();
             File tempFile = (dir == null)
                     ? File.createTempFile(prefix, suffix) // here your code crashes
                     : File.createTempFile(prefix, suffix, dir);
             LOGGER.fine("Created temp file = "+tempFile);
             dataHead.dataFile = new DataFile(tempFile);
         } catch(IOException ioe) {
             throw new MIMEParsingException(ioe);
         }

It tries to open a temp file, because the memory size threshold is passed.
It is called

at MyCode.MyServlet.doPost(MyServlet.java:215)

It looks like you are using SAAJ to receive the messages and have enabled the MimePull plugin (using -Dsaaj.use.mimepull=true flag). It should allow receiving larger files, as the MimePull implementation uses temporary files as a fallback.

Now the bad news seems to be, that you can't configure the MimePull reader through your SAAJ configuration. The good news may be that you are able to tweak the logic of File.createTempFile(...) through the system property java.io.tmpdir.

Try starting with -Djava.io.tmpdir=/path/to/tmpdir.

Else maybe try to consume the message directly with MimePull I never did this myself, so don't ask me about it. ;-)

EDIT:
Or switch off MimePull completely by setting -Dsaaj.use.mimepull=false if you do not expect your attachments to soak up all your memory.

Udo Klimaschewski
  • 5,150
  • 1
  • 28
  • 41
0

We solved the problem by just changing the Jersey-Libs version from 1.13 to 1.19. Seems that 1.13 is buggy.

Brain
  • 447
  • 7
  • 21