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);
}
}