spring-projects / spring-projects/spring-ai
`TikaDocumentReader` repeats previous text when `get()` is called more than once
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 9.5k
- Forks
- 2.9k
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 6
Description
Bug description
TikaDocumentReader keeps its ContentHandler in a final field built once by the constructor, and get() parses into that same handler on every call. BodyContentHandler accumulates and nothing resets it, so a second get() returns the first extraction followed by the second. The Metadata field is shared the same way.
Whether this counts as a defect depends on whether the reader is meant to be used more than once, and that is what I would like to settle.
Arguments that repeated calls should work: DocumentReader extends Supplier<List<Document>>, and the sibling readers are safe to call again. TextReader and JsonReader re-read the resource on each call, and MarkdownDocumentReader builds a new DocumentVisitor per read. TikaDocumentReader is the one that keeps its accumulator in a field.
Argument the other way: the reference documentation example builds a new reader inside the method that reads, so following the docs you never reach this. Nothing states that the reader is single use either.
If single use is intended, saying so on the class would be enough. If repeated calls are meant to work, the handler and the metadata need to be per call. One thing to note for that path: the public constructor that takes a ContentHandler hands ownership to the caller, so an injected handler probably cannot be recreated.
Environment
Spring AI main at c988e72. The same code is on 1.1.x and 1.0.x, under document-readers/tika-reader.
Java 17.0.19. No vector store involved.
Steps to reproduce
Build a TikaDocumentReader over any supported document and call get() twice.
Expected behavior
The second call returns the same text as the first.
What happens instead: the second call returns the first text with the same text appended. Using word-sample.docx from the module test resources, the first call returns 9798 characters and the second returns 19596, and the second starts with the first.
Minimal Complete Reproducible example
Add to TikaDocumentReaderTests:
@Test
void secondReadRepeatsTheFirstExtraction() {
var reader = new TikaDocumentReader("classpath:/word-sample.docx");
String first = reader.get().get(0).getText();
String second = reader.get().get(0).getText();
assertThat(second).isEqualTo(first);
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with TikaDocumentReader in the document-readers/tika-reader module and run TikaDocumentReaderTests using word-sample.docx. Resolve whether DocumentReader instances must support repeated reads, including the constructor that accepts a ContentHandler, then make the chosen behavior explicit in tests and API documentation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100