
들어가며
아래 기존 1주차 계획에서 프로젝트 구조 파악에서 코드를 보는 것은 skip 하기로 했습니다. 그 이유는 이슈 내용도 이해를 못한채로 글자만 읽는 것 같아 이슈 분석을 능동적으로 하고자 문서 수정, 오타 수정과 같은 라벨이 붙은 이슈를 찾으려 합니다. 한번 이슈를 해결한 후에 코어에 해당하는 코드를 읽을 예정입니다.
1주차: 로컬 빌드 환경 구축 및 프로젝트 구조 파악 (가장 중요)
오픈소스 기여의 50%는 빌드 환경 세팅입니다. 내 컴퓨터에서 테스트가 돌아가야 코드를 고칠 수 있습니다.
- 목표: Spring Boot 프로젝트를 로컬에서 빌드하고, 전체 테스트가 아닌 특정 모듈의 테스트를 통과시키기.
- 월~수:
- Github에서 Spring Boot Fork & Clone.
- CONTRIBUTING.adoc 파일을 정독하여 Java 버전과 빌드 툴(Gradle) 버전을 맞춥니다.
- 터미널에서 ./gradlew build를 실행해봅니다. (전체 빌드는 몇 시간 걸릴 수 있으니, spring-boot-project 폴더 내의 작은 모듈 하나만 골라 빌드해보세요.)
- 목~금:
- 프로젝트 구조 파악. 우리가 봐야 할 곳은 spring-boot-project 폴더입니다.
- 핵심 디렉토리: spring-boot-project/spring-boot-autoconfigure
- 이 안의 코드를 아무거나 열어서 @ConditionalOnClass, @Configuration이 어떻게 쓰였는지 눈으로만 읽으세요.
시도한 작업들
404 Not Found가 뜨는 링크를 찾기
주의할 점
XML 파일에 xmlns:접두사="URI"에 있는 URI(링크)가 404 Not Found 가 뜬다고 잘못된 링크가 적혀져 있는 것 아닙니다.
마치 도메인 이름(DNS)로 보여서 브라우저에 입력하면 기대하는 페이지가 나와야 될 것이라고 생각했는데요,
DNS가 유일한 값이다 보니 XML에서 이름이 동일한 속성들을 구분하기 위한 식별자(key)로 쓰인 것일 뿐 해당 도메인이 유효하지 않다(존재하지 않다고)고 틀린 것이 아니었습니다.
예를 들어, 아래 XML 파일에서 'h'와 'f'라는 접두어가 없다면 table 속성은 구별을 할 수 없습니다. 이름은 같지만, 각각 소속이 다른 table이라고 생각하시면 됩니다.
<root>
<h:table xmlns:h="http://www.w3.org/TR/html4/">
<h:tr>
<h:td>Apples</h:td>
<h:td>Bananas</h:td>
</h:tr>
</h:table>
<f:table xmlns:f="https://www.w3schools.com/furniture">
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
</root>
http://www.eclipse.org/oomph/setup/jdt/1.0

드디어 이슈를 찾은 것인가??? 가 아니었습니다.

*.java 파일 안에 있는 <a href="http:// ~ "> 의 링크를 봐야합니다. 그 이유는 <a href> 태그는 외부 링크로 이동할 때 쓰는 html 태그이기 때문입니다.
오타 찾기
an/a , the -> teh 등 javadoc에 있는 오타를 찾으려고 Cmd + Shift + F로 정규표현식과 일반 단어 검색을 해봤는데도 오타가 잘 보이지 않았습니다. 또 auto-configuration이 인텔리제이에서는 오타로 인식하고 있는지 빨간 밑줄이 있는데, github 들어가서 검색해보니 다른 문서에도 사용하는 단어라서 패스했습니다.

정적 분석
현재 JDK17을 사용하는 환경이라 instance of pattern matching을 사용하지 않는지 정적 분석을 해보았지만, 'spring-boot-project'에서는 발견된 건 없었습니다.
그래서 전체 프로젝트를 탐색한 결과 2개의 Warning이 뜬 것을 확인할 수 있었습니다.

JDK 16에서 instanceof에서 참조변수의 형변환을 생략해주는 패턴매칭(pattern matching)기능이 나왔습니다.
1) CommandRunner.java
아래 handleError메서드를 보시면, 참조변수 ex가 가리키는 예외 객체 타입이 CommandException 타입이면 commandException 참조변수로 {} 블럭 내에 사용할 수 있습니다. 하지만 이미 ex가 instanceof로 CommandException타입인 commandException이 있는데 throw부분에서 다시 불필요한 형변환을 한 것을 볼 수 있습니다. 이를 제거하고 commandException을 던지도록 합니다.
throw (CommandException) ex ; ==> throw commandException;
[수정 전]

[수정 후]

private int handleError(boolean debug, Exception ex) {
Set<CommandException.Option> options = NO_EXCEPTION_OPTIONS;
if (ex instanceof CommandException commandException) {
options = commandException.getOptions();
if (options.contains(CommandException.Option.RETHROW)) {
throw (CommandException) ex;
}
}
boolean couldNotShowMessage = false;
if (!options.contains(CommandException.Option.HIDE_MESSAGE)) {
couldNotShowMessage = !errorMessage(ex.getMessage());
}
if (options.contains(CommandException.Option.SHOW_USAGE)) {
showUsage();
}
if (debug || couldNotShowMessage || options.contains(CommandException.Option.STACK_TRACE)) {
printStackTrace(ex);
}
return 1;
}
2. AnnotationPropertySource.java
putProperties() 메서드도 위와 동일하게 value 참조변수를 이미 instanceof 패턴 패칭을 통해 형변환을 했으니 불필요한 형변환을 제거해주고 anntation 참조변수로 바꿔줍니다.
collectProperties(name, defaultSkip, (MergedAnnotation<?>) value), attribute, properties) ;
==> collectProperties(name, defaultSkip, annotation, attribute, properties) ;
[수정전]

수정후

빌드
java format 맞는지 체크
./gradlew format

checkStyle Rule에 위반하는지 체크
./gradlew checkStyleMain checkstyleTest

테스트, checkStyle Rule 등 작업을 한번에 검사하는 명령어
./gradlew check
커밋 메시지를 작성하고 clone한 레포로 push를 합니다.
그전에 제가 연결된 원격 저장소에서 fetch를 하여 충돌을 사전에 방지합니다.
아래와 첫 PR를 작성합니다.


첫 Pull Request를 Spring Boot 프로젝트에 올렸습니다. 제가 고친 게 정말로 도움이 되는건지 얼떨떨합니다.
maintainer의 댓글이 달리거나 PR이 잘 Merge 된다면 후기를 남기겠습니다.


너무 떨립니다... 좋은 결과가 있으면 좋겠습니다. ㅎㅎ
'OpenSource Contribution' 카테고리의 다른 글
| [OSS] Spring Boot 오픈소스 첫 기여 성공! (0) | 2025.12.19 |
|---|---|
| [OSS] 04. milestone에 PR등록되다 (간단한 후기) (0) | 2025.11.26 |
| [OSS] 02. 오픈소스 기여를 위한 로컬 빌드 환경 구성 (브랜치명, JDK 등) 및 빌드 테스트 (0) | 2025.11.25 |
| [OSS] 01. Spring Boot 오픈소스 기여 -CONTRIBUTING.adoc 정리 (0) | 2025.11.20 |