IT/git

[git] Contribute to Apache (아파치 오픈소스 기여 경험기)

snapcoder 2024. 9. 13. 00:25
728x90
반응형
SMALL

[git] Contribute to Apache (아파치 오픈소스 기여 경험기)

 

 

 

 

 

 

Contribution을 하게된 배경

바야흐로 2024년 중순경

 

Confluence의 첨부파일을 API 호출해서 다운받고

Apache-Tika 오픈소스 라이브러리 기반으로

텍스트를 추출하는 로직을 구현했다.

 

2024.07.05 - [IT/Elasticsearch] - [Elasticsearch] 회사 내부 첨부파일의 내용을 통합 검색할 수 있다면? (feat. Fasoo DRM, Tika, Confluence)

 

[Elasticsearch] 회사 내부 첨부파일의 내용을 통합 검색할 수 있다면? (feat. Fasoo DRM, Tika, Confluence)

※ 사내 기밀은 담지 않도록 ※[Elasticsearch] 회사 내부 첨부파일의 내용을 통합 검색할 수 있다면? (feat. Fasoo DRM, Tika, Confluence)    구글링할 수 없는 내부 문서중에서 어떤거 하나 찾으

snapcode.tistory.com

 

 

 

 

 

그때 사용했던 tika.parseToString 메소드 말썽이었다.

파일들이 다 정상적인 내용의 텍스트를 포함하고 있음에도 불구하고,

어떤 파일은, 에러 던지고~

어떤 파일은, 대체문자 던지고~

어떤 파일은, 공백을 던지고~

결론은, File 타입의 파라미터 자체에 문제가 있었다..암호화 이슈..

 

2024.09.12 - [IT/Java] - [java] 유니코드 대체문자(��) 자바 검증 처리 방법 (마름모 안의 물음표)

 

https://snapcode.tistory.com/entry/%EC%9E%90%EB%B0%94

 

snapcode.tistory.com

 

 

 

 

 

이때 ㄱㅁ이형이 생각났다.

에이블리 핵심인재 빛ㄱㅁ

본인은 React가 말썽이었어서 직접 Contribute 했었다고.

(말풍선에선 '리액트하나'라고 표현했지만 어마무시한 수정분을 본 기억이..)

 

그래서 나도 Apache-Tika를 직접 뜯어보고 고쳐봐야되나 싶었다.

 

 

 

 

 

 

 

 

막상 뜯어보니

코드들이 생각보다 조촐? 했다고나 할까..

https://github.com/apache/tika/blob/61943b664b57efec29ae7f2d21449ea1893812ae/tika-core/src/main/java/org/apache/tika/Tika.java#L493

 

tika/tika-core/src/main/java/org/apache/tika/Tika.java at 61943b664b57efec29ae7f2d21449ea1893812ae · apache/tika

The Apache Tika toolkit detects and extracts metadata and text from over a thousand different file types (such as PPT, XLS, and PDF). - apache/tika

github.com

 

 

그저 각종 타입의 파라미터를 받아서 String을 return해주는..

 

 

아무쪼록 함수 자체에는 문제가 없다고 판단할 수 있었고,

앞서 말했듯이 파일을 복호화 처리 해주고

대체문자를 예외처리 해주어 문제를 해결했다.

 

=> parseToString 메소드가 오류를 뱉어낸데는

다른 원인때문임을 인지하고, 결국 문제를 해결해서 다행이었다.

 

 

 

 

 

 

 

 

어? 아직도 try-catch-finally 구문이 있네?

문제 해결 이후 뜯어보다보니

parseToString 메소드에서 스트림 자원 관리 이슈를 발견했다.

 

finally 블록에서 스트림을 수동으로 닫아주고 있었다.

Java 7부터 도입된 try-with-resources 구문을 사용한 코드로 고쳐보자 마음먹었다.

public String parseToString(InputStream stream, Metadata metadata, int maxLength)
        throws IOException, TikaException {
    WriteOutContentHandler handler = new WriteOutContentHandler(maxLength);
    try {
        ParseContext context = new ParseContext();
        context.set(Parser.class, parser);
        parser.parse(stream, new BodyContentHandler(handler), metadata, context);
    } catch (SAXException e) {
        if (!WriteLimitReachedException.isWriteLimitReached(e)) {
            // This should never happen with BodyContentHandler...
            throw new TikaException("Unexpected SAX processing failure", e);
        }
    } finally {
        stream.close();
    }
    return handler.toString();
}

 

