fix: createWorkbook이 호출자의 Workbook을 닫고 반환하는 문제와 출력 스트림 누수 수정 - #306
Open
z3rotig4r wants to merge 1 commit into
Open
fix: createWorkbook이 호출자의 Workbook을 닫고 반환하는 문제와 출력 스트림 누수 수정#306z3rotig4r wants to merge 1 commit into
z3rotig4r wants to merge 1 commit into
Conversation
EgovExcelServiceImpl.createWorkbook(Workbook, String)이 파라미터로 받은 Workbook을 finally에서 닫은 뒤 그대로 반환한다. XSSFWorkbook.close()는 OPCPackage를 닫으므로 반환된 워크북으로 다시 write()하면 "Cannot write data, document seems to have been closed already"로 실패한다. 파라미터로 전달된 자원은 호출자 소유이므로 wb.close() 호출을 제거하고, 반환 계약(호출자가 이어서 사용·재저장 가능, 닫는 책임은 호출자)을 javadoc에 명시한다. 로딩 메서드 5개는 앞서 같은 패턴을 제거했으므로 정책이 일치한다. 또한 finally에서 wb.close()가 IOException을 던지면 다음 줄의 fileOut.close()가 실행되지 않아 FileOutputStream이 누수된다. FileOutputStream을 try-with-resources로 감싸 항상 닫히도록 한다. 회귀 방지 테스트 3건 추가(EgovExcelCreateWorkbookContractTest).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
변경 이유
EgovExcelServiceImpl.createWorkbook(Workbook, String)은 전달받은 Workbook을 파일로 저장한 뒤 그 Workbook을 반환합니다. 그런데 반환 직전finally에서wb.close()를 호출합니다.닫힌 Workbook을 반환하므로 호출자가 반환값으로 할 수 있는 일이 없습니다. XSSF는
write()호출 시Cannot write data, document seems to have been closed already로 실패하고, 시트 추가·셀 수정 후 재저장하는 사용 방식도 성립하지 않습니다. 반환 타입이void가 아니라Workbook인 이상 반환값을 쓸 수 있어야 하는데 현재는 어떤 경우에도 쓸 수 없습니다.닫는 주체가 잘못된 문제이기도 합니다. Workbook을 만든 쪽은 호출자입니다. 이 메서드는 저장만 위임받았는데 호출자가 만든 자원의 수명을 임의로 끝냅니다. 같은 클래스의
loadWorkbook계열이 Workbook을 반환하고 닫지 않는 것과도 어긋납니다.두 번째로 자원 누수가 있습니다.
finally에서wb.close()가 먼저 실행되므로 여기서 예외가 나면 다음 줄의fileOut.close()가 실행되지 않고FileOutputStream이 열린 채 남습니다. 파일 핸들이 반납되지 않아 Windows에서는 해당 파일이 잠기고, 반복 호출 시 핸들이 누적됩니다.변경 내용
FileOutputStream을 try-with-resources로 감쌌습니다. Workbook 쪽에서 무슨 일이 생기든 스트림은 닫힙니다.finally의wb.close()를 제거했습니다. Workbook의 수명은 이를 생성한 호출자가 관리합니다.close()가 실패하는 Workbook 대역으로FileOutputStream이 닫혔는지 확인합니다.테스트 방법
org.egovframe.rte.fdl.excel모듈 테스트가 모두 통과합니다(9개 클래스 34건, 실패·오류 0건).회귀 여부는 본문 수정만 되돌리고 테스트만 적용해 확인했습니다. 이 상태에서 신규 3건 중 2건이 실패합니다.
testCreateWorkbookReturnsWritableXssf—Cannot write data, document seems to have been closed alreadytestOutputStreamClosedWhenWorkbookCloseFails—wb.close()예외가BaseRuntimeException으로 전파되고 스트림은 열린 채 남음testCreateWorkbookReturnsWritableHssf는 수정 전에도 통과합니다. HSSF는close()이후에도 메모리상의 워크북 구조가 남아 쓰기가 성립하기 때문이며, 포맷에 따라 증상이 다르게 나타난다는 점을 남겨 두려고 함께 두었습니다.영향 범위
EgovExcelServiceImpl.java(본문 4줄)와EgovExcelService.java(javadoc 1줄), 신규 테스트 1개입니다.