Java error: java.io.IOException: Stream closed when trying to import a zip file into Mendix using Java action

83 views Asked by At

I am trying to use a Mendix Java action to import a zipped file of xml files however I am getting the following errors from the Java code:

java.base/java.util.zip.ZipInputStream.ensureOpen(Unknown Source)
java.base/java.util.zip.ZipInputStream.getNextEntry(Unknown Source)
public class Zip_Upload extends CustomJavaAction<java.util.List<IMendixObject>>
{
    private IMendixObject __InputZipFile;
    private system.proxies.FileDocument InputZipFile;

    public Zip_Upload(IContext context, IMendixObject InputZipFile)
    {
        super(context);
        this.__InputZipFile = InputZipFile;
    }

    @java.lang.Override
    public java.util.List<IMendixObject> executeAction() throws Exception
    {
        this.InputZipFile = this.__InputZipFile == null ? null : system.proxies.FileDocument.initialize(getContext(), __InputZipFile);

        // BEGIN USER CODE
        
        
        List<IMendixObject> ZipFiles = new ArrayList<IMendixObject>();
        
        InputStream fileInputStream = Core.getFileDocumentContent(getContext(), InputZipFile.getMendixObject());
        
        
        byte[] buffer = IOUtils.toByteArray(fileInputStream);
        fileInputStream.close();
        int bufferlength = buffer.length;
        
        /*String filename = "temp.zip";
        File myFile = new File(Core.getConfiguration().getResourcesPath() + File.separator + filename);
        myFile.createNewFile();
        
        OutputStream outStream = new FileOutputStream(myFile);
        outStream.write(buffer);
        outStream.close();
        */
        InputStream clonedStream = new ByteArrayInputStream(buffer);
        
        int clonedlength = clonedStream.available();
        
        Core.getLogger("Zip Import").log(LogLevel.INFO, "Byte Array Length = " + bufferlength);
        Core.getLogger("Zip Import").log(LogLevel.INFO, "Cloned Input Stream Length = " + clonedlength);
        ZipEntry ze;    
        
        ZipInputStream zis = new ZipInputStream(clonedStream);
        int zislength = zis.available();
        Core.getLogger("Zip Import").log(LogLevel.INFO, "Zip Input Stream availability = " + zislength);
        if ((ze = zis.getNextEntry()) != null) {
            IMendixObject FD = Core.instantiate(getContext(),flatfileinterfacecustomizations.proxies.ImportExportDocument.getType());
            Core.storeFileDocumentContent(getContext(), FD, zis);
            FD.setValue(getContext(), flatfileinterfacecustomizations.proxies.ImportExportDocument.MemberNames.Name.toString(), ze.getName());
            ZipFiles.add(FD);                       
        }
        
        
        zis.close();
        clonedStream.close();
        return ZipFiles;
        
        
        // END USER CODE
        
    }

    /**
     * Returns a string representation of this action
     * @return a string representation of this action
     */
    @java.lang.Override
    public java.lang.String toString()
    {
        return "Zip_Upload";
    }

    // BEGIN EXTRA CODE
    // END EXTRA CODE
}

I tried changing the 'while' to 'if' and this worked successfully, however this only allowed me to import 1 file, and I have multiple to import, hence needing the 'while' loop.

1

There are 1 answers

2
Tamires Araujo On

The zis.available() method returns the number of bytes available to read from the current entry. So, using if instead of while only processes the first entry in the zip archive.

Can you do the example:

ZipInputStream zis = new ZipInputStream(clonedStream);
ZipEntry ze;

while ((ze = zis.getNextEntry()) != null) {
    IMendixObject FD = Core.instantiate(getContext(), flatfileinterfacecustomizations.proxies.ImportExportDocument.getType());
    Core.storeFileDocumentContent(getContext(), FD, zis);
    FD.setValue(getContext(), flatfileinterfacecustomizations.proxies.ImportExportDocument.MemberNames.Name.toString(), ze.getName());
    ZipFiles.add(FD);
    
    zis.closeEntry();
}

zis.close();
clonedStream.close();

Is that what you need?