Skip to content

5.11.0: export produces nothing though all sheets reach PAGE — RunTable.afterUnmarshal NPE, and the binary-restart fallback throws FileSystemAlreadyExistsException #971

Description

@jdburrage

Summary

A book in which every sheet transcribes successfully can still export nothing. During
Book.export, reloading a sheet's persisted structure throws
NullPointerException: Cannot read the array length because "this.sequences" is null from
RunTable.afterUnmarshal. The recovery path then fails too, because reopening the book's
zip filesystem throws FileSystemAlreadyExistsException. The null sheet finally surfaces
as an NPE in Voices.refineScore, and no MusicXML is produced.

Two separate defects are visible in the one trace, and I think the second is worth fixing
independently of the first: the fallback that exists to rescue this situation cannot work.

Environment

Audiveris 5.11.0, build 9e1e55cd2746037d059345881c53e6a6754bffbd
Windows 11 10.0, amd64
OpenJDK 64-Bit Server VM (build 25.0.3+9-LTS, mixed mode)
Tesseract OCR 5.5.2

Minimal reproducer

Haydn, Symphony No. 45 "Farewell", Timothy Lanfear 2020 engraving — freely downloadable
from IMSLP as file #633504:
https://imslp.org/wiki/Symphony_No.45_in_F-sharp_minor,_Hob.I:45_(Haydn,_Joseph)

Take pages 3–9 only (page 1–2 are front matter) into a new PDF and run:

Audiveris.exe -batch -export -save -output <dir> -- haydn-pages-3-9.pdf

All 7 sheets reach PAGE. Exit code 1, no MusicXML.

I bisected this:

pages sheets reaching PAGE export
3–7 5 of 5 succeeds
3–8 6 of 6 succeeds
3–9 7 of 7 fails
9 alone 1 of 1 succeeds

So page 9 triggers it only in combination with the preceding sheets, not on its own. Page 9
is the first in the book whose systems hold three different staff counts (book.xml gives
<part> counts per <system> of 4, 5 and 6 on that sheet); pages 3–7 are uniformly 6 and
page 8 has two distinct counts.

Actual

Sheets 1–6 reload, sheet 7 does not:

INFO  SheetStub.java:1000 | Loaded /sheet#1 ... Loaded /sheet#6
WARN  SheetStub.java:1002 | Error in loading sheet structure javax.xml.bind.UnmarshalException
javax.xml.bind.UnmarshalException: null
	at com.sun.xml.bind.v2.runtime.JaxBeanInfo.invokeUnmarshallCallback(JaxBeanInfo.java:571)
	at com.sun.xml.bind.v2.runtime.JaxBeanInfo.invokeAfterUnmarshalMethod(JaxBeanInfo.java:562)
Caused by: java.lang.NullPointerException: Cannot read the array length because "this.sequences" is null
	at org.audiveris.omr.run.RunTable.afterMarshal(RunTable.java:339)
	at org.audiveris.omr.run.RunTable.afterUnmarshal(RunTable.java:359)

Audiveris then tries to recover, and the recovery itself fails:

INFO  SheetStub.java:1003 | Trying to restart from binary
WARN  DataHolder.java:166 | Error reading data from BINARY.png
java.nio.file.FileSystemAlreadyExistsException: null
	at jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.newFileSystem(Unknown Source)
	at org.audiveris.omr.util.ZipFileSystem.open(ZipFileSystem.java:111)
	at org.audiveris.omr.sheet.Book.openBookFile(Book.java:1840)
	at org.audiveris.omr.sheet.Book.openSheetFolder(Book.java:1856)
	at org.audiveris.omr.sheet.DataHolder.getData(DataHolder.java:143)
	at org.audiveris.omr.sheet.SheetStub.grabBinaryTable(SheetStub.java:1101)
	at org.audiveris.omr.sheet.SheetStub.resetToBinary(SheetStub.java:1471)
	at org.audiveris.omr.sheet.SheetStub.getSheet(SheetStub.java:1004)
	at org.audiveris.omr.score.Score.getPage(Score.java:483)

Leaving a null sheet, which surfaces as:

WARN  CLI.java:956 | Exception occurred java.lang.NullPointerException:
  Cannot invoke "org.audiveris.omr.sheet.Sheet.getPages()" because "sheet" is null
	at org.audiveris.omr.score.Score.getPage(Score.java:485)
	at org.audiveris.omr.score.Score.getPages(Score.java:621)
	at org.audiveris.omr.sheet.rhythm.Voices.refineScore(Voices.java:343)
	at org.audiveris.omr.sheet.Book.reduceScores(Book.java:2101)
	at org.audiveris.omr.sheet.Book.transcribe(Book.java:2633)
	at org.audiveris.omr.sheet.Book.export(Book.java:593)

Expected

A book whose sheets all reached PAGE should export.

Notes

  1. RunTable.afterUnmarshal (line 359) calls afterMarshal (line 339), which dereferences
    sequences. On this sheet sequences is null after unmarshalling — an empty or
    run-less RunTable is my guess, but I have not read the source.
  2. The FileSystemAlreadyExistsException looks independently fixable: ZipFileSystem.open
    is asked for a filesystem on a book file that is already open at that moment, so
    resetToBinary can never succeed on a book being exported. Even if (1) is fixed,
    anything else that triggers resetToBinary mid-export will hit this.

I also see the getPages() NPE at a different sheet index depending on how many sheets
are in the book, over overlapping content, so I would not read too much into which sheet is
named in any single run.

Filed separately: a RHYTHMS-step NPE in Voices.refineSystem on the same score's later
pages.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions