Inbound SOAP/Base64 attachments stopped working
An issue with inbound attachments being saved using this mechanism has been seen in ServiceNow instances upgrading to Quebec and later which are using base64 encoded attachments. An example of this error is shown below:
InternalError: The choice of Java method com.glide.ui.SysAttachment.write matching JavaScript argument types (object,org.mozilla.javascript.ConsString,string,null) is ambiguous; candidate methods are:
class java.lang.String write(com.glide.script.GlideRecord,java.lang.String,java.lang.String,java.io.InputStream)
class java.lang.String write(com.glide.script.GlideRecord,java.lang.String,java.lang.String,java.io.File)
class java.lang.String write(com.glide.script.GlideRecord,java.lang.String,java.lang.String,java.lang.String)
class java.lang.String write(com.glide.script.GlideRecord,java.lang.String,java.lang.String,byte[])
Unifi comes packaged with a utility for helping save attachments:
AttachmentHandler.saveAttachment(record, filename, content_type, data)
There has been a change to the GlideSysAttachment
API being used by this method. Now, passing the base64 decoded string as a byte array to the global GlideSysAttachment.write()
method via the Unifi AttachmentHandler appears to only work when Unifi trace mode is on. Internal investigation has revealed that there is some interaction between ServiceNow and the Unifi scoped app which is causing the byte array to be converted to null when Unifi trace mode is off. We suspect this is because ServiceNow routes the variable through some coercion in the Rhino environment when passing it through Unifi and that forces it to work. Without the debug mode turned on, the byte array is being passed through and, for some reason that isn't clear, it is treated differently.
Workaround
To work around this issue it is recommended to modify the Extract attachments script on the message which is being used to process attachments. By adding a new saveAttachments()
function that makes use of ServiceNow's writeBase64()
method, the data does not need to be decoded like it was in the past and attachments are processed properly regardless of Unifi settings.
Binary Base64
Decoding a base64 string should be done with binary aware methods to ensure that binary files are decoded correctly. We have seen problems using methods like GlideStringUtil.base64Decode() with binary files where the attachment is created but it is not usable. This is likely the problem if plain text files are working but images are not.
Full example for Extract attachments script
Extract attachments script
This example is for a JSON payload, but the same concept applies to SOAP.
Last updated