1. 코틀린 버전 1.4 에서 1.5 대로 업데이트 후 코드 작동 안함
얼마전 배포된 코틀린 버전 15.2 을 받고 나서 원래는 1.4.30 버전에서 잘 동작하던 코드가 동작하지 않는 현상을 발견했다. 처음에는 intelij프로젝트 설정을 잘 못한건가 해서 계속 다시만들고 source root directory 도 바꿔가면서 몇 시간동안 삽질을 하였다.
해당 코드는 코테를 보면서 알고리즘 문제를 풀며 작성한 코드로 해당 테스트에서 사용한 코틀린 컴파일러 버전대는 1.3.x 이었던 걸로 기억한다. 불과 1~2주 정도 전이라 나의 ide도 코틀린 1.4 버전대를 사용하고 있어서 문제가 되지 않았다.
문제의 코드
class Solution {
fun solution(bricks: IntArray, n: Int, k: Int): Int {
var answer: Int = 0
var cloneBricks = bricks.clone()
data class Brick(val height: Int, val index: Int)
val brickList = bricks.mapIndexed { index, i ->
Brick(i, index)
}.toMutableList()
brickList.sortBy {
-it.height
}
fun getCountDoung(bArr: IntArray): Int {
var prev = -1
var cnt = 0
for (i in bArr.indices) {
//n-1
if (bArr[i] >= n) {
if (prev == 0)
cnt++
prev = 1
} else {
prev = 0
}
}
if (prev == 0)
cnt++
return cnt
}
var currentCnt = 1
var totalAddBrick = 0
brickList.forEachIndexed { index, brick ->
val demoBricks = cloneBricks.clone().apply { set(brick.index, n) }
val cnt = getCountDoung(demoBricks)
if (currentCnt < cnt) {
currentCnt = cnt
totalAddBrick += n - brick.height
cloneBricks = demoBricks
if (currentCnt == k) {
return totalAddBrick
}
}
}
return answer
}
}
fun main() {
Solution().run {
solution(intArrayOf(0, 1, 2, 3, 4), 5,2).let {
println(it)
}
}
}
정말 혹시나 해서 웹 코틀린 실행 환경에서 해당 코드를 버전대를 바꿔가면서 실행해보았다.
1.4.30 버전대에서 main 함수를 실행해보면 결과로 2를 출력되는 것을 알 수 있다.
그러나 1.5 버전대를 사용하면 위와 같이 오류가 발생한다.
Exception in thread "main" java.lang.VerifyError: Bad access to protected data in invokevirtual
Exception Details:
Location:
Solution.solution([III)I @257: invokevirtual
Reason:
Type 'java/lang/Object' (current frame, stack[0]) is not assignable to 'Solution'
Current Frame:
bci: @257
flags: { }
locals: { 'Solution', '[I', integer, integer, integer, 'java/lang/Object', 'java/util/List', integer, integer, 'java/lang/Iterable', integer, integer, 'java/util/Iterator', 'java/lang/Object', integer, integer, 'Solution$solution$Brick', integer, integer }
stack: { 'java/lang/Object' }
Bytecode:
0x0000000: 2b12 0fb8 0015 0336 0401 3a05 2bb6 0019
0x0000010: 3a05 2b3a 0703 3608 1907 3a09 bb00 1b59
0x0000020: 1907 beb7 001e c000 203a 0a03 360b 0336
0x0000030: 0c19 093a 0d19 0dbe 360e 0336 0f15 0f15
0x0000040: 0ea2 0039 190d 150f 2e36 1019 0a15 0c84
0x0000050: 0c01 1510 3611 3612 3a19 0336 13bb 0022
0x0000060: 5915 1115 12b7 0025 3a1a 1919 191a b900
0x0000070: 2902 0057 840f 01a7 ffc6 190a c000 2b00
0x0000080: c000 20b8 0031 3a06 1906 3a07 0336 0819
0x0000090: 07b9 0035 0100 04a4 0015 1907 0336 09bb
0x00000a0: 0037 59b7 0038 c000 3ab8 003e 0003 3607
0x00000b0: 0436 0703 3608 1906 c000 403a 0903 360a
0x00000c0: 0336 0b19 09b9 0044 0100 3a0c 190c b900
0x00000d0: 4a01 0099 0083 190c b900 4d01 003a 0d15
0x00000e0: 0b84 0b01 360e 0336 0f15 0e9c 0006 b800
0x00000f0: 5015 0e19 0dc0 0022 3a10 3611 0336 1219
0x0000100: 05b6 0019 3a13 0336 1403 3615 1913 c000
0x0000110: 523a 1603 3617 1916 1910 b600 551c 4f19
0x0000120: 13c0 0052 3a18 1c19 18b8 0059 3613 1507
0x0000130: 1513 a200 2015 1336 0715 081c 1910 b600
0x0000140: 5c64 6036 0819 183a 0515 071d a000 0615
0x0000150: 08ac 00a7 ff79 0015 04ac
Stackmap Table:
full_frame(@61,{Object[#2],Object[#82],Integer,Integer,Integer,Object[#4],Top,Object[#82],Integer,Object[#82],Object[#32],Integer,Integer,Object[#82],Integer,Integer},{})
same_frame(@122)
full_frame(@172,{Object[#2],Object[#82],Integer,Integer,Integer,Object[#4],Object[#43],Object[#43],Integer,Top,Object[#32],Integer,Integer,Object[#82],Integer,Integer},{})
full_frame(@204,{Object[#2],Object[#82],Integer,Integer,Integer,Object[#4],Object[#43],Integer,Integer,Object[#64],Integer,Integer,Object[#70],Object[#4],Integer,Integer},{})
same_frame(@241)
full_frame(@338,{Object[#2],Object[#82],Integer,Integer,Integer,Object[#4],Object[#43],Integer,Integer,Object[#64],Integer,Integer,Object[#70],Object[#4],Integer,Integer,Object[#34],Integer,Integer,Integer,Integer,Integer,Object[#82],Integer,Object[#82]},{})
full_frame(@342,{Object[#2],Object[#82],Integer,Integer,Integer,Object[#4],Object[#43],Integer,Integer,Object[#64],Integer,Integer,Object[#70],Object[#4],Integer,Integer},{})
at FileKt.main (File.kt:59)
at FileKt.main (File.kt:-1)
youtrack.jetbrains 에 레포트
해당 문제를 스택오버플로우에 문의해보았는데 한 유저가 젯브레인의 youtrack에 신고해보라는 말을 해주어서 현재 youtrack에도 정상적으로 이슈를 등록해놓은 상태이다.
버전업이 되면서 생긴 버그로 추정되는데, 무엇이 원인인지 정말 궁금하다. 답변을 받거나 해결되면 이 글에 업데이트 해두도록 하겠다.
아무래도 가장 최신 버전을 사용하다보니 이러한 문제가 생긴 것 같은 데 이런 적은 처음이라 당황스럽기도하고 그만큼 신선하다. 아무래도 당분간은 1.4 버전대로 코틀린을 사용하고 있어야 할 것 같다.
[2021-07-15 추가]
답변을 받았습니다.
해당 버그는 아래 코드로 인해서 생기는 버그로 해결되어 향후 버전에서 적용될 것으로 보이네요..
val demoBricks = cloneBricks.clone().apply { set(brick.index, n) }
clone 에서 발생하는 오류 같아요. clone 한 것에서 apply 로 해당 데이터에 접근하려고 할 때 생기는 버그
2021.07.13 - [Android/App] - [Android] Youtube 앱 만들어보기 (ExoPlayer, MotionLayout)
2021.07.11 - [Android] - [Android] 화면 돌려도(회전시) 데이터 유지 시키기 : onSaveInstanceState
2021.07.13 - [Android/App] - [Android] Youtube 앱 만들어보기 (ExoPlayer, MotionLayout)
'Android > Kotlin' 카테고리의 다른 글
[코틀린] 더 좋은 Companion object 사용 방법 (0) | 2022.01.01 |
---|---|
[Kotlin] 코틀린 인터페이스의 Default implementation 과 JAVA (0) | 2021.09.12 |
[Android] dp를 px로 변환해주는 융통성 있는 코드 (dp to pixel) (0) | 2021.07.06 |
[Android] 코틀린(Kotlin) 코루틴(Coroutine) 한 번에 끝내기 (12) | 2021.06.22 |
[Android] Room 사용하여 로컬 데이터베이스에 데이터 저장하기 (0) | 2021.05.05 |