나의 첫 Contribution이자 + 오픈소스 기여도 할겸~

merge 승인 안해주면 어떡하나 일단하자 일단하자 아자아자

 

 

 

 

 

 

 

 

 

 

 

 

 

 

내가 고친 to-be 코드 (try-with-resources 기반)

public String parseToString(InputStream stream, Metadata metadata, int maxLength)
        throws IOException, TikaException {
    WriteOutContentHandler handler = new WriteOutContentHandler(maxLength);
    ParseContext context = new ParseContext();
    context.set(Parser.class, parser);
    try (InputStream autoCloseStream = stream) {
        parser.parse(autoCloseStream, new BodyContentHandler(handler), metadata, context);
    } catch (SAXException e) {
        if (!WriteLimitReachedException.isWriteLimitReached(e)) {
            // This should never happen with BodyContentHandler...
            throw new TikaException("Unexpected SAX processing failure", e);
        }
    }
    return handler.toString();
}

 

as-is에 비해 to-be는 코드가 더 간결해지고,

스트림이 제대로 닫히지 않는 문제를 예방할 수 있는 장점이 있다.

 

자세한 내용은 다음 링크 참고

[Java] try-with-resources란? try-with-resources 사용법 예시와 try-with-resources를 사용해야 하는 이유

  • 코드를 간결하게 만들 수 있음
  • 번거로운 자원 반납 작업을 하지 않아도 됨
  • 실수로 자원을 반납하지 못하는 경우를 방지할 수 있음
  • 에러로 자원을 반납하지 못하는 경우를 방지할 수 있음
  • 모든 에러에 대한 스택 트레이스를 남길 수 있음

자 이제 기여하러 가보자.

 

 

 

 

 

 

 

 

 

Contribute to Apache-Tika

우선 Fork 해주자.

레파지토리의 우측 상단에 "Create a new fork" 클릭.

 

 

 

 

 

포크 생성

Repository name 적고 Fork 생성.

(Repository name은 크게 신경 쓰지 말고 Owner만 제대로 되어있는지 확인하시면 됩니다.)

 

 

 

 

 

 

PR 올리기

그 다음 순서로는, 오픈소스 수정 및 Push.

(라이브러리 수정을 끝내고 Push를 해주세요. 어차피 Fork 된 Repo에 들어가기 때문에 겁먹지 않으셔도 됩니다.)

커밋은 언제나 즐거워

 

 

 

 

 

 

 

 

 

드디어 기다리던 PR !

한번 올려봅시다.

 

 

 

 

 

 

 

 

 

제목과 내용을 입력하고 'Create pull request'를 눌러주세요. 그러면 완료입니다. 이 과정이 실수해도 문제가 되지 않습니다. 잘못되었으면 외국인들이 친절하게 알려주거나 그냥 거절당하기 때문에 남에게 피해를 주지는 않습니다.

 

다만 Tika같은 경우에는 특정 양식을 사용해달라고 적혀있습니다.

"[TIKA-1234] 블라블라 기능 업데이트" 처럼요.

 

 

 

 

 

 

 

변경분 확인

Pull Request가 만들어지면 소스 변경분을 확인해보세요.

제가 반영한 부분은 다음과 같습니다.

 

finally구문을 삭제하고 try()구문을 사용했습니다.

 

 

 

 

 

 

 

 

 

이제 원래 라이브러리 깃 허브로 이동하여, 등록된 것을 확인하면 됩니다. 

 

 

 

 

 

 

 

 

 

 

드디어 승인

시간이 지나면 아래 사진처럼, 누군가가 승인을 해줄겁니다..!

해당 커밋은 merge해주시는분 따로, push해주시는분 따로 계시더라구요

 

 

 

 

 

 

 

뱃지는 덤

이 과정에서 뱃지를 두개나 얻었네요..!

(2개의 병합된 풀 리퀘스트를 만드는 경우)

 

(PR을 열었다가 5분안에 닫는 경우 획득)

 

 

 

 

 

 

 

 

 

 

마치며

처음이 어렵지, 막상 해보니 뿌듯했습니다.

앞으로도 오픈소스 활용해서 코드 만질때
직접 고치고싶거나 기능확장하고 싶은 부분들이 있으면, 주저하지않고 Contribute 해봐야겠습니다~

728x90
반응형
LIST