Skip to content

Commit b047ca8

Browse files
committed
fix: drop AttachGuard only after all GlobalRefs in JReaderInputStream are dropped
1 parent 818d94c commit b047ca8

File tree

4 files changed

+16
-19
lines changed

4 files changed

+16
-19
lines changed

extractous-core/benches/extractor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ fn extract_to_stream(c: &mut Criterion) {
1010
c.bench_function("extract_to_stream", |b| {
1111
b.iter(|| {
1212
// Extract the provided file content to a stream
13-
let stream = extractor.extract_file(file_path).unwrap();
13+
let (stream, _) = extractor.extract_file(file_path).unwrap();
1414
// Because stream implements std::io::Read trait we can perform buffered reading
1515
// For example we can use it to create a BufReader
1616
let mut reader = BufReader::new(stream);

extractous-core/src/extractor.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub enum CharSet {
3636
/// ```
3737
///
3838
pub struct StreamReader {
39-
pub(crate) inner: JReaderInputStream,
39+
pub(crate) inner: JReaderInputStream<'static>,
4040
}
4141

4242
impl std::io::Read for StreamReader {
@@ -202,7 +202,6 @@ impl Extractor {
202202
self.xml_output,
203203
)
204204
}
205-
206205
}
207206

208207
#[cfg(test)]

extractous-core/src/tika/parse.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ pub(crate) fn vm() -> &'static JavaVM {
1818
GRAAL_VM.get_or_init(create_vm_isolate)
1919
}
2020

21-
fn get_vm_attach_current_thread<'local>() -> ExtractResult<AttachGuard<'local>> {
21+
fn get_vm_attach_current_thread() -> ExtractResult<AttachGuard<'static>> {
2222
// Attaching a thead that is already attached is a no-op. Good to have this in case this method
2323
// is called from another thread
2424
let env = vm().attach_current_thread()?;
2525
Ok(env)
2626
}
2727

2828
fn parse_to_stream(
29-
mut env: AttachGuard,
29+
mut env: AttachGuard<'static>,
3030
data_source_val: JValue,
3131
char_set: &CharSet,
3232
pdf_conf: &PdfParserConfig,
@@ -60,7 +60,7 @@ fn parse_to_stream(
6060

6161
// Create and process the JReaderResult
6262
let result = JReaderResult::new(&mut env, call_result_obj)?;
63-
let j_reader = JReaderInputStream::new(&mut env, result.java_reader)?;
63+
let j_reader = JReaderInputStream::new(env, result.java_reader)?;
6464

6565
Ok((StreamReader { inner: j_reader }, result.metadata))
6666
}
@@ -71,7 +71,7 @@ pub fn parse_file(
7171
pdf_conf: &PdfParserConfig,
7272
office_conf: &OfficeParserConfig,
7373
ocr_conf: &TesseractOcrConfig,
74-
as_xml: bool
74+
as_xml: bool,
7575
) -> ExtractResult<(StreamReader, Metadata)> {
7676
let mut env = get_vm_attach_current_thread()?;
7777

extractous-core/src/tika/wrappers.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,29 @@ use crate::{Metadata, OfficeParserConfig, PdfParserConfig, TesseractOcrConfig, D
88
use bytemuck::cast_slice_mut;
99
use jni::objects::{GlobalRef, JByteArray, JObject, JValue};
1010
use jni::sys::jsize;
11-
use jni::JNIEnv;
11+
use jni::{AttachGuard, JNIEnv};
1212

1313
/// Wrapper for [`JObject`]s that contain `org.apache.commons.io.input.ReaderInputStream`
1414
/// It saves a GlobalRef to the java object, which is cleared when the last GlobalRef is dropped
1515
/// Implements [`Drop] trait to properly close the `org.apache.commons.io.input.ReaderInputStream`
16-
#[derive(Clone)]
17-
pub struct JReaderInputStream {
16+
pub struct JReaderInputStream<'local> {
1817
internal: GlobalRef,
1918
buffer: GlobalRef,
2019
capacity: jsize,
20+
_guard: AttachGuard<'local>,
2121
}
2222

23-
impl JReaderInputStream {
24-
pub(crate) fn new<'local>(
25-
env: &mut JNIEnv<'local>,
26-
obj: JObject<'local>,
27-
) -> ExtractResult<Self> {
23+
impl<'local> JReaderInputStream<'local> {
24+
pub(crate) fn new(guard: AttachGuard<'local>, obj: JObject<'local>) -> ExtractResult<Self> {
2825
// Creates new jbyte array
2926
let capacity = DEFAULT_BUF_SIZE as jsize;
30-
let jbyte_array = env.new_byte_array(capacity)?;
27+
let jbyte_array = guard.new_byte_array(capacity)?;
3128

3229
Ok(Self {
33-
internal: env.new_global_ref(obj)?,
34-
buffer: env.new_global_ref(jbyte_array)?,
30+
internal: guard.new_global_ref(obj)?,
31+
buffer: guard.new_global_ref(jbyte_array)?,
3532
capacity,
33+
_guard: guard,
3634
})
3735
}
3836

@@ -96,7 +94,7 @@ impl JReaderInputStream {
9694
}
9795
}
9896

99-
impl Drop for JReaderInputStream {
97+
impl Drop for JReaderInputStream<'_> {
10098
fn drop(&mut self) {
10199
if let Ok(mut env) = vm().attach_current_thread() {
102100
// Call the Java Reader's `close` method

0 commit comments

Comments
 (0)