Search code examples
coldfusioncoldfusion-2016apache-commons-io

Does CF not support Java constructors with variable number of arguments and any known workarounds?


We have a project that deals with files of various encodings. I am using BOMInputStream to skip UTF-8 byte order markers. The existing code works but needs to also support UTF-16 variations. The most straight forward approach is to pass the BOMInputStream constructor multiple ByteOrderMarkers.

Per documentation...

BOMInputStream bomIn = new BOMInputStream(in,
                               ByteOrderMark.UTF_16LE,
                               ByteOrderMark.UTF_16BE,
                               ByteOrderMark.UTF_32LE,
                               ByteOrderMark.UTF_32BE);

The constructor signature uses variable arguments:

public BOMInputStream(InputStream delegate,
          ByteOrderMark... boms)

However, when I try to call this constructor using the following code

<cfset var fis = createObject("java", "java.io.FileInputStream").init(arguments.filePath) />
<cfset var boms = createObject("java", "org.apache.commons.io.ByteOrderMark") />
<cfset var bomins = createObject("java", "org.apache.commons.io.input.BOMInputStream").init(fis, boms.UTF_8, boms.UTF_16LE, boms.UTF_16BE) />

I get the following error...

Unable to find a constructor for class org.apache.commons.io.input.BOMInputStream that accepts parameters of type ( java.io.FileInputStream, org.apache.commons.io.ByteOrderMark, org.apache.commons.io.ByteOrderMark, org.apache.commons.io.ByteOrderMark ).

I have tried just one BOM argument as well and get same error with fewer arguments in the error. So it appears that CF can't call Java constructors with unlimited arguments. Is that correct and, if so, is there any known work around?


Solution

  • Of course the moment I post an idea comes to me. It looks like these variables are accessed through an array in the Java object being called. I just changed the CF code to pass an array of BOMs instead of individual arguments and it worked as expected.

    <cfset var bomins = createObject("java", "org.apache.commons.io.input.BOMInputStream").init(
        fis, 
        [boms.UTF_8, boms.UTF_16LE, boms.UTF_16BE]
    ) />