Thursday, October 8, 2026

Oracle 19.32 OJVM ZipFile.getInputStream(ZipEntry entry) empty

This Blogs shows that in 19.32 OJVM, ZipFile.getInputStream(ZipEntry entry) can return empty for some of entries,
whereas in lower version (e.g.19.31), all entries are not empty.


1. Test Code



create or replace java source named s."DocxZipReadTest" as

import java.io.*;
import java.util.zip.*;

public class DocxZipReadTest {

  public static void readZip(String zipInFilePathname) throws IOException {
    ZipInputStream zipInStream   = new ZipInputStream(new FileInputStream(zipInFilePathname));
    System.out.println("zipInFilePathname = " + zipInFilePathname);

    ZipEntry    entry;
    ZipFile     zFile = new ZipFile(zipInFilePathname);
    InputStream inStream;
    int         counter     = 0;

    while ((entry = zipInStream.getNextEntry()) != null) {
      counter++;
      inStream = zFile.getInputStream(entry);   //@TODO can return null, fail

      if (inStream != null) {
        System.out.println(counter + ": === Read Check existed, Name = " + entry.getName() + ", Size() = " + entry.getSize());
        inStream.close();
      } else {
        System.out.println(counter + ": ===>>> Read Check NULL, Name = " + entry.getName() + "  is InputStream Null !!! <<<===");
        //inStream.read(byte[] b) throws NullPointerException
      }
    }
    zipInStream.close();
  }
}
/

create or replace procedure readDocxZipReadTest(p_zipFilePathAndName varchar2) as language java
name 'DocxZipReadTest.readZip(java.lang.String)';
/

2. 19.32 Test Output


Create a MS docx file (Microsoft Word for Microsoft 365 MSO 64-bit): test_create_1.docx, and put it under /tmp directory.

Run following test, the output shows that among 34 entries, 9 are marked with "InputStream Null".
If we read from those entries, Java throws NullPointerException.

SQl > select version_full from v$instance;

  VERSION_FULL
  -----------------
  19.32.0.0.0

SQl > select dbms_java.get_ojvm_property(propstring=>'java.version') java_version from dual;

  JAVA_VERSION
  ---------------
  1.8.0_501

SQl > set serveroutput on size 50000
SQl > exec dbms_java.set_output(50000);

SQl > exec readDocxZipReadTest('/tmp/test_create_1.docx');

  zipInFilePathname = /tmp/test_create_1.docx
    1: ===>>> Read Check NULL, Name = [Content_Types].xml  is InputStream Null !!! <<<===
    2: ===>>> Read Check NULL, Name = _rels/.rels  is InputStream Null !!! <<<===
    3: === Read Check existed, Name = word/document.xml, Size() = 3930
    4: ===>>> Read Check NULL, Name = word/_rels/document.xml.rels  is InputStream Null !!! <<<===
    5: === Read Check existed, Name = word/footnotes.xml, Size() = 3172
    6: === Read Check existed, Name = word/endnotes.xml, Size() = 3166
    7: === Read Check existed, Name = word/header2.xml, Size() = 4479
    8: === Read Check existed, Name = word/footer2.xml, Size() = 5762
    9: === Read Check existed, Name = word/header1.xml, Size() = 4548
    10: === Read Check existed, Name = word/footer1.xml, Size() = 8581
    11: === Read Check existed, Name = word/_rels/header1.xml.rels, Size() = 289
    12: === Read Check existed, Name = word/_rels/header2.xml.rels, Size() = 289
    13: === Read Check existed, Name = word/theme/theme1.xml, Size() = 6735
    14: === Read Check existed, Name = word/media/image1.png, Size() = 35674
    15: === Read Check existed, Name = word/settings.xml, Size() = 5996
    16: === Read Check existed, Name = customXml/item1.xml, Size() = 289
    17: === Read Check existed, Name = customXml/itemProps1.xml, Size() = 341
    18: === Read Check existed, Name = customXml/item2.xml, Size() = 219
    19: === Read Check existed, Name = customXml/itemProps2.xml, Size() = 335
    20: === Read Check existed, Name = customXml/item3.xml, Size() = 17627
    21: === Read Check existed, Name = customXml/itemProps3.xml, Size() = 1277
    22: === Read Check existed, Name = customXml/item4.xml, Size() = 1059
    23: === Read Check existed, Name = customXml/itemProps4.xml, Size() = 675
    24: === Read Check existed, Name = word/numbering.xml, Size() = 52220
    25: === Read Check existed, Name = word/styles.xml, Size() = 56750
    26: === Read Check existed, Name = word/webSettings.xml, Size() = 1069
    27: === Read Check existed, Name = word/fontTable.xml, Size() = 2893
    28: ===>>> Read Check NULL, Name = docProps/core.xml  is InputStream Null !!! <<<===
    29: ===>>> Read Check NULL, Name = docProps/app.xml  is InputStream Null !!! <<<===
    30: === Read Check existed, Name = docMetadata/LabelInfo.xml, Size() = 307
    31: ===>>> Read Check NULL, Name = customXml/_rels/item1.xml.rels  is InputStream Null !!! <<<===
    32: ===>>> Read Check NULL, Name = customXml/_rels/item2.xml.rels  is InputStream Null !!! <<<===
    33: ===>>> Read Check NULL, Name = customXml/_rels/item3.xml.rels  is InputStream Null !!! <<<===
    34: ===>>> Read Check NULL, Name = customXml/_rels/item4.xml.rels  is InputStream Null !!! <<<===

