일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Graph
- Selection Sorting
- 윤성우의 열혈 자료구조
- 혼자 공부하는 C언어
- insertion sort
- 알기쉬운 알고리즘
- 이스케이프 문자
- list 컬렉션
- Stack
- datastructure
- s
- Algorithm
- C 언어 코딩 도장
- 이것이 자바다
- 윤성우 열혈자료구조
- R
- C programming
- 메모리구조
- Serialization
- stream
- coding test
- buffer
- JSON
- Today
- Total
Engineering Note
[Error Handling] 파일 업로드 테스트 에러 해결 본문
파일 업로드를 테스트하며 에러가 발생해서 에러 발생 해결 과정을 정리하려고 한다.
에러메세지
java.lang.StringIndexOutOfBoundsException: Range [-1, 9) out of bounds for length 9
at java.base/jdk.internal.util.Preconditions$1.apply(Preconditions.java:55)
at java.base/jdk.internal.util.Preconditions$1.apply(Preconditions.java:52)
at java.base/jdk.internal.util.Preconditions$4.apply(Preconditions.java:213)
at java.base/jdk.internal.util.Preconditions$4.apply(Preconditions.java:210)
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:98)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckFromToIndex(Preconditions.java:112)
at java.base/jdk.internal.util.Preconditions.checkFromToIndex(Preconditions.java:349)
at java.base/java.lang.String.checkBoundsBeginEnd(String.java:4602)
at java.base/java.lang.String.substring(String.java:2715)
at java.base/java.lang.String.substring(String.java:2688)
at com.shop.service.FileService.uploadFile(FileService.java:15)
at com.shop.service.ItemImgService.saveItemImg(ItemImgService.java:30)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:380)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:728)
at com.shop.service.ItemImgService$$SpringCGLIB$$0.saveItemImg(<generated>)
at com.shop.service.ItemService.saveItem(ItemService.java:38)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:380)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:728)
at com.shop.service.ItemService$$SpringCGLIB$$0.saveItem(<generated>)
at com.shop.service.ItemServiceTest.saveItem(ItemServiceTest.java:63)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
가장 위에 에러메세지를 보면 'java.lang.StringIndexOutOfBoundsException: Range [-1, 9) out of bounds for length 9' 으로 문자열에서 범위가 벗어난 인덱스를 참조하려고 해서 에러가 발생했다는 걸 알 수 있다.
그리고 at으로 적힌 스택트레이스를 통해 호출한 메서드를 보면서 에러가 발생한 지점을 찾아갈 수 있다. 우선 내가 적은 코드에서 에러가 발생했을 수도 있고, 라이브러리 자체에서 발생했을 수도 있지만, 내 프로젝트의 코드 어디서 에러가 발생했는데 패키지 명을 통해 에러가 발생한 지점을 찾았다.
11 번째 줄과 12번째 줄을 보면 ' at com.shop.service.FileService.uploadFile(FileService.java:15)
at com.shop.service.ItemImgService.saveItemImg(ItemImgService.java:30)' 이라고 적혀있어서 FileService 클래스의 15번 째 줄을 보았다.
여기서 잠깐 정리하면 ItemImgService 의 30번 째 줄에서 FileService 15라인 의 uploadFile() 메서드를 호출했다는 의미이다.
FileService 15라인을 보면 originalFileName 문자열을 자르는 substring() 메서드가 사용되었고, 파라미터로 originalFileName.lastIndexOf(".")이 전달 되었다.
String extension = originalFileName.substring(originalFileName.lastIndexOf("."));
String 의 lastIndexOf() 메서드는 문자열의 뒤부터 인자로 전달된 문자를 찾아서 인덱스를 반환하는 메서드이다. 그래서 테스트 코드에서 처음 호출하는 코드를 찾았다. 이유는 테스트를 위해 전달해준 originalFileName에서 확장자를 구분하는 "."이 없어서 에러가 발생했다고 추론할 수 있기 때문이다.
최초 호출 지점은 가장 아래 쪽 at 부터 찾아 갈 수 있는데 아래서 4번째 줄을 보면, ItemServiceTest의 63번 라인에서 saveItem()에서 처음 호출된 걸 알 수 있다.
at com.shop.service.ItemServiceTest.saveItem(ItemServiceTest.java:63)
63라인을 보면 이렇게 작성했는데 createMultipartFiles()는 테스트를 위해 만든 메서드로, Mock 객체로 Mock file을 객체를 전달해주는 메서드이다.
List<MultipartFile> multipartFileList = createMultipartFiles();
Long itemId = itemService.saveItem(itemFormDto, multipartFileList);
코드를 확인하고 createMultipartFiles() 메서드 내부를 확인해 보았다.
createMultipartFiles() 메서드
List<MultipartFile> createMultipartFiles() throws Exception {
List<MultipartFile> multipartFileList = new ArrayList<>();
for(int i=0;i<5;i++){
String path = "/tmp/item";
String imageName = "image" + i + "jpg";
MultipartFile multipartFile = new MockMultipartFile(path, imageName, "img/jpg", new byte[]{1,2,3,4});
multipartFileList.add(multipartFile);
}
return multipartFileList;
}
메서든 내부를 보니 imageName에 "." 확장자 구분 문자열이 빠진걸 확인할 수 있었다.
문제 원인 발견 후 수정한 createMulipartFiles()
List<MultipartFile> createMultipartFiles() throws Exception {
List<MultipartFile> multipartFileList = new ArrayList<>();
for(int i=0;i<5;i++){
String path = "/Users/kim/myroot/tmp/item";
String imageName = "image" + i + ".jpg";
MultipartFile multipartFile = new MockMultipartFile(path, imageName, "img/jpg", new byte[]{1,2,3,4});
multipartFileList.add(multipartFile);
}
return multipartFileList;
}
실행 결과
'Error Handling' 카테고리의 다른 글
[Error Handling] Thymeleaf Parsing Error, NotReadablePropertyException 예외 (0) | 2025.09.16 |
---|---|
[Error Handling] Spring Security 로그아웃 버그 해결 (0) | 2025.09.14 |
[Error Handling] DB 연결 설정 테스트 문제해결, ActiveProfile로 테스트 환경 관리 (0) | 2025.09.13 |
[Error Handling] Spring Security 로그인 테스트에서 userParameter 설정 이슈 해결 (0) | 2025.09.12 |
[Error Handling] EC2에서 Spring Boot 빌드 오류 해결 (0) | 2025.09.05 |