3. 19.31 Test Output


Run the same test on Oracle 19.31, no empty entry can be found.

SQL > select version_full from v$instance;

  VERSION_FULL
  -----------------
  19.31.0.0.0

SQL > select dbms_java.get_ojvm_property(propstring=>'java.version') java_version from dual;

  JAVA_VERSION
  ---------------
  1.8.0_491

SQL > exec readDocxZipReadTest('/tmp/test_create_1.docx');
  zipInFilePathname = /tmp/test_create_1.docx
    1: === Read Check existed, Name = [Content_Types].xml, Size() = 2913
    2: === Read Check existed, Name = _rels/.rels, Size() = 736
    3: === Read Check existed, Name = word/document.xml, Size() = 4082
    4: === Read Check existed, Name = word/_rels/document.xml.rels, Size() = 2301
    5: === Read Check existed, Name = word/footnotes.xml, Size() = 3172
    6: === Read Check existed, Name = word/endnotes.xml, Size() = 3166
    7: === Read Check existed, Name = word/header2.xml, Size() = 4479
    8: === Read Check existed, Name = word/footer2.xml, Size() = 5762
    9: === Read Check existed, Name = word/header1.xml, Size() = 4548
    10: === Read Check existed, Name = word/footer1.xml, Size() = 8581
    11: === Read Check existed, Name = word/_rels/header1.xml.rels, Size() = 289
    12: === Read Check existed, Name = word/_rels/header2.xml.rels, Size() = 289
    13: === Read Check existed, Name = word/theme/theme1.xml, Size() = 6735
    14: === Read Check existed, Name = word/media/image1.png, Size() = 35674
    15: === Read Check existed, Name = word/settings.xml, Size() = 6100
    16: === Read Check existed, Name = customXml/item1.xml, Size() = 289
    17: === Read Check existed, Name = customXml/itemProps1.xml, Size() = 341
    18: === Read Check existed, Name = customXml/item2.xml, Size() = 219
    19: === Read Check existed, Name = customXml/itemProps2.xml, Size() = 335
    20: === Read Check existed, Name = customXml/item3.xml, Size() = 17627
    21: === Read Check existed, Name = customXml/itemProps3.xml, Size() = 1277
    22: === Read Check existed, Name = customXml/item4.xml, Size() = 1059
    23: === Read Check existed, Name = customXml/itemProps4.xml, Size() = 675
    24: === Read Check existed, Name = word/numbering.xml, Size() = 52220
    25: === Read Check existed, Name = word/styles.xml, Size() = 56750
    26: === Read Check existed, Name = word/webSettings.xml, Size() = 1069
    27: === Read Check existed, Name = word/fontTable.xml, Size() = 2893
    28: === Read Check existed, Name = docProps/core.xml, Size() = 741
    29: === Read Check existed, Name = docProps/app.xml, Size() = 711
    30: === Read Check existed, Name = docMetadata/LabelInfo.xml, Size() = 307
    31: === Read Check existed, Name = customXml/_rels/item1.xml.rels, Size() = 296
    32: === Read Check existed, Name = customXml/_rels/item2.xml.rels, Size() = 296
    33: === Read Check existed, Name = customXml/_rels/item3.xml.rels, Size() = 296
    34: === Read Check existed, Name = customXml/_rels/item4.xml.rels, Size() = 296

4. Fix


Here is a 19.32 OJVM fix which uses ZipInputStream.getNextEntry.
(method entryRead is added to verfiy InputStream.read(buffer)).

create or replace java source named s."DocxZipReadTest" as

import java.io.*;
import java.util.zip.*;

public class DocxZipReadTest {

  public static void readZip(String zipInFilePathname) throws IOException {
    ZipInputStream zipInStream   = new ZipInputStream(new FileInputStream(zipInFilePathname));
    System.out.println("zipInFilePathname = " + zipInFilePathname);

    ZipEntry    entry;
    //ZipFile     zFile = new ZipFile(zipInFilePathname);
    InputStream inStream;
    int         counter     = 0;

    while ((entry = zipInStream.getNextEntry()) != null) {
      counter++;
      inStream = (InputStream)zipInStream;   

      if (inStream != null) {
        System.out.println(counter + ": === Read Check existed, Name = " + entry.getName() + ", Size() = " + entry.getSize());
      } else {
        System.out.println(counter + ": ===>>> Read Check NULL, Name = " + entry.getName() + "  is InputStream Null !!! <<<===");
        //inStream.read(byte[] b) throws NullPointerException
      }
      //entryRead(inStream);
    }
    zipInStream.close();
  }

   static void entryRead(InputStream inStream) throws IOException {
    int  num;
    int  writeCount = 0;
    long byteCount  = 0;
    byte[] buffer   = new byte[10000];
    while ((num = inStream.read(buffer)) > 0) {
      writeCount++;
      byteCount  += num;
    }
    System.out.println("------------------- entryRead byteCount = " + byteCount + " by writeCount = " + writeCount);
  }
}