Pyjnius: PyJnius ๋Œ€ JPype

์— ๋งŒ๋“  2020๋…„ 07์›” 16์ผ  ยท  27์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: kivy/pyjnius

์ €๋Š” JPype์˜ ์ฃผ ์ €์ž์ž…๋‹ˆ๋‹ค. JPype ๋ฌธ์„œ ์—…๋ฐ์ดํŠธ์˜ ์ผํ™˜์œผ๋กœ JPype์— ๋Œ€ํ•œ ๋Œ€์ฒด ์ฝ”๋“œ ๋ชฉ๋ก์— PyJnius๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ถˆํ–‰ํžˆ๋„ PyJnius๋ฅผ ๊ฐ€์ง€๊ณ  ๋†€๊ณ  2์‹œ๊ฐ„ ํ›„์— JPype๋ณด๋‹ค PyJnius์˜ ์žฅ์ ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ๊ฒƒ์„ ์ƒ๊ฐํ•ด๋‚ผ ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ํ”„๋ก์‹œ, ์ปค์Šคํ„ฐ๋งˆ์ด์ €, ๋‹ค์ฐจ์› ๋ฐฐ์—ด ์ฒ˜๋ฆฌ, javadoc ํ†ตํ•ฉ, GC ์ฒ˜๋ฆฌ, ๋ฒ„ํผ, ๊ณผํ•™์  ์ฝ”๋“œ ํ†ตํ•ฉ(numpy, matplotlib ๋“ฑ), ํ˜ธ์ถœ์ž์— ๋ฏผ๊ฐํ•œ ๋ฉ”์„œ๋“œ, ๋ฌธ์„œ ๋ฐ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์‹คํ–‰ ์†๋„์—์„œ ์‚ดํŽด๋ณธ ๋ชจ๋“  ์ธก๋ฉด์€ ํ˜„์žฌ ๋‹ค๋ฃน๋‹ˆ๋‹ค. JPype์—์„œ๋Š” PyJnius๋ณด๋‹ค ๋” ์™„๋ฒฝํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ JPype์˜ ์ €์ž๊ฐ€ ๋˜๋ฉด์„œ PyJnius ํŒ€์˜ ์ธก๋ฉด๋ณด๋‹ค๋Š” ์ œ๊ฐ€ ๊ฐ€์น˜ ์žˆ๊ฒŒ ์—ฌ๊ธฐ๋Š” ์ธก๋ฉด์„ ๋ณด๊ณ  ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ์˜ ์žฅ์ ์„ ๋” ์ž˜ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ด ํ”„๋กœ์ ํŠธ์˜ ๊ฐ€์น˜ ์ œ์•ˆ์€ ๋ฌด์—‡์ด๋ฉฐ ๋Œ€์ƒ ๊ณ ๊ฐ์€ ๋ฌด์—‡์ด๋ฉฐ ๋Œ€์•ˆ์ด ์•„์ง ๋‹ค๋ฃจ์ง€ ์•Š๋Š” ๋Œ€์ƒ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์ €๋Š” ์•ฝ 2๋…„ ์ „์— ๋ชจ๋“  Java ๋ธŒ๋ฆฌ์ง€ ์ฝ”๋“œ์— ์ ‘๊ทผํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ถˆํ–‰ํžˆ๋„, PyJnius ์ฝ”๋“œ๋Š” ๋‚ด ๊ฒ€์ƒ‰์— ๊ฒฐ์ฝ” ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถ„๋ช…ํžˆ ๋†“์ณค์Šต๋‹ˆ๋‹ค. ์ง€๋‚œ๋ฒˆ์— ๋ฉ‹์ง„ ๊ธฐ์ˆ  ๋ณด๋„ ์ž๋ฃŒ๋ฅผ ์ œ๊ณตํ•œ ํŽ˜์ด์ง€๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋‹ค๊ฐ€ ๋‘ ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•ด ๋…ผ์˜ํ•˜๋Š” ๋ธ”๋กœ๊ทธ๋ฅผ ์šฐ์—ฐํžˆ ๋ฐœ๊ฒฌํ•œ ๊ฒƒ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ์ด๋ฒˆ ๋ผ์šด๋“œ์—์„œ๋„ ๋†“์ณค์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. 2๋…„ ๋™์•ˆ ๊ฐ™์€ ๋ถ„์•ผ์—์„œ ์ง„ํ–‰ ์ค‘์ธ ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ๋†“์ณค๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ ๋ถ„๋ช…ํžˆ ๋‚ด ์ž˜๋ชป์ด์—ˆ์Šต๋‹ˆ๋‹ค.

JPype๊ฐ€ ๋‹ค๋ฅธ ์ฃผ์š” ๋ธŒ๋ฆฌ์ง€ ์ฝ”๋“œ์ธ Py4J์™€ ํ˜ผ๋™๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋“ค๋ฆฝ๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ์ˆ˜๋ฐ˜๋˜๋Š” ์ด์ ๊ณผ ๋‹จ์ ์„ ๋ชจ๋‘ ๊ฐ€์ง„ ์†Œ์ผ“์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“  ๊ฒƒ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ”„๋กœ์ ํŠธ๊ฐ€ ๋‚ด ์š”๊ตฌ ์‚ฌํ•ญ์„ ์ถฉ์กฑํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ๋ฅผ ์ง€์›ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๊ฒƒ์— ๋Œ€ํ•œ ์—ฐ๊ตฌ๋ฅผ ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋น„๋ก ๋‚ด๊ฐ€ ๊ฐ€๋Šฅํ•œ ๊ฒƒ๋ณด๋‹ค ์•ฝ๊ฐ„์˜ ๊ธฐ์ˆ  ์‚ฌ์–‘์ด ์žˆ๋‹ค๋ฉด. ๋„ค์ดํ‹ฐ๋ธŒ JNI์™€ Python์˜ C API์— ๋Œ€ํ•œ ์ผ๋ฐ˜ ์ด์ „ ํ˜ธ์ถœ ์™ธ์—๋Š” ์šฐ๋ฆฌ๊ฐ€ ํ•˜๊ณ  ์žˆ๋Š” ์ž‘์—…์ด ์—†์Šต๋‹ˆ๋‹ค.

์ ‘๊ทผ ๋ฐฉ์‹์— ๊ด€ํ•œ ํ•œ JPype๋Š” "startJVM()" ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ JVM์„ Python๊ณผ ๊ฒฐํ•ฉํ•˜๊ธฐ ์œ„ํ•ด ๋…์ ์ ์œผ๋กœ JNI๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ฒ„์ „(2.0)๋„ Java ๋‚ด์—์„œ Python์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ˜๋Œ€์˜ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ ˆ์ด์–ด ์ ‘๊ทผ ๋ฐฉ์‹์„ ํ†ตํ•ด ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ํ”„๋ก ํŠธ ์—”๋“œ ์—ญํ• ์„ ํ•˜๋Š” ๋ชจ๋“  ๊ณ ๊ธ‰ ํด๋ž˜์Šค๋ฅผ ๋ณด์œ ํ•˜๋Š” Python ๊ณ„์ธต, ์ง„์ž…์ ์„ ๋ณด์œ ํ•˜๋Š” ๊ธฐ๋ณธ ํด๋ž˜์Šค๊ฐ€ ์žˆ๋Š” CPython ๊ฐœ์ธ ๋ชจ๋“ˆ, ๋ชจ๋“  ์œ ํ˜• ๋ณ€ํ™˜ ๋ฐ ์ผ์น˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ๊ธฐ๋ณธ ๋ชจ๋“ˆ๋กœ ์ž‘๋™ํ•˜๋Š” C++ ์ง€์› ๊ณ„์ธต์ด ์žˆ์Šต๋‹ˆ๋‹ค. Java ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฐ ๋ชจ๋“  ์œ ํ‹ธ๋ฆฌํ‹ฐ ์ž‘์—…(๊ฐ์ฒด ์ˆ˜๋ช… ์œ ์ง€, ์Šฌ๋ผ์ด์Šค ๋ฐ ์˜ˆ์™ธ์— ๋Œ€ํ•œ ์ง€์› ํด๋ž˜์Šค ์ƒ์„ฑ, javadoc ์ถ”์ถœ๊ธฐ/๋ Œ๋”๋ง)์„ ์ˆ˜ํ–‰ํ•˜๋Š” Java ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ.

8๋…„ ์ „ JPype๋Š” ์•ฝ๊ฐ„ ์—‰๋ง์ด์—ˆ์Šต๋‹ˆ๋‹ค. Ruby์™€ Python์„ ๋ชจ๋‘ ์ง€์›ํ•˜๋ ค๊ณ  ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— C++ ๋ ˆ์ด์–ด๋Š” ์ž‘์—…ํ•  ๋ž˜ํผ๊ฐ€ ์–ฝํ˜€ ์žˆ๊ณ  ํ”„๋ŸฐํŠธ ์—”๋“œ๋Š” ๋ชจ๋‘ Python์œผ๋กœ ๋˜์–ด ์žˆ์–ด์„œ ๋งค์šฐ ๋Š๋ ธ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ numpy ์ง€์›์ด ์ปดํŒŒ์ผ๋˜์–ด ๋‹ค๋ฅธ ๊ฐ์ฒด๊ฐ€ ๋ฐ˜ํ™˜๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ฐ˜ํ™˜ ์œ ํ˜•์—์„œ ๋ถ„๊ธฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋„ค์ดํ‹ฐ๋ธŒ Python๊ณผ Java ๊ฐ์ฒด๊ฐ€ ๋‹ค๋ฅธ ํ”„๋ก์‹œ ์—ญํ• ์„ ํ•˜๋ ค๋ฉด JException๊ณผ ๊ฐ™์€ ๋งŽ์€ ์–ด๋Œ‘ํ„ฐ ํด๋ž˜์Šค๊ฐ€ ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ”„๋กœ์ ํŠธ์— ํ•ฉ๋ฅ˜ํ•œ ์ง€ 3๋…„ ๋งŒ์— ๋ชจ๋“  ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. JPype์˜ ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ๋ชฉํ‘œ(์ €๋ฅผ ์œ„ํ•ด)๋Š” ๋ฌผ๋ฆฌํ•™์ž๋“ค์ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ์ต์ˆ™ํ•˜์—ฌ Java๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ  ๊ณผํ•™์ ์ธ Python ์ฝ”๋“œ์™€ ๋†’์€ ์ˆ˜์ค€์˜ ํ†ตํ•ฉ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์„ ๋งŒํผ ์ถฉ๋ถ„ํžˆ ๊ฐ„๋‹จํ•œ ๊ตฌ๋ฌธ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ž๋ฐ”๊ฐ€ ์ง€์›ํ•˜๋Š” ๊ฐ์ฒด๊ฐ€ "๋ชจ๋“  ์žฅ์‹" CPython ๊ฐ์ฒด ๋ž˜ํผ๋ฅผ ๊ฐ–๋„๋ก ํ•จ์œผ๋กœ์จ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. Java ์›์‹œ ๋ฐฐ์—ด์„ ๋ณ€ํ™˜ํ•˜๋Š” ๋Œ€์‹  Java ์›์‹œ ๋ฐฐ์—ด์„ numpy์™€ ๋™์ผํ•œ ์ง„์ž…์ ์„ ๋ชจ๋‘ ๊ตฌํ˜„ํ•˜๋Š” ์ƒˆ๋กœ์šด ์›์‹œ Python ์œ ํ˜•์œผ๋กœ ๋งŒ๋“ค๊ณ  ์ด ๋ชจ๋“  ๊ฒƒ์ด ๋ฉ”๋ชจ๋ฆฌ ๋ฒ„ํผ ์ „์†ก์œผ๋กœ ์ง€์›๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ list(jarray) ๋˜๋Š” np.array(jarray) ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋น ๋ฅธ ๋ณ€ํ™˜์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

Android์— ์ ์šฉํ•˜๋ ค๋ฉด ์‹œ์ž‘ ์‹œํ€€์Šค๋ฅผ ๋‹ค์‹œ ์ž‘์—…ํ•ด์•ผ ํ•˜๋ฉฐ ๋‚ด๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋กœ๋“œํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” ์ฝํฌ ์ฝ”๋“œ๋ฅผ ๋ณด๋‹ค ์ „ํ†ต์ ์ธ JNI ๋ชจ๋ธ๋กœ ๊ต์ฒดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ฒ„์ „์—์„œ ์ด๋ฏธ ์ฝํฌ ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ–ˆ์œผ๋ฏ€๋กœ ์ดํ›„ ๋ฒ„์ „์€ ์ด๋ฏธ ์ถฉ์กฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ „์ž๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๋ณผ ์ˆ˜์žˆ๋Š” ์ ‘๊ทผ ๋ฐฉ์‹์˜ ์ฃผ์š” ์ฐจ์ด์ ์€ PyJnius๊ฐ€ ๋ฐฐ์—ด์„ ์˜ค๊ฐ€๋Š” ๋ฐฐ์—ด์„ ๋ณ€ํ™˜ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ํฐ ๋ฐฐ์—ด(์ข…์ข… ๋ณ€ํ™˜๋˜์ง€ ์•Š์Œ)์„ ๋’ค๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด ์„ ํ˜ธ๋˜๋Š” JPype ์Šคํƒ€์ผ์ธ ๊ณผํ•™์  ์ฝ”๋”ฉ์— ๋งค์šฐ ๊ธˆ์ง€๋œ ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ๋ณ€ํ™˜์„ ์š”๊ตฌํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•˜๋ฉด ๊ฐ’์— ์˜ํ•œ ์ „๋‹ฌ ๋ฐ ์ฐธ์กฐ์— ์˜ํ•œ ์ „๋‹ฌ๊ณผ ๊ฐ™์€ ์˜ต์…˜์ด ๊ฐ•์ œ ์ ์šฉ๋˜์ง€๋งŒ, ์ด๋Š” ๋‹ค์ค‘ ์ธ์ˆ˜ ํ˜ธ์ถœ์ด ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ชจ๋“  ์ธ์ˆ˜์— ๋Œ€ํ•ด ํ•˜๋‚˜์˜ ์ •์ฑ…์„ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ž ์žฌ์ ์œผ๋กœ ๋” ํฐ ๋ฌธ์ œ๋กœ ์ด์–ด์ง‘๋‹ˆ๋‹ค. ๋˜ํ•œ ๋‹ค์ฐจ์› ๋ฐฐ์—ด์„ ๋‹ค๋ฃจ๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ( obj.method(1, jnius.byref(list1), list2) ์™€ ๊ฐ™์ด ์‚ฌ์šฉ๋˜๋Š” ์–ด๋Œ‘ํ„ฐ ํด๋ž˜์Šค๊ฐ€ ๋‹ฌ์„ฑ๋  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋” ๋‚˜์€ ์ œ์–ด๋ฅผ ์ œ๊ณตํ–ˆ์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.) ์ด ์™ธ์—๋„ GC ์—ฐ๊ฒฐ, ํ˜ธ์ถœ์ž์— ๋ฏผ๊ฐํ•œ ๋ฉ”์„œ๋“œ ๋“ฑ JPype๊ฐ€ ํ•ด๊ฒฐํ•œ ๋ฌธ์ œ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๊ฒƒ์ด ์—†๋‹ค๋ฉด JPype ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ข‹์€ ์•„์ด๋””์–ด๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

๋ชจ๋“  27 ๋Œ“๊ธ€

๋ฌธ์˜ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๋ช‡ ๋…„ ๋™์•ˆ jpype๋ฅผ ๋ณด์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž˜๋ชป ๊ธฐ์–ตํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์•„๋‹Œ ์„œ๋ฒ„(IPC)๋ฅผ ํ†ตํ•ด JVM๊ณผ ์ด์•ผ๊ธฐํ•˜๋Š” ๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ์ง€๋งŒ readme๋Š” ๋ฐ˜๋Œ€๋ฅผ ์•”์‹œํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚˜๋Š” ์ฝ”๋“œ๋ฅผ ํ•œ ๋ˆˆ์— ๋ด๋„ ๊ทธ๊ฒƒ์„ ๋ฐ˜์ฆํ•˜๋Š” ํžŒํŠธ๋ฅผ ๋ณผ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์•„๋งˆ๋„ ์™„์ „ํžˆ ํ‹€๋ ธ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด ์ ‘๊ทผ ๋ฐฉ์‹์€ ์˜ˆ๋ฅผ ๋“ค์–ด ์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š๊ฒŒ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ์‚ฌ๋žŒ๋“ค์€ ๋ฐ์Šคํฌํƒ‘ ํ”Œ๋žซํผ์—์„œ ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค). ๋ฐ˜๋ฉด์—, jni.h๊ฐ€ AOSP์—์„œ ๊ฐ€์ ธ์˜จ ๊ฒƒ ๊ฐ™๊ธฐ ๋•Œ๋ฌธ์— native ๋””๋ ‰ํ† ๋ฆฌ์— ๊ด€ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ๋ฉด JPype ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ Android ์ง€์›์— ๋Œ€ํ•œ ํžŒํŠธ๋ฅผ ๋งŽ์ด ๋ณผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์†”์งํžˆ ๋งํ•ด์„œ, ์šฐ๋ฆฌ๋Š” ํ”„๋กœ์ ํŠธ๊ฐ€ ์‹œ์ž‘๋˜์—ˆ์„ ๋•Œ JPype๋ฅผ ์ „ํ˜€ ์ธ์‹ํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. kivy ์ง€์›์„ ์œ„ํ•ด ํŠน์ • ์•ˆ๋“œ๋กœ์ด๋“œ ํด๋ž˜์Šค์— ์ธํ„ฐํŽ˜์ด์Šคํ•˜๊ธฐ ์œ„ํ•ด ์ˆ˜๋™์œผ๋กœ jni ์ฝ”๋“œ๋ฅผ ์ฝ”๋”ฉํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์—์„œ ํ•œ ๋‹จ๊ณ„ ๋” ์˜ฌ๋ผ๊ฐ„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” @tito ๊ฐ€ ๋‚˜์ค‘์— ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์•Œ๊ฒŒ ๋˜์—ˆ์„ ๋•Œ ๋น„๊ตํ•˜๊ธฐ ์œ„ํ•ด ์•ฝ๊ฐ„์˜ ํŒŒ๊ณ ๋ฅผ ํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ๊ทธ๊ฐ€ ์ „ํ™˜์„ ์‹œ๋„ํ•˜์ง€ ๋ง์•„์•ผ ํ•  ๊ตฌ์ฒด์ ์ธ ์ด์œ ๋ฅผ ๋ณด์•˜๋Š”์ง€ ๊ธฐ์–ต์ด ๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”. JPype ์ด๋ฆ„์€ ๊ธฐ์–ต๋‚˜๋Š”๋ฐ, ๋ญ˜ ์“ธ ์ˆ˜ ์žˆ๋Š”์ง€ ๊ฒ€์ƒ‰ํ•  ๋‹น์‹œ ์†”์งํžˆ 8๋…„ ์ „๋งŒ ํ•ด๋„ ์™œ ์ „ํ˜€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๋Š”์ง€ ๊ธฐ์–ต์ด ์•ˆ ๋‚˜๋„ค์š” :) ์ฒ˜์Œ์˜ ์œ ์ผํ•œ ๋ชฉํ‘œ๋Š” Android์™€ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. API๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ ์ค‘๊ฐ„ RPC ์„œ๋ฒ„๋ฅผ P4A ํ”„๋กœ์ ํŠธ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์€ ๊ทธ ๋‹น์‹œ ํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” ์•ฝ 2๋…„ ์ „์— ๋ชจ๋“  Java ๋ธŒ๋ฆฌ์ง€ ์ฝ”๋“œ์— ์ ‘๊ทผํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ถˆํ–‰ํžˆ๋„, PyJnius ์ฝ”๋“œ๋Š” ๋‚ด ๊ฒ€์ƒ‰์— ๊ฒฐ์ฝ” ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถ„๋ช…ํžˆ ๋†“์ณค์Šต๋‹ˆ๋‹ค. ์ง€๋‚œ๋ฒˆ์— ๋ฉ‹์ง„ ๊ธฐ์ˆ  ๋ณด๋„ ์ž๋ฃŒ๋ฅผ ์ œ๊ณตํ•œ ํŽ˜์ด์ง€๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋‹ค๊ฐ€ ๋‘ ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•ด ๋…ผ์˜ํ•˜๋Š” ๋ธ”๋กœ๊ทธ๋ฅผ ์šฐ์—ฐํžˆ ๋ฐœ๊ฒฌํ•œ ๊ฒƒ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ์ด๋ฒˆ ๋ผ์šด๋“œ์—์„œ๋„ ๋†“์ณค์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. 2๋…„ ๋™์•ˆ ๊ฐ™์€ ๋ถ„์•ผ์—์„œ ์ง„ํ–‰ ์ค‘์ธ ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ๋†“์ณค๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ ๋ถ„๋ช…ํžˆ ๋‚ด ์ž˜๋ชป์ด์—ˆ์Šต๋‹ˆ๋‹ค.

JPype๊ฐ€ ๋‹ค๋ฅธ ์ฃผ์š” ๋ธŒ๋ฆฌ์ง€ ์ฝ”๋“œ์ธ Py4J์™€ ํ˜ผ๋™๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋“ค๋ฆฝ๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ์ˆ˜๋ฐ˜๋˜๋Š” ์ด์ ๊ณผ ๋‹จ์ ์„ ๋ชจ๋‘ ๊ฐ€์ง„ ์†Œ์ผ“์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“  ๊ฒƒ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ”„๋กœ์ ํŠธ๊ฐ€ ๋‚ด ์š”๊ตฌ ์‚ฌํ•ญ์„ ์ถฉ์กฑํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ๋ฅผ ์ง€์›ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๊ฒƒ์— ๋Œ€ํ•œ ์—ฐ๊ตฌ๋ฅผ ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋น„๋ก ๋‚ด๊ฐ€ ๊ฐ€๋Šฅํ•œ ๊ฒƒ๋ณด๋‹ค ์•ฝ๊ฐ„์˜ ๊ธฐ์ˆ  ์‚ฌ์–‘์ด ์žˆ๋‹ค๋ฉด. ๋„ค์ดํ‹ฐ๋ธŒ JNI์™€ Python์˜ C API์— ๋Œ€ํ•œ ์ผ๋ฐ˜ ์ด์ „ ํ˜ธ์ถœ ์™ธ์—๋Š” ์šฐ๋ฆฌ๊ฐ€ ํ•˜๊ณ  ์žˆ๋Š” ์ž‘์—…์ด ์—†์Šต๋‹ˆ๋‹ค.

์ ‘๊ทผ ๋ฐฉ์‹์— ๊ด€ํ•œ ํ•œ JPype๋Š” "startJVM()" ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ JVM์„ Python๊ณผ ๊ฒฐํ•ฉํ•˜๊ธฐ ์œ„ํ•ด ๋…์ ์ ์œผ๋กœ JNI๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ฒ„์ „(2.0)๋„ Java ๋‚ด์—์„œ Python์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ˜๋Œ€์˜ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ ˆ์ด์–ด ์ ‘๊ทผ ๋ฐฉ์‹์„ ํ†ตํ•ด ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ํ”„๋ก ํŠธ ์—”๋“œ ์—ญํ• ์„ ํ•˜๋Š” ๋ชจ๋“  ๊ณ ๊ธ‰ ํด๋ž˜์Šค๋ฅผ ๋ณด์œ ํ•˜๋Š” Python ๊ณ„์ธต, ์ง„์ž…์ ์„ ๋ณด์œ ํ•˜๋Š” ๊ธฐ๋ณธ ํด๋ž˜์Šค๊ฐ€ ์žˆ๋Š” CPython ๊ฐœ์ธ ๋ชจ๋“ˆ, ๋ชจ๋“  ์œ ํ˜• ๋ณ€ํ™˜ ๋ฐ ์ผ์น˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ๊ธฐ๋ณธ ๋ชจ๋“ˆ๋กœ ์ž‘๋™ํ•˜๋Š” C++ ์ง€์› ๊ณ„์ธต์ด ์žˆ์Šต๋‹ˆ๋‹ค. Java ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฐ ๋ชจ๋“  ์œ ํ‹ธ๋ฆฌํ‹ฐ ์ž‘์—…(๊ฐ์ฒด ์ˆ˜๋ช… ์œ ์ง€, ์Šฌ๋ผ์ด์Šค ๋ฐ ์˜ˆ์™ธ์— ๋Œ€ํ•œ ์ง€์› ํด๋ž˜์Šค ์ƒ์„ฑ, javadoc ์ถ”์ถœ๊ธฐ/๋ Œ๋”๋ง)์„ ์ˆ˜ํ–‰ํ•˜๋Š” Java ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ.

8๋…„ ์ „ JPype๋Š” ์•ฝ๊ฐ„ ์—‰๋ง์ด์—ˆ์Šต๋‹ˆ๋‹ค. Ruby์™€ Python์„ ๋ชจ๋‘ ์ง€์›ํ•˜๋ ค๊ณ  ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— C++ ๋ ˆ์ด์–ด๋Š” ์ž‘์—…ํ•  ๋ž˜ํผ๊ฐ€ ์–ฝํ˜€ ์žˆ๊ณ  ํ”„๋ŸฐํŠธ ์—”๋“œ๋Š” ๋ชจ๋‘ Python์œผ๋กœ ๋˜์–ด ์žˆ์–ด์„œ ๋งค์šฐ ๋Š๋ ธ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ numpy ์ง€์›์ด ์ปดํŒŒ์ผ๋˜์–ด ๋‹ค๋ฅธ ๊ฐ์ฒด๊ฐ€ ๋ฐ˜ํ™˜๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ฐ˜ํ™˜ ์œ ํ˜•์—์„œ ๋ถ„๊ธฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋„ค์ดํ‹ฐ๋ธŒ Python๊ณผ Java ๊ฐ์ฒด๊ฐ€ ๋‹ค๋ฅธ ํ”„๋ก์‹œ ์—ญํ• ์„ ํ•˜๋ ค๋ฉด JException๊ณผ ๊ฐ™์€ ๋งŽ์€ ์–ด๋Œ‘ํ„ฐ ํด๋ž˜์Šค๊ฐ€ ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ”„๋กœ์ ํŠธ์— ํ•ฉ๋ฅ˜ํ•œ ์ง€ 3๋…„ ๋งŒ์— ๋ชจ๋“  ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. JPype์˜ ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ๋ชฉํ‘œ(์ €๋ฅผ ์œ„ํ•ด)๋Š” ๋ฌผ๋ฆฌํ•™์ž๋“ค์ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ์ต์ˆ™ํ•˜์—ฌ Java๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ  ๊ณผํ•™์ ์ธ Python ์ฝ”๋“œ์™€ ๋†’์€ ์ˆ˜์ค€์˜ ํ†ตํ•ฉ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์„ ๋งŒํผ ์ถฉ๋ถ„ํžˆ ๊ฐ„๋‹จํ•œ ๊ตฌ๋ฌธ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ž๋ฐ”๊ฐ€ ์ง€์›ํ•˜๋Š” ๊ฐ์ฒด๊ฐ€ "๋ชจ๋“  ์žฅ์‹" CPython ๊ฐ์ฒด ๋ž˜ํผ๋ฅผ ๊ฐ–๋„๋ก ํ•จ์œผ๋กœ์จ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. Java ์›์‹œ ๋ฐฐ์—ด์„ ๋ณ€ํ™˜ํ•˜๋Š” ๋Œ€์‹  Java ์›์‹œ ๋ฐฐ์—ด์„ numpy์™€ ๋™์ผํ•œ ์ง„์ž…์ ์„ ๋ชจ๋‘ ๊ตฌํ˜„ํ•˜๋Š” ์ƒˆ๋กœ์šด ์›์‹œ Python ์œ ํ˜•์œผ๋กœ ๋งŒ๋“ค๊ณ  ์ด ๋ชจ๋“  ๊ฒƒ์ด ๋ฉ”๋ชจ๋ฆฌ ๋ฒ„ํผ ์ „์†ก์œผ๋กœ ์ง€์›๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ list(jarray) ๋˜๋Š” np.array(jarray) ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋น ๋ฅธ ๋ณ€ํ™˜์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

Android์— ์ ์šฉํ•˜๋ ค๋ฉด ์‹œ์ž‘ ์‹œํ€€์Šค๋ฅผ ๋‹ค์‹œ ์ž‘์—…ํ•ด์•ผ ํ•˜๋ฉฐ ๋‚ด๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋กœ๋“œํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” ์ฝํฌ ์ฝ”๋“œ๋ฅผ ๋ณด๋‹ค ์ „ํ†ต์ ์ธ JNI ๋ชจ๋ธ๋กœ ๊ต์ฒดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ฒ„์ „์—์„œ ์ด๋ฏธ ์ฝํฌ ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ–ˆ์œผ๋ฏ€๋กœ ์ดํ›„ ๋ฒ„์ „์€ ์ด๋ฏธ ์ถฉ์กฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ „์ž๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๋ณผ ์ˆ˜์žˆ๋Š” ์ ‘๊ทผ ๋ฐฉ์‹์˜ ์ฃผ์š” ์ฐจ์ด์ ์€ PyJnius๊ฐ€ ๋ฐฐ์—ด์„ ์˜ค๊ฐ€๋Š” ๋ฐฐ์—ด์„ ๋ณ€ํ™˜ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ํฐ ๋ฐฐ์—ด(์ข…์ข… ๋ณ€ํ™˜๋˜์ง€ ์•Š์Œ)์„ ๋’ค๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด ์„ ํ˜ธ๋˜๋Š” JPype ์Šคํƒ€์ผ์ธ ๊ณผํ•™์  ์ฝ”๋”ฉ์— ๋งค์šฐ ๊ธˆ์ง€๋œ ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ๋ณ€ํ™˜์„ ์š”๊ตฌํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•˜๋ฉด ๊ฐ’์— ์˜ํ•œ ์ „๋‹ฌ ๋ฐ ์ฐธ์กฐ์— ์˜ํ•œ ์ „๋‹ฌ๊ณผ ๊ฐ™์€ ์˜ต์…˜์ด ๊ฐ•์ œ ์ ์šฉ๋˜์ง€๋งŒ, ์ด๋Š” ๋‹ค์ค‘ ์ธ์ˆ˜ ํ˜ธ์ถœ์ด ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ชจ๋“  ์ธ์ˆ˜์— ๋Œ€ํ•ด ํ•˜๋‚˜์˜ ์ •์ฑ…์„ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ž ์žฌ์ ์œผ๋กœ ๋” ํฐ ๋ฌธ์ œ๋กœ ์ด์–ด์ง‘๋‹ˆ๋‹ค. ๋˜ํ•œ ๋‹ค์ฐจ์› ๋ฐฐ์—ด์„ ๋‹ค๋ฃจ๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ( obj.method(1, jnius.byref(list1), list2) ์™€ ๊ฐ™์ด ์‚ฌ์šฉ๋˜๋Š” ์–ด๋Œ‘ํ„ฐ ํด๋ž˜์Šค๊ฐ€ ๋‹ฌ์„ฑ๋  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋” ๋‚˜์€ ์ œ์–ด๋ฅผ ์ œ๊ณตํ–ˆ์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.) ์ด ์™ธ์—๋„ GC ์—ฐ๊ฒฐ, ํ˜ธ์ถœ์ž์— ๋ฏผ๊ฐํ•œ ๋ฉ”์„œ๋“œ ๋“ฑ JPype๊ฐ€ ํ•ด๊ฒฐํ•œ ๋ฌธ์ œ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๊ฒƒ์ด ์—†๋‹ค๋ฉด JPype ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ข‹์€ ์•„์ด๋””์–ด๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

@Thrameos ์ตœ๊ทผ ๋ณ‘ํ•ฉํ•˜๋ ค๊ณ  ํ•˜๋Š” ๊ฒƒ์€ Java Functional ์ธํ„ฐํŽ˜์ด์Šค์— Python ๋žŒ๋‹ค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. https://github.com/kivy/pyjnius/pull/515 ์ฐธ์กฐ ; ๋‚˜๋Š” JPype์—์„œ ๊ทธ๊ฒƒ์„ ๋ณด์ง€ ๋ชปํ–ˆ๋‹ค?

JPype๋Š” 1.0.0๋ถ€ํ„ฐ ๊ธฐ๋Šฅ ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋žŒ๋‹ค๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” 3์›” 30์ผ 1.0์œผ๋กœ์˜ ํ‘ธ์‹œ 30๊ฐœ ์ค‘ ์ผ๋ถ€์˜€์Šต๋‹ˆ๋‹ค.

JPype๋Š” ์˜ค๋žœ ์ž ๋ณต๊ธฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์›๋ž˜ 2004๋…„์— ์‹œ์ž‘๋˜์–ด 2007๋…„๊นŒ์ง€ ์‹คํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ํ›„ ์‚ฌ์šฉ์ž ๊ทธ๋ฃน์ด 2015๋…„๊ฒฝ Python 3์œผ๋กœ ์ด์‹ํ•˜๊ธฐ ์œ„ํ•ด ๋ถ€ํ™œ์‹œ์ผฐ๊ธฐ ๋•Œ๋ฌธ์— ํฐ ํž˜์„ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ 2017๋…„์— ๊ตญ๋ฆฝ ์—ฐ๊ตฌ์†Œ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์„ ํƒ๋˜์–ด 0.6์—์„œ ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. 3 ~ 0.7.2. ๊ทธ ๊ธฐ๊ฐ„ ๋™์•ˆ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ํ•ต์‹ฌ ๊ธฐ์ˆ ์„ ๊ฐœ์„ ํ•˜๊ณ  ๊ฐ•ํ™”ํ•˜๋Š” ๋ฐ ๋ชจ๋“  ๋…ธ๋ ฅ์ด ์ง‘์ค‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‘ ๋ฒˆ์งธ ํ•ต์‹ฌ ์žฌ์ž‘์„ฑ ํ›„ 3์›”์— ๋งˆ์นจ๋‚ด ์™„๋ฃŒ๋˜์–ด ๋งˆ์นจ๋‚ด 1.0.0์„ ํ‘ธ์‹œํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ดํ›„๋กœ ์šฐ๋ฆฌ๋Š” "30์ผ ๋ฐค์— 30๊ฐœ ๋ฝ‘๊ธฐ" ์œ„์‹œ๋ฆฌ์ŠคํŠธ ์บ ํŽ˜์ธ์—์„œ "๋ˆ„๋ฝ๋œ" ๋ชจ๋“  ๊ฒƒ์„ ์ถ”๊ฐ€ํ•ด ์™”์Šต๋‹ˆ๋‹ค. ๋„ˆ๋ฌด ๋งŽ์€ ์ž‘์—…์œผ๋กœ ์ธํ•ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์—†์—ˆ๋˜ ๋ชจ๋“  ๋ฐฑ๋กœ๊ทธ๊ฐ€ ๋งˆ์นจ๋‚ด ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค(๋ฌธ์ œ๊ฐ€ 50๊ฐœ์—์„œ 20๊ฐœ๋กœ ๊ฐ์†Œํ•˜๊ณ  ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฌด์—‡์ด ํ•„์š”ํ•œ์ง€ ๋ฌป๋Š” ๋“ฑ). ๋”ฐ๋ผ์„œ ํ˜„์žฌ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ด์ „ ๋ฒ„์ „์—์„œ๋Š” ์ฐพ์„ ์ˆ˜ ์—†์—ˆ๋˜ ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” ๋Œ€๋ถ€๋ถ„์˜ ๊ธฐ๋Šฅ ์š”์ฒญ์„ 1์ฃผ์ผ๋„ ์ฑ„ ์•ˆ ๋˜์–ด ์ฒ˜๋ฆฌํ–ˆ๊ณ  ๋‚˜๋จธ์ง€ 3๊ฐ€์ง€(์—ญ ๋ธŒ๋ฆฌ์ง€, Python์˜ ํด๋ž˜์Šค ํ™•์žฅ, ๋‘ ๋ฒˆ์งธ JVM์„ ์‹œ์ž‘ํ•˜๋Š” ๊ธฐ๋Šฅ)๋งŒ ๋‚จ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Java๊ฐ€ Python์„ ํ˜ธ์ถœํ•˜๊ณ  Java ๊ธฐ๋ณธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก Python ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ์Šคํ…์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๋ฆฌ๋ฒ„์Šค ๋ธŒ๋ฆฌ์ง€ ์ฝ”๋“œ๋ฅผ ์™„๋ฃŒํ•˜๊ธฐ ์œ„ํ•œ 6๊ฐœ์›”์˜ ๊ธด ๋…ธ๋ ฅ ์ค‘ 2๊ฐœ์›”์ด ๊ฑธ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋กœ์ ํŠธ๋Š” ๋‹ค์‹œ ์ž ์ด ๋“ค ๊ฒƒ์ž…๋‹ˆ๋‹ค. Python์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ์ง€์›์„ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ASM์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฆ‰์„์—์„œ Java ํด๋ž˜์Šค๋ฅผ ๋นŒ๋“œํ•ฉ๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ Jython์ฒ˜๋Ÿผ ์™„์ „ํžˆ ํ†ตํ•ฉ๋˜์ง€๋Š” ์•Š์•˜์ง€๋งŒ ํฐ ์ฐจ์ด๊ฐ€ ์—†์„ ์ •๋„๋กœ ์ถฉ๋ถ„ํžˆ ๊ฐ€๊น์Šต๋‹ˆ๋‹ค.

์ž์„ธํ•œ ์„ค๋ช…์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์•„์ด๋””์–ด๊ฐ€ ์žˆ๋‹ค๋ฉด ์ฝ”๋“œ๋ฅผ ๊ณต๋ถ€ํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•ž์„œ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๋ฉด ์ฝ”๋“œ ํ’ˆ์งˆ๊ณผ ๊ตฌ์กฐ ๋ชจ๋‘์—์„œ ๋‚ด๊ฐ€ ๋ณธ ๊ฒƒ์ด ๋งค์šฐ ๊นจ๋—ํ•ด ๋ณด์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ์ž‘์—…์„ ์ถ•ํ•˜ํ•ฉ๋‹ˆ๋‹ค. ๋‹น์‹ ์€ Py4J์™€์˜ ํ˜ผํ•ฉ์— ๋Œ€ํ•ด ์˜ณ์•˜์Šต๋‹ˆ๋‹ค. ์ œ ์ƒ๊ฐ์— JPype๋ฅผ ๋ณด์•˜์„ ๋•Œ ๋‹น์‹ ์ด ์„ค๋ช…ํ•˜๋Š” ์ง€์ €๋ถ„ํ•œ ์ƒํƒœ์— ์žˆ์–ด์•ผ ํ•˜๊ณ  ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ด ์‹œ์ ์—์„œ PyJNIus๋ณด๋‹ค ํ›จ์”ฌ ๋” ๋ณต์žกํ–ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฐ’/๋ณ€ํ™˜์— ์˜ํ•œ ์ „๋‹ฌ์— ๋Œ€ํ•œ ๊ท€ํ•˜์˜ ์š”์ ์€ ๋งค์šฐ ์‚ฌ์‹ค์ด๋ฉฐ @hx2A ๊ฐ€ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์กฐ์‚ฌํ•˜๊ณ  ํŒŒ์ด์ฌ ์œ ํ˜•์œผ๋กœ ๋‹ค์‹œ ๋ณ€ํ™˜์„ ์„ ํƒ ์‚ฌํ•ญ์œผ๋กœ ๋งŒ๋“ค์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์—์„œ๋„ ์ตœ๊ทผ ํ† ๋ก ์„ ์ด‰๋ฐœํ–ˆ์Šต๋‹ˆ๋‹ค. ์ž๋ฐ” ๋ชฉ๋ก์œผ๋กœ ๋ณ€ํ™˜๋˜๊ณ , ์ž๋ฐ”์— ์˜ํ•ด ์ˆ˜์ •๋˜๊ณ , ํŒŒ์ด์ฌ์œผ๋กœ ๋‹ค์‹œ ๋ณ€ํ™˜๋˜์–ด ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘์„ ์œ„ํ•ด ํ™•์‹คํžˆ ์ฐจ์„ ์ฑ…์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ํ‚ค์›Œ๋“œ ์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋น„์šฉ์œผ๋กœ ๋‘ ๋ฒˆ์งธ ๋ถ€๋ถ„์„ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž๋ฐ”๋Š” ๊ทธ๊ฒƒ๋“ค์„ ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ช… ์ถฉ๋Œ์€ ์—†์ง€๋งŒ ํ™•์‹คํžˆ ๋ฌธ๋ฒ•์ ์œผ๋กœ ์ข€ ๋” ์‹œ๋„๋Ÿฝ์Šต๋‹ˆ๋‹ค).

JPype์™€ PyJNIus์˜ ๊ฐ€๋Šฅํ•œ ์ฐจ์ด์ ์— ๊ด€ํ•ด์„œ๋Š” Python ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Java ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์ด๋ฅผ Java์— ์ „๋‹ฌํ•˜์—ฌ ์ฝœ๋ฐฑ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด์— Java ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜๋ ค๋ฉด Java ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํŒŒ์ด์ฌ์—์„œ, ๊ทธ๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ ๋‹ค๋ฃฐ ์ˆ˜ ์—†๋Š” ์ผ๋ถ€ ์•ˆ๋“œ๋กœ์ด๋“œ API๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์š”๊ตฌ ์‚ฌํ•ญ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ท€ํ•˜์˜ ์˜๊ฒฌ์—์„œ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ถ”๋ก ํ–ˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ ์•„๋งˆ๋„ Java ํด๋ž˜์Šค๊ฐ€ ๊ท€ํ•˜๋ฅผ ํ˜ธ์ถœํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๋Š” ๋Šฅ๋ ฅ์ด ์—†์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ํŒŒ์ด์ฌ ์ฝ”๋“œ(์ธํ„ฐํŽ˜์ด์Šค ์‚ฌ์šฉ).

JPype๋Š” Python์—์„œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜ Python ํด๋ž˜์Šค์— ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

from java.util.function import Consumer

@jpype.JImplements(Consumer)
class MyConsumer:
   @jpype.JOverride
   def apply(self, obj):
       pass

JVM์ด ์‹œ์ž‘๋˜๊ธฐ ์ „์— ํด๋ž˜์Šค๊ฐ€ ์ •์˜๋œ ๊ฒฝ์šฐ @JImplements ์—์„œ ๋ฌธ์ž์—ด์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ•œ ๋ฒˆ์— ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋ชจ๋“  ๋ฉ”์†Œ๋“œ๊ฐ€ ๊ตฌํ˜„๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ฃผ์š” ์ฐจ์ด์ ์€ JPype๋Š” ์˜ค๋ฒ„๋กœ๋“œ๋œ ๋ฉ”์„œ๋“œ๊ฐ€ ์•„๋‹Œ ๋””์ŠคํŒจ์น˜ ๋ฉ”์„œ๋“œ(๋ชจ๋“  ์˜ค๋ฒ„๋กœ๋“œ๋Š” ๋™์ผํ•œ ๋ฉ”์„œ๋“œ๋กœ ์ด๋™)๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” Java์™€ Python ๋ชจ๋‘์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์ธ ๊ฒฝ์šฐ ๊ฐœ๋ณ„ ์˜ค๋ฒ„๋กœ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์•„๋ฌด๋„ ์š”์ฒญํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

(ํŽธ์ง‘: ์šฐ๋ฆฌ๊ฐ€ Python ์ƒ์†์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ์ด์œ ๋Š” ์ด๊ฒƒ์ด ์ถ”๊ฐ€๋˜์—ˆ์„ ๋•Œ ๋งŽ์€ ๋ฉ”ํƒ€ ํด๋ž˜์Šค ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚จ Python 2๋ฅผ ์—ฌ์ „ํžˆ ์ง€์›ํ•˜๊ณ  ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํด๋ž˜์Šค ํ™•์žฅ์ด ๋ฐฐ์น˜๋˜๋ฉด ๋” ์ •๋ฆฌํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ฃผ์„์€ ์„ ์–ธ ์‹œ๊ฐ„์— ํ•œ ๋ฒˆ ํ‰๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ๋” ๊นจ๋—ํ–ˆ์Šต๋‹ˆ๋‹ค.)

์šฐ๋ฆฌ๋Š” ๋™์ผํ•œ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ์ปค์Šคํ„ฐ๋งˆ์ด์ €(dunder?)๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

@jpype.JImplementationFor("java.util.ArrayList")
class ArrayListImpl:
    def __getitem__(self, i):
        return self.get(i)
    @jpype.JOverride
    def addAll(self, list):
        # Decide if we need to convert or can call directly.
        ...

๋˜ํ•œ ์ฃผ์„์„ ์‚ฌ์šฉํ•˜์—ฌ "๋ชจ๋“  Python ๊ฒฝ๋กœ ๊ฐœ์ฒด๊ฐ€ java.io.File๋กœ ๋ณ€ํ™˜๋จ"๊ณผ ๊ฐ™์€ ์•”์‹œ์  ๋ณ€ํ™˜๊ธฐ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

 @jpype.JConversion("java.io.File", instanceof=pathlib.PurePath)
 def _JFileConvert(jcls, obj):
       Paths = jpype.JClass("java.nio.file.Paths")
       return Paths.get(str(obj))

๋ถ„๋ช…ํžˆ ์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ๋…ผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ํŠน์ˆ˜ C ๋ฐฉ๋ฒ•๋ณด๋‹ค ์•ฝ๊ฐ„ ๋Š๋ฆฌ์ง€๋งŒ ๊ฐ€๋…์„ฑ๊ณผ ์œ ์—ฐ์„ฑ์„ ๋†’๊ฒŒ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ๋ณ‘๋ชฉ ํ˜„์ƒ์ด ์ž…์ฆ๋œ ์ค‘์š”ํ•œ ๊ฒฝ๋กœ๋ฅผ ํ•„์š”์— ๋”ฐ๋ผ C๋กœ ๋˜๋Œ๋ ค ๋†“์•˜์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ๋˜ํ•œ ๊น”๋”ํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ๊ตฌ๋ฌธ ์„คํƒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. MyJavaClass@obj => MyJavaClass๋กœ ์บ์ŠคํŠธ(Java์— ์ƒ์‘ํ•˜๋Š” (MyJavaClass)obj ) ๋˜๋Š” cls=JInt[:] => ๋ฐฐ์—ด ์œ ํ˜• ์ƒ์„ฑ( cls=int[].class ) ๋˜๋Š” a=JDouble[10][5] => multidim ๋ฐฐ์—ด์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค( double[][] a = new double[10][5] ).

์ €๋Š” JPype์—์„œ ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜๊ธฐ ์œ„ํ•œ ํ”„๋กœํ† ํƒ€์ž… ์ž‘์—…์„ ํ•ด์™”์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ Swing ํด๋ž˜์Šค ๋ฐ ๊ธฐํƒ€ API์—์„œ ํด๋ž˜์Šค ํ™•์žฅ์ด ํ•„์š”ํ•œ ๊ฒƒ๊ณผ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ๋‚ด๊ฐ€ ๋งŒ๋“  ์†”๋ฃจ์…˜์€ ์žฌ์ •์˜๋œ ๊ฐ ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•ด HashMap์ด ์žˆ๋Š” ํ™•์žฅ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•ด๋‹น ์ง„์ž…์ ์— ๋Œ€ํ•œ ํ•ด์‹œ๋งต์— ์•„๋ฌด ๊ฒƒ๋„ ์—†์œผ๋ฉด ์ด๋ฅผ super์— ์ „๋‹ฌํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ํ”„๋ก์‹œ ๋ฉ”์†Œ๋“œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ์ด๊ฒƒ์ด ์—ญ ๋ธŒ๋ฆฌ์ง€๊ฐ€ ์™„๋ฃŒ๋œ ํ›„์— ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์‰ฌ์šธ ๊ฒƒ์ด๋ผ๊ณ  ํŒ๋‹จํ•˜์—ฌ Java๊ฐ€ ์‹ค์ œ๋กœ Java ํ”„๋ก์‹œ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฑฐ์น˜์ง€ ์•Š๊ณ  Python ๋ฉ”์†Œ๋“œ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ํ”„๋กœํ† ํƒ€์ž…์ด ์ž‘๋™ํ•˜๊ธฐ๊นŒ์ง€ ์•ฝ 6๊ฐœ์›”์ด ๋‚จ์•˜์Šต๋‹ˆ๋‹ค. epypj ๋ถ„๊ธฐ(์—ญ ๋ธŒ๋ฆฌ์ง€์˜ ๊ฒฝ์šฐ ๋‚ด ์ด๋ฆ„)๋ฅผ ๋ณด๋ฉด Java์—์„œ Python์œผ๋กœ ๋‹ค์‹œ ํ˜ธ์ถœ์ด ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹๊ณผ ASM์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฆ‰์„์—์„œ Java ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“œ๋Š” ํ˜ธ์ถœ์ž๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํŒจํ„ด์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ€๋น„์ง€ ์ˆ˜์ง‘์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ๊ณผ ๊ด€๋ จํ•˜์—ฌ ํ•ด๋‹น ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” JPype๋Š” ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค. ๋จผ์ € Python ๊ฐ์ฒด์˜ ์ˆ˜๋ช…์„ Java ๊ฐ์ฒด์— ๋ฐ”์ธ๋”ฉํ•˜๋Š” JPypeReferenceQueue(native/java/org/jpype/ref/JPypeReferenceQueue)๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ Java๊ฐ€ ์ผ์ • ๊ธฐ๊ฐ„ ๋™์•ˆ Python ๊ฐœ๋…์— ์•ก์„ธ์Šคํ•ด์•ผ ํ•˜๋Š” ๋ฒ„ํผ ๋ฐ ๊ธฐํƒ€ ํ•ญ๋ชฉ์„ ๋งŒ๋“œ๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ๋Š” ์ „์—ญ ์ฐธ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Python์ด ๋ฒ”์œ„ ๋‚ด์—์„œ Java ๊ฐ์ฒด๋ฅผ ๋ณด์œ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” ํŠน์ • ์กฐ๊ฑด(ํ’€ ํฌ๊ธฐ, ์ƒ๋Œ€์  ์ฆ๊ฐ€)์ด ์žˆ์„ ๋•Œ ์‹œ์Šคํ…œ ์ค‘ ํ•˜๋‚˜๊ฐ€ GC๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜๊ณ  ์ด๋ฅผ ๋‹ค๋ฅธ ์‹œ์Šคํ…œ์— pingํ•˜๋Š” ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘๊ธฐ ๋งํฌ(native/common/jp_gc.cpp)๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰ ํ”„๋ก์‹œ๋Š” ์•ฝํ•œ ์ฐธ์กฐ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ฃจํ”„๋ฅผ ํ˜•์„ฑํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค(ํ”„๋ก์‹œ๋Š” Java ์ ˆ๋ฐ˜์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ๋ณด์œ ํ•˜๊ณ  Java ์ ˆ๋ฐ˜์€ Python ๊ตฌํ˜„์„ ๋‹ค์‹œ ๊ฐ€๋ฆฌํ‚ด). ๊ฒฐ๊ตญ ์ €๋Š” Python์ด Java๋ฅผ ํŠธ๋ž˜๋ฒ„์Šคํ•  ์ˆ˜ ์žˆ๋„๋ก ์—์ด์ „ํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•˜์ง€๋งŒ ์ด๋Š” ๊ณง ๊ฐˆ ๊ธธ์ž…๋‹ˆ๋‹ค.

์ €๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ๊ฐ€ ์•„๋‹Œ ๋ฐ์Šคํฌํƒ‘์—์„œ pyjnius๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ๋“ค ์ค‘ ํ•œ ๋ช…์ž…๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ ๊ตฌ์ถ•์„ ์‹œ์ž‘ํ•  ๋•Œ JPype์— ๋Œ€ํ•ด ๋ชฐ๋ž์ง€๋งŒ ์ฐจ์ด์ ์ด ๋ฌด์—‡์ธ์ง€ ์•Œ์•„๋ณด๊ธฐ ์œ„ํ•ด ์กฐ์‚ฌ๋ฅผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

pyjnius์˜ ๊ณ ์œ ํ•œ ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜๋Š” ํ˜ธ์ถœ์ž๊ฐ€ ๋ณดํ˜ธ ๋ฐ ๋น„๊ณต๊ฐœ ๋ฉ”์„œ๋“œ์™€ ํ•„๋“œ๋ฅผ ํฌํ•จํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚ด ์„ ํ˜ธ ์‚ฌํ•ญ์€ ๊ณต๊ฐœ ์ „์šฉ์ด์ง€๋งŒ ๋น„๊ณต๊ฐœ ํ•„๋“œ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์œ ์šฉํ•˜๋‹ค๋Š” ์ฃผ์žฅ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค.

์„ฑ๋Šฅ์€ ๋‚ด ํ”„๋กœ์ ํŠธ์— ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ํด๋ž˜์Šค๋กœ ๋ช‡ ๊ฐ€์ง€ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

package org.pkg;

public class MyClass {

  public MyClass() {
  }

  public int number = 42;

  public float add1(float x, float y) {
    return x + y;
  }

  public float add2(float x, float y) {
    return x + y;
  }

  public float add2(int x, int y) {
    return x + y;
  }
}

JPype์—์„œ:

In [1]: import jpype
   ...: import jpype.imports
   ...: jpype.startJVM()
   ...: from org.pkg import MyClass
   ...: myInstance = MyClass()
   ...:

In [2]: %timeit myInstance.number
640 ns ยฑ 2.65 ns per loop (mean ยฑ std. dev. of 7 runs, 1000000 loops each)

In [3]: %timeit myInstance.add1(10.3, 20.5)
2.13 ยตs ยฑ 24.8 ns per loop (mean ยฑ std. dev. of 7 runs, 100000 loops each)

In [4]: %timeit myInstance.add2(10.3, 20.5)
2.19 ยตs ยฑ 9.41 ns per loop (mean ยฑ std. dev. of 7 runs, 100000 loops each)

ํ”ผ๋‹ˆ์šฐ์Šค์—์„œ:

In [1]: import jnius

In [2]: MyClass = jnius.autoclass('org.pkg.MyClass')

In [3]: myInstance = MyClass()

In [4]: %timeit myInstance.number
161 ns ยฑ 0.104 ns per loop (mean ยฑ std. dev. of 7 runs, 10000000 loops each)

In [5]: %timeit myInstance.add1(10.3, 20.5)
1.04 ยตs ยฑ 8.16 ns per loop (mean ยฑ std. dev. of 7 runs, 1000000 loops each)

In [6]: %timeit myInstance.add2(10.3, 20.5)
2.71 ยตs ยฑ 11.2 ns per loop (mean ยฑ std. dev. of 7 runs, 100000 loops each)

Pyjnius๋Š” ์˜ค๋ฒ„๋กœ๋“œ๋œ ๋ฐฉ๋ฒ•์„ ์ œ์™ธํ•˜๊ณ ๋Š” ์ƒ๋‹นํžˆ ๋น ๋ฆ…๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ๊ฐ€ ์˜ค๋ฒ„๋กœ๋“œ๋  ๋•Œ ํ˜ธ์ถœํ•  ๋ฉ”์„œ๋“œ๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ฐธ๊ณ  ์‚ฌํ•ญ์„ ๋น„๊ตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Pyjnius์—๋Š” ๋งŽ์€ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ด๋Š” ์ด๋Ÿฌํ•œ ์ ์ˆ˜ ๋งค๊ธฐ๊ธฐ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. JPype๋Š” ๊ทธ ๊ฒฐ์ •์„ ํ›จ์”ฌ ๋” ๋น ๋ฅด๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ๋ฒค์น˜๋งˆํฌ ๋ชฉ์ ์œผ๋กœ:

In [9]: def add(x, y):
   ...:     return x + y
   ...:

In [10]: %timeit add(10.3, 20.5)
82.9 ns ยฑ 0.187 ns per loop (mean ยฑ std. dev. of 7 runs, 10000000 loops each)

๋ฌผ๋ก  ๋ช‡ ยตs์˜ ์ฐจ์ด๋Š” ์‚ฌ์†Œํ•˜์ง€๋งŒ ์ˆ˜์ฒœ ๊ฐœ์˜ ์ž‘์€ ํ˜ธ์ถœ์„ ๋งค์šฐ ๋น ๋ฅด๊ฒŒ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ๋”ํ•ด์ง€๋ฏ€๋กœ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

JPype์™€ numpy์˜ ํ†ตํ•ฉ์€ ๋งค์šฐ ํ›Œ๋ฅญํ•˜๊ณ  ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. ์—ฐ๊ตฌ์ž๋“ค์ด ๋ณต์žกํ•œ ๊ตฌ๋ฌธ ์—†์ด Java ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ํฐ ๋ฐฐ์—ด์„ ์ „๋‹ฌํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์ด๊ฒƒ์„ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ํฐ ๋ฐฐ์—ด์„ ์ „๋‹ฌํ•ด์•ผ ํ•˜๊ณ  tobytes() ๋ฐ ๋ฐ”์ดํŠธ๋ฅผ ์ˆ˜์‹ ํ•  ์ˆ˜ ์žˆ๋Š” ํŠน์ˆ˜ Java ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•˜์ง€๋งŒ ๋ถ„๋ช…ํžˆ ๊ทธ๋ ‡๊ฒŒ ๊น”๋”ํ•˜๊ฑฐ๋‚˜ ํŽธ๋ฆฌํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.

๋ถˆํ–‰ํžˆ๋„ JPype ์†๋„๋Š” ์ผ์ข…์˜ ์ „๋ง์ž…๋‹ˆ๋‹ค. JPype๋Š” ๋‚˜์œ ์ผ๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•ด ๋งค์šฐ ๋ฐฉ์–ด์ ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์‚ฌ์†Œํ•˜์ง€ ์•Š์€ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋งŽ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์˜ˆ๋ฅผ ๋“ค์–ด Java ํ˜ธ์ถœ์ด ์ˆ˜ํ–‰๋  ๋•Œ๋งˆ๋‹ค ์Šค๋ ˆ๋“œ๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋ฏ€๋กœ IDE์™€ ๊ฐ™์€ ์™ธ๋ถ€ ์Šค๋ ˆ๋“œ์—์„œ ํ˜ธ์ถœ๋˜๋Š” ๊ฒฝ์šฐ segfault๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚ด ๋กœ์ปฌ ์‚ฌ์šฉ์ž ๊ทธ๋ฃน์€ ๋ชจ๋‘ ๊ณผํ•™์ž์ด๋ฏ€๋กœ ์ง„์ž…์ ์€ ๋ชจ๋‘ ๋งค์šฐ ๋”์ฐํ•œ ๊ต์ฐจ ๋ฐฐ์„ ์œผ๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธ๋ฉ๋‹ˆ๋‹ค. ์–ด๋–ค ๊ฒƒ์ด ๊ทธ๋“ค์—๊ฒŒ ์„ธ๊ทธํดํŠธ(segfaults)๊ฐ€ ์žˆ๋‹ค๋ฉด(์•„๋ฌด๋ฆฌ ๋ฏธ์ณค์–ด๋„), ๋‚˜๋Š” ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค. (์ด๋Š” ์˜๋„์ ์œผ๋กœ ๋‚˜์œ ๊ฐ์ฒด๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์„ ํฌํ•จํ•˜์—ฌ 1500๋ฒˆ์˜ ํ…Œ์ŠคํŠธ๋ฅผ ์„ค๋ช…ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.)

๋‘˜์งธ, ๊ฐœ๋ณ„ ์ž‘์—…์˜ ์†๋„๋Š” ์ˆ˜ํ–‰๋˜๋Š” ์ž‘์—…์˜ ์•„์ฃผ ์ž‘์€ ์ฐจ์ด์—์„œ ํฌ๊ฒŒ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์ด ์ค€ ์‚ฌ์†Œํ•œ ์˜ˆ๋Š” ์ตœ์•…์˜ ๊ฒฝ์šฐ ์ค‘ ํ•˜๋‚˜์˜€์Šต๋‹ˆ๋‹ค. ์•ก์„ธ์Šค ์ค‘์ธ ํ•„๋“œ ์œ ํ˜•์— ๋”ฐ๋ผ ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ์•ก์„ธ์Šค ์†๋„๊ฐ€ ์‹ค์ œ๋กœ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์†๋„ ์˜ˆ์ œ์˜ ๊ฒฝ์šฐ int ํ•„๋“œ๋ฅผ ์š”์ฒญํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

  • PyJnius์—์„œ๋Š” ๊ฐ์ฒด ์กฐํšŒ๋ฅผ ์œ„ํ•œ ์„ค๋ช…์ž๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํ•„๋“œ์— ์•ก์„ธ์Šคํ•˜์—ฌ ์ƒˆ๋กœ์šด Python long์„ ์ƒ์„ฑํ•œ ๋‹ค์Œ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • JPype์—์„œ๋Š” ๊ฐ์ฒด ์กฐํšŒ๋ฅผ ์œ„ํ•œ ๋””์Šคํฌ๋ฆฝํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํ•„๋“œ์— ์•ก์„ธ์Šคํ•˜๊ณ  ์ƒˆ๋กœ์šด Python long์„ ์ƒ์„ฑํ•œ ๋‹ค์Œ Java int์— ๋Œ€ํ•œ ๋ž˜ํผ ์œ ํ˜•์„ ์ƒ์„ฑํ•˜๊ณ  Python long ๋ฉ”๋ชจ๋ฆฌ๋ฅผ JInt์— ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ •์ˆ˜ ํด๋ž˜์Šค ์ง์ ‘), ๊ทธ๋Ÿฐ ๋‹ค์Œ ์Šฌ๋กฏ์„ Java ๊ฐ’์œผ๋กœ ๋ฐ”์ธ๋”ฉํ•˜๊ณ  ๋งˆ์ง€๋ง‰์œผ๋กœ ๊ฒฐ๊ณผ JInt๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ํ•„๋“œ์— ์•ก์„ธ์Šคํ•  ๋•Œ ์†๋„ ๋ฒค์น˜๋งˆํ‚น์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ์‚ฌ์†Œํ•œ ์ผ์ด๋ผ๋„ ์‹ค์ œ๋กœ๋Š” ๊ทธ๋ ‡๊ฒŒ ์‚ฌ์†Œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
์ฐจ์ด์ ์€ ํ•˜๋‚˜๋Š” Python long์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ์‹ค์ œ Java ์ •์ˆ˜(Java ๋ณ€ํ™˜ ๊ทœ์น™์„ ๋”ฐ๋ฆ„)๋ฅผ ๋ฐ˜ํ™˜ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ์˜ค๋ฒ„๋กœ๋“œ๋œ ๋ฉ”์„œ๋“œ์— ์ „๋‹ฌ๋˜๊ณ  ์ œ๋Œ€๋กœ ๋ฐ”์ธ๋”ฉ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ž˜ํผ ์œ ํ˜•์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ž‘์—…์€ ๋‹จ์ˆœํžˆ Python ์œ ํ˜•์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ ์ด์ƒ์ด๋ฏ€๋กœ ์†๋„์—์„œ ํฐ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ช‡ ๊ฐ€์ง€ ๋‹ค๋ฅธ ํ•„๋“œ ์œ ํ˜•์„ ํ…Œ์ŠคํŠธํ•˜์—ฌ ์ด๋ฅผ ๋ณด์—ฌ์ฃผ๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ถˆํ–‰ํžˆ๋„, ๋‚ด๊ฐ€ Object ํ•„๋“œ๋ฅผ ํ…Œ์ŠคํŠธํ–ˆ์„ ๋•Œ jnius๋Š” "harness.objectField = ๋งˆ๊ตฌ" ์ฝ”๋“œ์—์„œ segfault๋ฅผ ๋ฐœ์ƒ์‹œ์ผฐ์Šต๋‹ˆ๋‹ค. ๊ทธ ํŠน์ • ๊ต์ฐจ ๋ฐฐ์„ ์ด ์™œ ๋ฌธ์ œ๋ฅผ ์ผ์œผ์ผฐ๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ ๋‚˜์—๊ฒŒ๋Š” ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ํ˜ธ์ถœ ์†๋„๊ฐ€ 3-5๋ฐฐ, ํŠน์ • ์–ด๋ ˆ์ด ์•ก์„ธ์Šค๊ฐ€ 300๋ฐฐ ๋นจ๋ผ์ง„ ์‹ฌ๊ฐํ•œ ์œ„๋ฐ˜์ž๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ ์™ธ์— JPype์˜ ์†๋„์— ๊ทธ๋‹ค์ง€ ๊ด€์‹ฌ์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์•„๋งˆ๋„ ์–ด๋–ค ๋ถ€๋ถ„์ด ๊ฐœ์„ ๋  ์ˆ˜ ์žˆ๋Š”์ง€ ๊ฒ€ํ† ํ•˜๊ณ  ํ™•์ธํ•ด์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์•ˆ์ „์„ ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜ ๋ฐ˜ํ’ˆ ๊ณ„์•ฝ์„ ์ œ๊ฑฐํ•˜์ง€ ์•Š๊ณ  PyJnius์™€ ๊ฐ™์€ ๋งจ ๋ผˆ๋กœ ์ค„์ผ ์ˆ˜ ์žˆ๋Š”์ง€ ์˜์‹ฌํ•ฉ๋‹ˆ๋‹ค(๋‚˜๋Š” ํ•  ์ˆ˜ ์—†์Œ). ๊ธฐ๊ปํ•ด์•ผ 10-30%์˜ ์†๋„ ํ–ฅ์ƒ์ด ์—ฌ์ „ํžˆ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

private ๋ฐ protected ํ•„๋“œ์— ์•ก์„ธ์Šคํ•˜๋Š” ๊ธฐ๋Šฅ์€ ํ™•์‹คํžˆ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๊ฐœ์ฒด๋ฅผ ์ง์ ‘ ๋…ธ์ถœํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋ฐ˜์‚ฌ ๋˜๋Š” ๊ธฐํƒ€ ๋‚ด๋ถ€ ์•ก์„ธ์Šค ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๊ฒƒ์„ ์ œ๊ณตํ•ด์•ผ ํ•œ๋‹ค๋ฉด ๊ณต๊ฐœ์ ์œผ๋กœ ๋…ธ์ถœ๋˜์ง€ ์•Š๋Š” ํ•„๋“œ๋ฅผ ํฌํ•จํ•˜๋Š” _private ๋ผ๋Š” ํ•„๋“œ๋ฅผ ๋งŒ๋“ค ๊ฒƒ์ž…๋‹ˆ๋‹ค. JPype๋Š” ๊ฐ ์œ ํ˜•์— ๋Œ€ํ•ด ํ•˜๋‚˜์˜ ํด๋ž˜์Šค ๋ž˜ํผ๋งŒ ์ œ๊ณตํ•˜๋ฏ€๋กœ ์„ธ๋ฐ€ํ•œ ์ œ์–ด ๋ฐฉ๋ฒ•์ด ๋ณ„๋กœ ์—†์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋น„๊ณต๊ฐœ ์•ก์„ธ์Šค ๊ถŒํ•œ์ด ์žˆ๋Š” ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“  ๋‹ค์Œ ๋™์ผํ•œ ์œ ํ˜•์˜ ๋‘ ๋ฒˆ์งธ ๊ฐœ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ๋น„๊ณต๊ฐœ๊ฐ€ ๋…ธ์ถœ๋˜์ง€ ์•Š๋„๋ก ์„ ํƒํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋ฌธ์ž์—ด ๋ณ€ํ™˜์œผ๋กœ ๊ทธ ๊ธธ์„ ๊ฐ”๊ณ  ์–ด๋–ค ๋„์„œ๊ด€์€ ํ•˜๋‚˜์˜ ์ •์ฑ…์„ ์„ ํƒํ•˜๊ณ  ๋‹ค๋ฅธ ๋„์„œ๊ด€์€ ๋‹ค๋ฅธ ์ •์ฑ…์„ ์„ ํƒํ•˜์—ฌ ๋น„ํ˜ธํ™˜์„ฑ์„ ์ดˆ๋ž˜ํ•˜๋Š” ์žฌ์•™์ด์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฐฐ์—ด ๋ชฉ๋ก์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ช‡ ๊ฐ€์ง€ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

import jpype
import timeit
jpype.startJVM()
ArrayList = jpype.JClass("java.util.ArrayList")

def pack():
    ja = ArrayList()
    for i in range(1000):
        ja.add(i)

def iter(ja):
    u = 0
    for i in ja:
        u+=i

def access(ja):
    u = 0
    for i in range(len(ja)):
        u+=ja.get(i)

def access2(ja):
    u = 0
    for i in range(len(ja)):
        u+=ja[i]


ja = ArrayList()
for i in range(1000):
   ja.add(i)

print("Pack arraylist %e"%( timeit.timeit("pack()", globals=globals(), number=1000)/1e6))
print("Iterate arraylist %e"%(timeit.timeit("iter(ja)", globals=globals(), number=1000)/1e6))
# Get is a direct call
print("Access(get) arraylist %e"%(timeit.timeit("access(ja)", globals=globals(), number=1000)/1e6))
# [] is emulated
print("Access([]) arraylist %e"%(timeit.timeit("access2(ja)", globals=globals(), number=1000)/1e6))

์ œ์ดํŒŒ์ด

ํŒฉ ๋ฐฐ์—ด ๋ชฉ๋ก 2.768904e-06
๋ฐฐ์—ด ๋ชฉ๋ก 5.208071e-06 ๋ฐ˜๋ณต
์•ก์„ธ์Šค(๊ฐ€์ ธ์˜ค๊ธฐ) ๋ฐฐ์—ด ๋ชฉ๋ก 4.037985e-06
์•ก์„ธ์Šค([]) ๋ฐฐ์—ด ๋ชฉ๋ก 4.690264e-06

์ฅฌ๋‹ˆ์šฐ์Šค

ํŒฉ ๋ฐฐ์—ด ๋ชฉ๋ก 3.322248e-06
๋ฐฐ์—ด ๋ชฉ๋ก 4.099314e-06 ๋ฐ˜๋ณต
์•ก์„ธ์Šค(๊ฐ€์ ธ์˜ค๊ธฐ) ๋ฐฐ์—ด ๋ชฉ๋ก 5.653444e-06
์•ก์„ธ์Šค([]) ๋ฐฐ์—ด ๋ชฉ๋ก 7.762727e-06

๋งค์šฐ ๋‹ค๋ฅธ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์ œ์™ธํ•˜๊ณ ๋Š” ์‚ฌ์†Œํ•˜๊ฒŒ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ ์™ธ์—๋Š” ๋งค์šฐ ์ผ๊ด€๋œ ์ด์•ผ๊ธฐ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ๋‹น์‹ ์ด ํ•˜๋Š” ๋ชจ๋“  ๊ฒƒ์ด ๋ฉ”์†Œ๋“œ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์ด๋ผ๋ฉด ๊ทธ๊ฒƒ๋“ค์€ ๊ฝค ๋น„์Šทํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. JPype๋กœ ์‚ฌ์ „ ๋ณ€ํ™˜๋œ ๋ฐฐ์—ด์„ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ 100๋ฐฐ ๋” ๋น ๋ฅด๋ฉฐ ๋ชฉ๋ก๊ณผ ํŠœํ”Œ์„ ๋ณ€ํ™˜ํ•˜๋Š” JPype๋Š” 2๋ฐฐ ๋” ๋Š๋ฆฝ๋‹ˆ๋‹ค(ํ˜„์žฌ ๋ฒกํ„ฐ ์•ก์„ธ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ํŠœํ”Œ์— ๋Œ€ํ•œ ํŠน์ˆ˜ ์šฐํšŒ๊ฐ€ ์žˆ์Œ). ๋”ฐ๋ผ์„œ ๊ฒฐ๋ก ์€ ์ฝ”๋”ฉ ์Šคํƒ€์ผ์— ๋”ฐ๋ผ ์–ด๋Š ์ชฝ์ด ํ›จ์”ฌ ๋น ๋ฅผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚ด ์‚ฌ์šฉ์ž๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์†๋„๋ณด๋‹ค๋Š” ์‚ฌ์šฉ ํŽธ์˜์„ฑ๊ณผ ๋ฐฉํƒ„ ๊ตฌ์„ฑ์„ ์œ„ํ•ด JPype๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. (์•„ ๋†๋‹ด์ด์•ผ! JPype๊ฐ€ ์šฐ์—ฐํžˆ Google์—์„œ ์ฐพ์€ ์ฒซ ๋ฒˆ์งธ ๋งํฌ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ธํ„ฐ๋„ท์—์„œ ์šฐ์—ฐํžˆ ๋ฐœ๊ฒฌํ–ˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ํฝ๋‹ˆ๋‹ค.)

JPype๊ฐ€ ๋ฉ”์†Œ๋“œ ๋ฐ”์ธ๋”ฉ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ๋Š” ๊ฐœ๋ฐœ์ž/์‚ฌ์šฉ์ž ๊ฐ€์ด๋“œ์— ์„ธ๋ถ€์‚ฌํ•ญ์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์†Œ๋“œ ๋ฐ”์ธ๋”ฉ์€ Java ์‚ฌ์–‘์— ์ œ๊ณต๋œ ๊ทœ์น™์— ๋”ฐ๋ผ ๋””์ŠคํŒจ์น˜์— ๋Œ€ํ•œ ๋ฉ”์†Œ๋“œ ๋ชฉ๋ก์„ ์‚ฌ์ „ ์ •๋ ฌํ•˜์—ฌ ์‹œ์ž‘ํ•˜์—ฌ ๋ฌด์–ธ๊ฐ€๊ฐ€ ๋‹ค๋ฅธ ๊ฒƒ์„ ์ˆจ๊ธฐ๋ฉด ๋ชฉ๋ก์—์„œ ๋จผ์ € ํ‘œ์‹œ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค(์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด native/java/org/jpype์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋””์ŠคํŒจ์น˜๊ฐ€ ์ฒ˜์Œ ์ƒ์„ฑ๋  ๋•Œ ์ •๋ ฌ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด Java ์œ ํ‹ธ๋ฆฌํ‹ฐ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉ). ๋˜ํ•œ ๊ฐ ๋ฐฉ๋ฒ•์—๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์ˆจ๊ธฐ๋Š” ๊ธฐ๋ณธ ์„ค์ • ๋ชฉ๋ก์ด ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ํ•ด๊ฒฐ์€ ๋จผ์ € ๊ฐ ์ธ์ˆ˜๋ฅผ ํ™•์ธํ•˜์—ฌ ์ธ์ˆ˜์— ๋Œ€ํ•œ "Java ์Šฌ๋กฏ"์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. Java ์Šฌ๋กฏ์€ ๋ณ€ํ™˜์ด ํ•„์š” ์—†๋Š” ๊ธฐ์กด ๊ฐœ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋ฏ€๋กœ ์ผ์น˜ํ•˜๊ธฐ ์ „์— ์ด๋Ÿฌํ•œ ๊ฐœ์ฒด๋ฅผ ์ œ๊ฑฐํ•˜๋ฉด ์•”์‹œ์  ๊ทœ์น™์ด ์•„๋‹Œ ์ง์ ‘ ๊ทœ์น™์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์œ ํ˜•์— ๋”ฐ๋ผ ์ธ์ˆ˜๋ฅผ 4๋‹จ๊ณ„(์ •ํ™•, ์•”์‹œ์ , ๋ช…์‹œ์ , ์—†์Œ)๋กœ ์ผ์น˜์‹œํ‚ต๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ฉ”์„œ๋“œ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ ์œ„ํ•ด ๋ช…์‹œ์  ๋ฐ ์—†์Œ์— ๋Œ€ํ•œ ๋ฐ”๋กœ ๊ฐ€๊ธฐ์ž…๋‹ˆ๋‹ค. ์ •ํ™•ํ•œ ์ •๋ณด๋ฅผ ์–ป์œผ๋ฉด ์ „์ฒด ํ”„๋กœ์„ธ์Šค๋ฅผ ๋‹จ์ถ•ํ•˜์—ฌ ํ˜ธ์ถœ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. ์ผ์น˜ํ•˜๋Š” ํ•ญ๋ชฉ์ด ์žˆ์œผ๋ฉด ๋œ ๊ตฌ์ฒด์ ์ธ ๋ฐ”์ธ๋”ฉ์ด ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ˆจ๊น๋‹ˆ๋‹ค. ์ˆจ๊ฒจ์ง€์ง€ ์•Š์€ ๋‘ ๊ฐœ์˜ ์•”์‹œ์  ์ผ์น˜ ํ•ญ๋ชฉ์ด ๋ฐœ๊ฒฌ๋˜๋ฉด TypeError๊ฐ€ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์ผ์น˜ ํ•ญ๋ชฉ์ด ์†Œ์ง„๋˜๋ฉด ๋ณ€ํ™˜ ๋ฃจํ‹ด์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ Python ์ „์—ญ ์ž ๊ธˆ์„ ํ•ด์ œํ•˜๊ณ  ํ˜ธ์ถœํ•˜๊ณ  ์ „์—ญ ์ž ๊ธˆ์„ ๋‹ค์‹œ ํš๋“ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜ ์œ ํ˜•์ด ์กฐํšŒ๋˜๊ณ  ๋ฐ˜ํ™˜๋œ ์œ ํ˜•์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒˆ Python ๋ž˜ํผ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค(๊ณต๋ณ€ ๋ฐ˜ํ™˜์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ๋ฐ˜ํ™˜๋œ ์œ ํ˜•์ด ๋ฉ”์„œ๋“œ์˜ ์œ ํ˜•์ด ์•„๋‹ˆ๋ผ ๊ฐ€์žฅ ๋งŽ์ด ํŒŒ์ƒ๋จ). ๊ฐ€๋ณ€ ์ธ์ˆ˜์— ๋Œ€ํ•œ ์•ฝ๊ฐ„์˜ ๋ณต์žก์„ฑ์ด ์žˆ์ง€๋งŒ ์‚ฌ์ „ ๊ตฌ์„ฑ๋œ ํ…Œ์ด๋ธ”์€ foo(double, double)๋ฅผ ์‹œ๋„ํ•˜๊ธฐ ์ „์— foo(long, long)๋ฅผ ์‹œ๋„ํ•˜๊ณ  (long , long)์€ Java ๋ฉ”์†Œ๋“œ ํ™•์ธ ๊ทœ์น™์œผ๋กœ ์ธํ•ด ๋ชจ๋“  ์ผ์น˜ ํ•ญ๋ชฉ์—์„œ double, double์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ์†๋„ ํ–ฅ์ƒ์ด ์žˆ์ง€๋งŒ ์ถ”๊ฐ€ ์บ์‹ฑ ํ…Œ์ด๋ธ”์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

2017๋…„์— ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•  ๋•Œ ๋ฐ”๋กœ ๊ฐ€๊ธฐ๊ฐ€ ์žˆ๋Š” ์ฃผ๋ฌธ ์‹œ์Šคํ…œ์„ ์ƒ์†๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. ์˜ค๋ฒ„ํ—ค๋“œ์˜ ๋Œ€๋ถ€๋ถ„์„ ๋ฐ€์–ด๋‚ด๊ธฐ ์œ„ํ•ด ์บ์‹œ์™€ ์ž๋ฐ” ์Šฌ๋กฏ์„ ์ˆจ๊ธฐ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฉ”์„œ๋“œ์˜ ์‹คํ–‰ ๊ฒฝ๋กœ๋ฅผ ์ตœ์ ํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค. JPype์˜ ์ˆ˜์ •๋œ ์ˆซ์ž๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

ํŒฉ ๋ฐฐ์—ด ๋ชฉ๋ก 2.226081e-06
๋ฐฐ์—ด ๋ชฉ๋ก 4.082152e-06 ๋ฐ˜๋ณต
์•ก์„ธ์Šค(๊ฐ€์ ธ์˜ค๊ธฐ) ๋ฐฐ์—ด ๋ชฉ๋ก 2.962606e-06
์•ก์„ธ์Šค([]) ๋ฐฐ์—ด ๋ชฉ๋ก 3.644642e-06

๋‚ด ๋กœ์ปฌ ์‚ฌ์šฉ์ž ๊ทธ๋ฃน์€ ๋ชจ๋‘ ๊ณผํ•™์ž์ด๋ฏ€๋กœ ์ง„์ž…์ ์€ ๋ชจ๋‘ ๋งค์šฐ ๋”์ฐํ•œ ๊ต์ฐจ ๋ฐฐ์„ ์œผ๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธ๋ฉ๋‹ˆ๋‹ค. ์–ด๋–ค ๊ฒƒ์ด ๊ทธ๋“ค์—๊ฒŒ ์„ธ๊ทธํดํŠธ(segfaults)๊ฐ€ ์žˆ๋‹ค๋ฉด(์•„๋ฌด๋ฆฌ ๋ฏธ์ณค์–ด๋„), ๋‚˜๋Š” ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ, segfaults๋Š” ๋”์ฐํ•˜๋ฉฐ pyjnius๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์„ ๋•Œ ์ˆ˜๋ฐฑ ๊ฐœ์˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์•„๋งˆ๋„ ์•ˆ์ „ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ๋‚ด ์ฝ”๋“œ์— ๋‚ด์žฅํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์˜ค๋žซ๋™์•ˆ ์•„๋ฌด ๊ฒƒ๋„ ์–ป์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ๋ชจ๋“  ๊ฒƒ์ด ์•ˆ์ •์ ์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹น์‹ ์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค์–‘ํ•œ Java ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋ฐ์ดํ„ฐ ๋ถ„์„์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด Java ๊ฐ์ฒด๋กœ ์ง์ ‘ ์ž‘์—…ํ•˜๋Š” ๊ณผํ•™์ž์ธ ๊ฒฝ์šฐ segfault๋กœ ์ธํ•ด ๋ชจ๋“  ์ž‘์—…์ด ์†์‹ค๋ฉ๋‹ˆ๋‹ค. JPype๋Š” ์ตœ์ข… ์‚ฌ์šฉ์ž๊ฐ€ Python์„ ํ†ตํ•ด Java ๊ฐ์ฒด๋กœ ์ง์ ‘ ์ž‘์—…ํ•˜๋Š” ๊ณผํ•™ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐ ๋” ์ ํ•ฉํ•ด ๋ณด์ž…๋‹ˆ๋‹ค. pyjnius์˜ ์ฃผ์š” ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” Android์™€ ํ†ต์‹ ํ•˜๋Š” ๊ฒƒ๊ณผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์•ˆ์ „ ๋ฌธ์ œ๋Š” ๊ฐœ๋ฐœ์ž์˜ ๋ฌธ์ œ์ด๋ฏ€๋กœ ์•ˆ์ „ ๋Œ€ ์†๋„์— ๋Œ€ํ•ด ๋‹ค๋ฅธ ์„ ํƒ์„ ํ•˜๋Š” ๊ฒƒ์ด ์ ์ ˆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” "๋‹น์‹ ์ด ์ด ์ˆœ์„œ๋Œ€๋กœ ์ด ์‚ฌ๊ฐํ˜•์„ ๋ฐŸ๋Š” ํ•œ ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค"์˜ ์—ด๋ ฌํ•œ ํŒฌ์ด ์•„๋‹˜์„ ์ธ์ •ํ•ฉ๋‹ˆ๋‹ค. JPype ์ž‘์—…์„ ์‹œ์ž‘ํ–ˆ์„ ๋•Œ ๋กœ์ปฌ ๊ทธ๋ฃน์— ์ฝ”๋“œ๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์„ ๋งŒํผ ๋ชจ๋“  ์ง„์ž…์ ์„ ๋ฐฉํƒ„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ๊ฑฐ์˜ 1๋…„์ด ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์ดํ›„๋กœ 2๋…„์˜ API ์•„๋จธ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. JVM์ด ๋กœ๋“œ๋˜์ง€ ์•Š๋Š”(ํ•ด๊ฒฐํ•˜๊ธฐ ๋งค์šฐ ์–ด๋ ค์šด) ์†Œ์ˆ˜์˜ ๋“œ๋ฌธ ์‚ฌ๋žŒ๋“ค์„ ์ œ์™ธํ•˜๊ณ ๋Š” JPype๊ฐ€ ํ”„๋กœ๋•์…˜ ์ฝ”๋“œ ํ‘œ์ค€์œผ๋กœ ์˜ฌ๋ผ์™”๊ธฐ ๋•Œ๋ฌธ์— ๋‚จ์•„ ์žˆ๋Š” ๋ฌธ์ œ๊ฐ€ ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค.

์†๋„์™€ ์•ˆ์ „์˜ ์ ˆ์ถฉ์— ๊ด€ํ•ด์„œ๋Š” ์†๋„๋Š” ํ›Œ๋ฅญํ•˜์ง€๋งŒ ์•ˆ์ „ํ•œ ์ž‘์—…์„ ์†Œํ™€ํžˆ ํ•˜์—ฌ ์†๋„๋ฅผ ์–ป๊ณ  ์žˆ๋‹ค๋ฉด ์ผ๋ฐ˜์ ์œผ๋กœ ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ข‹์ง€ ์•Š์€ ๊ฑฐ๋ž˜์ž…๋‹ˆ๋‹ค. ํ”„๋กœํ† ํƒ€์ดํ•‘ ์ฝ”๋“œ๋ฅผ ๋Œ๋ฆฌ๋“  ํ”„๋กœ๋•์…˜ ์‹œ์Šคํ…œ์„ ์ž‘์„ฑํ•˜๋“  ์ž‘์—…์„ ์ค‘๋‹จํ•˜๊ณ  segfault๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๊ณ  ์‹œ๋„ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ ์‚ฌ์šฉ์ž๊ฐ€ ์ง๋ฉดํ•ด์„œ๋Š” ์•ˆ ๋˜๋Š” ์ฃผ์˜๋ฅผ ์‚ฐ๋งŒํ•˜๊ฒŒ ํ•˜๋Š” ์ผ์ž…๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€๊ฐ€ Android ์—๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ JPype๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์˜ˆ๋ฅผ ๊ธฐ๊บผ์ด ์ œ๊ณตํ•œ๋‹ค๋ฉด ํ•„์š”ํ•œ ์ˆ˜์ • ์ž‘์—…์— ๋Œ€ํ•ด ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Android์—์„œ ์‚ฌ์šฉํ•˜๋ ค๋ฉด pyjnius๋ฅผ python-for-android์— ์˜ํ•ด ๋นŒ๋“œ๋œ Python ๋ฐฐํฌํŒ์˜ ์˜ˆ์ˆ ๋กœ ํŒจํ‚ค์ง•ํ•˜๊ณ (์ข…์ข… buildozer๋ฅผ ๋” ์‰ฌ์šด ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์‚ฌ์šฉํ•˜์ง€๋งŒ ๋™์ผํ•จ) ์ด ๋ฐฐํฌํŒ์„ ์ œ๊ณตํ•˜๋Š” Python ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋นŒ๋“œํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด python ์ฝ”๋“œ๋Š” pyjnius ๋˜๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์•ฑ์„ ์‹คํ–‰ํ•  ๋•Œ python ๋ฐฐํฌํŒ์— ๋นŒ๋“œ๋œ ๋‹ค๋ฅธ python ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„๋Š” ๋ฐฐํฌํŒ์—์„œ jpype๋ฅผ ์ปดํŒŒ์ผํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์š”๊ตฌ ์‚ฌํ•ญ์˜ ์ผ๋ถ€๋ผ๊ณ  ๋งํ•  ๋•Œ p4a(https://github.com/kivy/python-for-android/)์— ์˜ํ•ด ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•ญ์ƒ ๊ทธ๋Ÿฐ ๊ฒƒ์€ ์•„๋‹˜) "๋ ˆ์‹œํ”ผ"๋Š” p4a์— ์ˆœ์ˆ˜ ํŒŒ์ด์ฌ์ด ์•„๋‹Œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋นŒ๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. pyjnius์šฉ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” https://github.com/kivy/python-for-android/blob/ ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด p4a.local_recipes ์— ์„ค์ • buildozer.spec ๋‹น์‹ ์ด ํฌํฌ์— ํŒŒ์ด์ฌ๋ฅผ ์œ„ํ•ด ์•ˆ๋“œ๋กœ์ด๋“œ๋ฅผ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค, ์š”๊ตฌ ์‚ฌํ•ญ์— ๋Œ€ํ•œ ์กฐ๋ฆฌ๋ฒ•์„ ์ฐพ์„ ์ˆ˜์žˆ๋Š” ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์„ ์–ธ ๋‹น์‹ ์˜ ์กฐ๋ฆฌ๋ฒ•์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

https://buildozer.readthedocs.io/en/latest/installation.html#targeting -android ๋” ๋งŽ์€ ์ž‘์—…์„ ์ž๋™ํ™”ํ•˜๊ณ  ์—ฌ์ „ํžˆ ๋กœ์ปฌ ๋ ˆ์‹œํ”ผ๋ฅผ ์„ค์ •ํ•˜์—ฌ ์‹œ๋„ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ buildozer๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋นŒ๋“œ๋Š” python๊ณผ arm์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ ์ข…์†์„ฑ์„ ๋นŒ๋“œํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋ฉฐ, ์ด๋ฅผ ์œ„ํ•œ Android ndk ๋ฐ sdk๋ฅผ ๋‹ค์šด๋กœ๋“œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์•ฑ์— ๊ธฐ๋ณธ kivy ๋ถ€ํŠธ์ŠคํŠธ๋žฉ์„ ์‚ฌ์šฉํ•˜๊ณ  jpype๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ๋ ˆ์ด๋ธ”์— ์ผ๋ถ€ ์ฝ”๋“œ์˜ ๊ฒฐ๊ณผ๋ฅผ ํ‘œ์‹œํ•˜๊ฑฐ๋‚˜ ์‹ฌ์ง€์–ด ์ธ์‡„๋ฅผ ์‚ฌ์šฉํ•˜๋Š” logcat์— ํ‘œ์‹œํ•˜๋Š” ์•ฑ๊ณผ ๊ฐ™์€ "hello world"๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. kivy๊ฐ€ ์•ˆ๋“œ๋กœ์ด๋“œ ์—๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ์–ผ๋งˆ๋‚˜ ์ž˜ ์‹คํ–‰๋˜๋Š”์ง€ ๊ธฐ์–ตํ•˜์‹ญ์‹œ์˜ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ์ผ๋ถ€ ์‚ฌ์šฉ์ž๋Š” ๊ทธ๋ ‡๊ฒŒํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€์† ์„ค์ •์œผ๋กœ ์ž‘๋™ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. afaik, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด sdl2 ๋ž˜ํผ ๋˜๋Š” webview๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ  ํ”Œ๋ผ์Šคํฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณ‘ ์„œ๋ฒ„๊ฐ€ ๋ฌผ๊ฑด์„ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ€์žฅ ๋จผ์ € ํ…Œ์ŠคํŠธ๋ฅผ ๊ฑฐ์นœ ํ‚ค๋น„ ์„œ๋ฒ„๋กœ ๋จผ์ € ์‹œ๋„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Android์šฉ์œผ๋กœ ๋นŒ๋“œํ•˜๋ ค๋ฉด Linux ๋˜๋Š” osx ๋จธ์‹ (VM์€ ๊ดœ์ฐฎ๊ณ  Windows 10์˜ WSL์€ ๊ดœ์ฐฎ์Œ)์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

python-for-android์šฉ jpype ๋ ˆ์‹œํ”ผ ์ž‘์—…์„ ์‹œ์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ ๋…ผ์˜๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋„๋ก ์ง„ํ–‰ ์ค‘์ธ PR์„ ์—ฌ๋Š” ๊ฒƒ์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค. ์ž‘๋™ํ•œ๋‹ค๋ฉด ํŠนํžˆ ์˜ค๋ž˜ ์ง€์†๋˜์–ด์˜จ pyjnius ์ œํ•œ ์‚ฌํ•ญ์„ ์‹ค์ œ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์Šค๋ ˆ๋“œ์˜ ์•ž๋ถ€๋ถ„์—์„œ ๋…ผ์˜ํ•œ ๋ฐ”์™€ ๊ฐ™์ด, pyjnius๋Š” ๋ณธ์งˆ์ ์œผ๋กœ kivy ์‚ฌ์šฉ์— ๋Œ€ํ•œ ํ•ต์‹ฌ ์š”๊ตฌ ์‚ฌํ•ญ์„ ๋‹ค๋ฃจ์ง€๋งŒ, ์ด๋ฅผ ํ›จ์”ฌ ๋›ฐ์–ด๋„˜์„ ๋งŒํผ ์ถฉ๋ถ„ํ•œ ๊ฐœ๋ฐœ ๋Šฅ๋ ฅ์ด ์—†์Šต๋‹ˆ๋‹ค.

@inclement jpype-project/jpype#799์—์„œ Android ํฌํŠธ์— ๋Œ€ํ•œ PR์„ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ถˆํ–‰ํžˆ๋„, ๋‚˜๋Š” ์—ฌ๊ธฐ์—์„œ ์–ด๋””๋กœ ๊ฐ€์•ผํ• ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์˜ฌ๋ฐ”๋ฅธ ๋นŒ๋“œ ๊ฒฝ๋กœ๊ฐ€ ์•„๋‹Œ gradle์„ ์‹คํ–‰ํ•˜๋ ค๊ณ ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ˆ˜ํ–‰ํ•ด์•ผ ํ•  ์กฐ์น˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • [x] ๋ชจ๋“  jpype/*.py ํŒŒ์ผ์„ ๋นŒ๋“œ(๋˜๋Š” ์‚ฌ์ „ ์ปดํŒŒ์ผ๋œ ๋ฒ„์ „)์— ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  • [x] native/build.xml์—์„œ Apache ant๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๊ฒฐ๊ณผ jar ํŒŒ์ผ์„ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ์œ„์น˜์— ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค.
  • [x] ๋นŒ๋“œ์— jar ํŒŒ์ผ(๋˜๋Š” ์ด์— ์ƒ์‘ํ•˜๋Š” ํŒŒ์ผ)์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  • [x] native/common ๋ฐ native/python์˜ C++ ์ฝ”๋“œ๋ฅผ ๋นŒ๋“œ์— ํฌํ•จํ•  _jpype๋ผ๋Š” ๋ชจ๋“ˆ๋กœ ์ปดํŒŒ์ผํ•ฉ๋‹ˆ๋‹ค.
  • [x] ์ง€๊ธˆ์€ ์ˆ˜๋™์œผ๋กœ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋„๋ก ๋Œ€ํ™”ํ˜• ์…ธ์„ ์‹œ์ž‘ํ•˜๋Š” main.py ํŒŒ์ผ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  • [ ] ์•ž์œผ๋กœ ๋™์ ์œผ๋กœ ์ƒ์„ฑ๋œ ํด๋ž˜์Šค๋ฅผ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋„๋ก "ASM" ๋˜๋Š” Android์šฉ์œผ๋กœ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ๊ณผ ์œ ์‚ฌํ•œ ๊ฒƒ์„ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • [x] ์‚ฌ์šฉ์ž ์ง€์ • ๋ถ€ํŠธ์ŠคํŠธ๋žฉ์„ ์‚ฌ์šฉํ•˜์—ฌ JVM ๋ฐ ๋„์šฐ๋ฏธ jar ํŒŒ์ผ์„ ๋กœ๋“œํ•˜๊ณ  ๋ชจ๋“  ๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ๋ฅผ ์—ฐ๊ฒฐํ•˜๋„๋ก C++ ์ฝ”๋“œ๋ฅผ ํŒจ์น˜ํ•ฉ๋‹ˆ๋‹ค.
  • [ ] jvmfinder๋ฅผ android์—์„œ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ํŒจ์น˜ํ•˜๊ณ  "startJVM"์ด ๋ฉ”์ธ ์‹œ์ž‘ ๋ถ€๋ถ„์ด ์•„๋‹ˆ๋ผ ์ž๋™์œผ๋กœ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
  • [ ] jar ํƒ์ƒ‰ ์‹œ์Šคํ…œ(๊ฐ€์ ธ์˜ค๊ธฐ๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹)์ด Android์—์„œ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ๋„๋ก org.jpype๋ฅผ ํŒจ์น˜ํ•ฉ๋‹ˆ๋‹ค.

์ผ๋ถ€ ๋ฌธ์„œ๋ฅผ ์‚ดํŽด๋ณด์•˜์ง€๋งŒ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋ˆˆ์— ๋„๋Š” ๊ฒƒ์€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ํ”„๋กœ์ ํŠธ ๋ ˆ์ด์•„์›ƒ์€ ๊ธฐ๋ณธ ๋ชจ๋“ˆ ์•„๋ž˜์— ๋ชจ๋“  ๊ฒƒ์„ ๋„ฃ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํ‰์†Œ์™€ ๋‹ค์†Œ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ชจ๋“  ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  gradle ์‹คํ–‰๊ณผ ๊ฐ™์€ ๋ฐ”๋žŒ์งํ•˜์ง€ ์•Š์€ ํŒจํ„ด์„ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค(๋‚ด๊ฐ€ ๋งํ•  ์ˆ˜ ์—†๋Š” ์œ ์šฉํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๋Š” ํ•œ).

์‹ค์ œ๋กœ ์˜ฌ๋ฐ”๋ฅธ ๋นŒ๋“œ ๊ฒฝ๋กœ๊ฐ€ ์•„๋‹Œ gradle์„ ์‹คํ–‰ํ•˜๋ ค๊ณ ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Gradle์€ APK ํŒจํ‚ค์ง•์˜ ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„๋กœ ์‚ฌ์šฉ๋˜๋Š” ๋นŒ๋“œ ๋„๊ตฌ์ด๋ฉฐ ์•„๋งˆ๋„ jpype๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ๊ณผ ๊ด€๋ จ์ด ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  jpype/*.py ํŒŒ์ผ์„ ๋นŒ๋“œ(๋˜๋Š” ์‚ฌ์ „ ์ปดํŒŒ์ผ๋œ ๋ฒ„์ „)์— ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ jpype๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ผ๋ฐ˜ Python ๋ชจ๋“ˆ๋กœ ์ˆ˜ํ–‰๋˜๋Š” ๊ฒฝ์šฐ ์ฒซ ๋ฒˆ์งธ ๋ ˆ์‹œํ”ผ ์‹œ๋„๋Š” ์•„๋งˆ๋„ ๋Œ€๋ถ€๋ถ„์˜ ์–ด๋ ค์šด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. CppCompiledComponentsPythonRecipe ๋Š” python setup.py build_ext ๋ฐ python setup.py install ์‹คํ–‰๊ณผ ๊ฐ™์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. NDK ํ™˜๊ฒฝ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์•ฑ ๋‚ด๋ถ€์— ํฌํ•จํ•˜๊ธฐ ์œ„ํ•ด ๋นŒ๋“œ๋˜๋Š” Python ํ™˜๊ฒฝ ๋‚ด์— jpype python ํŒจํ‚ค์ง€๊ฐ€ ์„ค์น˜๋ฉ๋‹ˆ๋‹ค.

๋นŒ๋“œ์— jar ํŒŒ์ผ(๋˜๋Š” ์ด์— ์ƒ์‘ํ•˜๋Š” ํŒŒ์ผ)์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์•„๋งˆ๋„ ๋ ˆ์‹œํ”ผ๊ฐ€ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š” ์ถ”๊ฐ€ ๋‹จ๊ณ„์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” python-for-android๊ฐ€ ๋นŒ๋“œ ์ค‘์ธ Android ํ”„๋กœ์ ํŠธ ๋‚ด์˜ ์ ์ ˆํ•œ ์œ„์น˜์— jar ํŒŒ์ผ(๋˜๋Š” ํ•„์š”ํ•œ ๋ชจ๋“  ๊ฒƒ)์„ ๋ณต์‚ฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

native/common ๋ฐ native/python์˜ C++ ์ฝ”๋“œ๋ฅผ ๋นŒ๋“œ์— ํฌํ•จํ•  _jpype๋ผ๋Š” ๋ชจ๋“ˆ๋กœ ์ปดํŒŒ์ผํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด setup.py์— ์˜ํ•ด ์ฒ˜๋ฆฌ๋œ๋‹ค๋ฉด ์ด๊ฒƒ์€ ์ด๋ฏธ ์ž‘๋™ํ•˜๊ณ  ์žˆ์ง€๋งŒ ์•ฝ๊ฐ„์˜ ์กฐ์ •์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋ ˆ์‹œํ”ผ์— ์ปดํŒŒ์ผ ๋ช…๋ น์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๋‹ค๋ฅธ ๋ ˆ์‹œํ”ผ์—์„œ self.get_env ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์™„๋ฃŒ๋จ์„ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด ์ ์ ˆํ•œ env ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜์—ฌ Android ํ™˜๊ฒฝ์šฉ์œผ๋กœ ๋นŒ๋“œํ•˜๋„๋ก ํ•จ).

์‚ฌ์šฉ์ž ์ •์˜ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ์„ ์‚ฌ์šฉํ•˜์—ฌ JVM ๋ฐ ์ปดํŒจ๋‹ˆ์–ธ jar ํŒŒ์ผ์„ ๋กœ๋“œํ•˜๊ณ  ๋ชจ๋“  ๊ธฐ๋ณธ ๋ฉ”์†Œ๋“œ๋ฅผ ์—ฐ๊ฒฐํ•˜๋„๋ก C++ ์ฝ”๋“œ๋ฅผ ํŒจ์น˜ํ•ฉ๋‹ˆ๋‹ค.

์˜ฌ๋ฐ”๋ฅธ Android JNI ์ธํ„ฐํŽ˜์ด์Šค ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์— ๋”ฐ๋ผ ์ด ๋ถ€๋ถ„์ด ์ƒ๋‹นํžˆ ๊ฐ„๋‹จํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ด ํŒจ์น˜ ์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด ๋‹ค๋ฅธ ๋„์šฐ๋ฏธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋‹ค๋ฅธ ๋žฉํ”„๋ ˆ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ ์ ˆํ•œ ์กฐ๊ฑด๋ถ€ ์ปดํŒŒ์ผ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋Œ€์‹  pyjnius๋ฅผ ํŒจ์น˜ํ•˜์—ฌ ์•ฝ๊ฐ„ ํ•ดํ‚น๋œ ๋ฐฉ์‹์œผ๋กœ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰

jvmfinder๋ฅผ android์—์„œ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ํŒจ์น˜ํ•˜๊ณ  "startJVM"์€ main์ด ์‹œ์ž‘๋  ๋•Œ๊ฐ€ ์•„๋‹ˆ๋ผ ์ž๋™์œผ๋กœ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

JVM์— ๋Œ€ํ•ด ์ž˜ ์•Œ์ง€๋Š” ๋ชปํ•˜์ง€๋งŒ Android๋Š” ํ•ญ์ƒ ๊ธฐ์กด jvm์— ์•ก์„ธ์Šคํ•˜๊ธฐ๋ฅผ ์›ํ•˜๊ณ  ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒŒ ๋ฌธ์ œ๊ฐ€ ๋ ๊นŒ์š”(์•„๋‹ˆ๋ฉด ๊ทธ๋ƒฅ ์ž˜๋ชป๋œ ๊ฑด๊ฐ€์š”?)?

native/build.xml์—์„œ Apache ant๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๊ฒฐ๊ณผ jar ํŒŒ์ผ์„ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ์œ„์น˜์— ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค.

์ต์ˆ™ํ•˜์ง€ ์•Š์•„์„œ ์ด๊ฒƒ์— ๋Œ€ํ•ด์„œ๋„ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‹จ์ง€ ๋‚ด๋ถ€ jpype ๋นŒ๋“œ ๋‹จ๊ณ„์ž…๋‹ˆ๊นŒ? Java ๋ฒ„์ „์ด ์–ด๋–ป๊ฒŒ ์ƒํ˜ธ ์ž‘์šฉํ•˜๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ ์—ฌ๊ธฐ์—์„œ๋Š” ์‹œ์Šคํ…œ ๋„ค์ดํ‹ฐ๋ธŒ ๊ฐœ๋ฏธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

buildozer๊ฐ€ setup.py๋ฅผ ์กด์ค‘ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒฝ๊ณ ๋ฅผ ํ‘œ์‹œํ•˜๋ฏ€๋กœ ๋งจ ์œ„์—์„œ gradle ๋‹จ๊ณ„๋กœ ์ง์ ‘ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ ์ค‘๊ฐ„ ๋‹จ๊ณ„๋ฅผ ์ˆ˜๋™์œผ๋กœ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ setup.py๋Š” jar ํŒŒ์ผ์„ dll๊ณผ ๋ณ‘ํ•ฉํ•˜๊ธฐ ์œ„ํ•ด ํ›„ํฌ ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋งŽ์€ ์‚ฌ์šฉ์ž ์ •์˜ ์ปดํŒŒ์ผ ๋‹จ๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋‹จ๊ณ„๋Š” ์—ฌ๊ธฐ์— ์ ์šฉ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๊ฑด๋„ˆ๋›ฐ์–ด๋„ ๊ดœ์ฐฎ์•˜์ง€๋งŒ cpp ๋ฐ Java ํŒŒ์ผ๋„ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. setup.py์— ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ์˜ ์ผ๋ถ€๋Š” ๋‚ด setup.py๊ฐ€ ๋„ˆ๋ฌด ์ปค์„œ setupext ๋ชจ๋“ˆ๋กœ ๋ถ„ํ• ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋จผ์ € ํ”„๋กœ์„ธ์Šค๋ฅผ ํ•œ ๋ฒˆ ์‹คํ–‰ํ•˜๊ณ  ๋กœ๊ทธ๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ๋„๋ก clean ๋ช…๋ น์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. (๋‚˜๋Š” ํ”Œ๋ ˆ์ดํ•˜๋ฉด์„œ ์ฒ˜์Œ์œผ๋กœ ์กฐ๊ฐ ์‹์‚ฌ๋ฅผ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊นจ๋—ํ•œ ๋กœ๊ทธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.) ๋˜ํ•œ ์šฐ๋ฆฌ๋Š” ์ด ๋Œ€ํ™”๋ฅผ PR๋กœ ์˜ฎ๊ฒจ์„œ ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•œ ์ฃผ์ œ์— ๋” ๋จธ๋ฌผ ์ˆ˜ ์žˆ๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

FWIW Android๊ฐ€ ์•„๋‹Œ ํ”„๋กœ์ ํŠธ์˜ ํ•ต์‹ฌ์„ JPype๋กœ ์ด์‹ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋‘ ๊ฐ€์ง€ ์‚ฌ์†Œํ•œ ์–ด๋ ค์›€์ด๋‚˜ ์ฐจ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  1. classpath ์—์„œ kwarg jpype.startJVM() ์ƒ๊ด€์—†์ด ๋‚ด๊ฐ€ ๋ญ˜ ๋ฌด์‹œ ๊ฒƒ์œผ๋กœ ๋ณด์ธ๋‹ค. ํ•˜์ง€๋งŒ addClassPath() ๊ธฐ๋Šฅ์€ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. ํด๋ž˜์Šค ๊ฒฝ๋กœ ์ˆœ์„œ์— ๊ด€์‹ฌ์ด ์žˆ๋Š” ๊ฐœ๋ฐœ์ž๋Š” jnius_config.add_classpath() ์‚ฌ์šฉ ๋ฐฉ์‹๊ณผ ๋น„๊ตํ•˜์—ฌ ์•ฝ๊ฐ„์˜ ์กฐ์ •์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  2. Java ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„์€ ํ›Œ๋ฅญํ•˜๊ฒŒ ์ž‘๋™ํ•˜์ง€๋งŒ ์•ฝ๊ฐ„ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๋‚ด ์ฝ”๋“œ์—๋Š” Python ๋ฌธ์ž์—ด ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋Œ์ด์ผœ๋ณด๋ฉด ์•„๋งˆ ๊ฐ ๋ฌธ์ž์—ด์„ Java ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ–ˆ์–ด์•ผ ํ–ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‚˜๋Š” ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜์ง€ ์•Š์•˜๊ณ  ์ธํ„ฐํŽ˜์ด์Šค ํ•จ์ˆ˜ ์ •์˜๊ฐ€ ์ด๊ฒƒ์ด ์ž‘๋™ํ•˜๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด Java ๊ฐ์ฒด ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” pyjnius์—์„œ ์ž˜ ์ž‘๋™ํ•˜์—ฌ python ๋ฌธ์ž์—ด์„ Java ๊ฐ์ฒด์˜ ํ•˜์œ„ ํด๋ž˜์Šค๋กœ ํšจ๊ณผ์ ์œผ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค. JPype์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์ง€๋งŒ JPype์˜ JString ํด๋ž˜์Šค๋กœ ๋ฌธ์ž์—ด์„ ๋ณ€ํ™˜ํ•˜์—ฌ ์‰ฝ๊ฒŒ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ตฌํ˜„๋œ ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•ด @JOverride ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์€ @java_method('(Ljava/lang/String;[Ljava/lang/Object;)V') ์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ณด๋‹ค ํ›จ์”ฌ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

์ด ๋‘ ๊ฐ€์ง€ ๋ฌธ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์ž˜ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๋Š” ๋ฐ”์ดํŠธ ๋ฐฐ์—ด์„ ์ „๋‹ฌํ•˜๋Š” ์ผ๋ถ€ ์ฝ”๋“œ๊ฐ€ ์žˆ์ง€๋งŒ JPype๋Š” ์ด๋ฅผ ์ž˜ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ JPype์˜ ์•”์‹œ์  ์œ ํ˜• ๋ณ€ํ™˜์€ ๋งค์šฐ ํŽธ๋ฆฌํ•˜๋ฉฐ ์—ฌ๊ธฐ์ €๊ธฐ ๋ฟŒ๋ ค์•ผ ํ–ˆ๋˜ ๋งŽ์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@Thrameos ์—ฌ๊ธฐ์—์„œ ๋‹น์‹ ์˜ ๊ฒฐ๋‹จ์„ ์กด์ค‘ํ•ฉ๋‹ˆ๋‹ค. JPype๊ฐ€ Android์—์„œ ์ž‘๋™ํ•˜๋„๋ก ํ•˜๋Š” ํ–‰์šด์„ ๋น•๋‹ˆ๋‹ค.

๋Œ“๊ธ€ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

ํด๋ž˜์Šค ๊ฒฝ๋กœ์—์„œ ๋ฌด์—‡์ด ์ž˜๋ชป๋  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ ๊ทธ๊ฒƒ์ด Python์„ ์‹œ์ž‘ํ•˜๋Š” ๊ณณ์ผ ๊ฒƒ์ด๋ผ๊ณ  ์ถ”์ธกํ•ด์•ผ ํ•œ๋‹ค๋ฉด. ๋•Œ๋•Œ๋กœ ์‚ฌ๋žŒ๋“ค์€ ๋ชจ๋“ˆ์—์„œ JVM์„ ์‹œ์ž‘ํ•˜๊ณ  ์‹œ์ž‘ ๋””๋ ‰ํ† ๋ฆฌ์— ๋Œ€ํ•œ Java ๊ฒฝ๋กœ ๋ฐ Python ๊ฒฝ๋กœ์— ๋Œ€ํ•œ ๊ทœ์น™์ด ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— jar๊ฐ€ ๋ˆ„๋ฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ์‚ฌ์šฉ์ž ๊ฐ€์ด๋“œ ์„น์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.)

๋‚˜๋Š” ๋งค์ผ classpath ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉฐ ์ด๊ฒƒ์€ ์šฐ๋ฆฌ ํ…Œ์ŠคํŠธ ํŒจํ„ด์˜ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํด๋ž˜์Šค ๊ฒฝ๋กœ๊ฐ€ ์กด์ค‘๋˜์ง€ ์•Š์œผ๋ฉด ๊ฝค ํฐ ์‹คํŒจ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ๋ณต์žกํ•œ ํŒจํ„ด์„ ์ž‘๋™์‹œํ‚ค๋Š” ๋ฐ ํ•„์š”ํ•œ ๋งˆ๋ฒ• ๊ฐ™์€ ์œ„์น˜์™€ ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š” ๋ฐ ์–ด๋ ค์›€์„ ๊ฒช๋Š” ์ฒซ ๋ฒˆ์งธ ์‚ฌ๋žŒ์€ ์•„๋‹™๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ๊ฐœ๋ฐœ ์˜์—ญ์„ ๊ธฐ์ค€์œผ๋กœ Py ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ํ…Œ์ŠคํŠธ ์‹œ์Šคํ…œ์„ ์‹œ์ž‘ํ•˜๋Š” ์˜ˆ์ž…๋‹ˆ๋‹ค.

import jpype
import os

devel = os.path.dirname(__file__)
devel = os.path.join(devel, '..', '..')
devel = os.path.abspath(devel)  # Notice that I converted the path to absolute so that it doesn't matter where the
# PWD of Java will be when this script is called.   Otherwise, if I import this from a different location it will use the
# original PWD and Java will find nothing in the classpath.

classpath = [
    '%s/gov.llnl.math/dist/*' % devel,
    '%s/gov.llnl.rdak/dist/*' % devel,
    '%s/gov.llnl.rnak/dist/*' % devel,
    '%s/gov.llnl.rtk/dist/*' % devel,
    '%s/gov.llnl.rtk.gadras/dist/*' % devel,
    '%s/gov.llnl.rtk.response/dist/*' % devel,
    '%s/gov.llnl.utility/dist/*' % devel,
    ]

jpype.startJVM(classpath=classpath, convertStrings=False)

์ƒ๋Œ€ ๊ฒฝ๋กœ์™€ ์ ˆ๋Œ€ ๊ฒฝ๋กœ๊ฐ€ ์ž‘๋™ํ•˜์ง€๋งŒ ์‹œ์ž‘ ์œ„์น˜์— ๋”ฐ๋ผ ํฌ๊ฒŒ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. addClassPath์—๋Š” ๋ชจ๋“  ๊ฒฝ๋กœ๊ฐ€ ํ˜ธ์ถœ์ž ์œ„์น˜์™€ ๊ด€๋ จ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ํŠน๋ณ„ํ•œ ๋งˆ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. classpath ํ‚ค์›Œ๋“œ ์ธ์ˆ˜์—๋„ ๋™์ผํ•œ ๋…ผ๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์ž์—ด ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠธ๋ฆฌ๊ฑฐ๋˜๋Š” ๋™์ž‘์— ๋Œ€ํ•œ ๋ฐ˜ํ™˜ ์œ ํ˜•์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ๊ฐ€ String[] ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์„ ์–ธ๋œ ๊ฒฝ์šฐ ๋ฐ˜ํ™˜ํ•  ๋•Œ ๊ฐ Python ๋ฌธ์ž์—ด์„ Java๋กœ ๊ฐ•์ œ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์†Œ๋“œ๊ฐ€ List<String> ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์„ ์–ธ๋œ ๊ฒฝ์šฐ Java ์ œ๋„ค๋ฆญ์ด ์ด๋ฅผ ์ œ๊ฑฐํ•˜์—ฌ List<Object> ๊ฐ€ ๋  ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. JPype๊ฐ€ ๋ชฉ๋ก์„ ๋ณด๋Š” ๋ฐฉ์‹์— ๋”ฐ๋ผ ๋ณ€ํ™˜์„ ์‹œ๋„ํ•˜๊ฑฐ๋‚˜ ์‹œ๋„ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋Š” ์ •์˜๋œ ๋™์ž‘์ด๋ฏ€๋กœ ํ™•์ธํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์•ˆ์ „ํ•œ ์†”๋ฃจ์…˜์€ ๋ฐ˜ํ’ˆ์„ ์œ„ํ•ด ๋ชจ๋“  ํ•ญ๋ชฉ์„ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋Š” ๋ชฉ๋ก ์ดํ•ด์ž…๋‹ˆ๋‹ค.

ํด๋ž˜์Šค ๊ฒฝ๋กœ์—์„œ ๋ฌด์—‡์ด ์ž˜๋ชป๋  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ ๊ทธ๊ฒƒ์ด Python์„ ์‹œ์ž‘ํ•˜๋Š” ๊ณณ์ผ ๊ฒƒ์ด๋ผ๊ณ  ์ถ”์ธกํ•ด์•ผ ํ•œ๋‹ค๋ฉด. ๋•Œ๋•Œ๋กœ ์‚ฌ๋žŒ๋“ค์€ ๋ชจ๋“ˆ์—์„œ JVM์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๊ฒŒ ๋‚ด๊ฐ€ ํ•˜๋˜ ์ผ์ด์•ผ!

๋‚˜๋Š” ๋งค์ผ classpath ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉฐ ์ด๊ฒƒ์€ ์šฐ๋ฆฌ ํ…Œ์ŠคํŠธ ํŒจํ„ด์˜ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํด๋ž˜์Šค ๊ฒฝ๋กœ๊ฐ€ ์กด์ค‘๋˜์ง€ ์•Š์œผ๋ฉด ๊ฝค ํฐ ์‹คํŒจ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ๋ณต์žกํ•œ ํŒจํ„ด์„ ์ž‘๋™์‹œํ‚ค๋Š” ๋ฐ ํ•„์š”ํ•œ ๋งˆ๋ฒ• ๊ฐ™์€ ์œ„์น˜์™€ ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š” ๋ฐ ์–ด๋ ค์›€์„ ๊ฒช๋Š” ์ฒซ ๋ฒˆ์งธ ์‚ฌ๋žŒ์€ ์•„๋‹™๋‹ˆ๋‹ค.

์˜ˆ, ์ด๊ฒƒ์€ ๋‹น์‹ ์ด ์ฆ‰์‹œ ์•Œ์•„์ฐจ๋ฆด ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋ฉฐ ๋‚ด๊ฐ€ ์ด ๋ฌธ์ œ๋ฅผ ๊ฒช์€ ์ฒซ ๋ฒˆ์งธ ์‚ฌ๋žŒ์ด ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๋„์›€์ด ๋˜๋Š” ์ฝ”๋“œ ์ƒ˜ํ”Œ์„ ์ œ๊ณตํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ผ๋ถ€ ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.

์•ˆ์ „ํ•œ ์†”๋ฃจ์…˜์€ ๋ฐ˜ํ’ˆ์„ ์œ„ํ•ด ๋ชจ๋“  ํ•ญ๋ชฉ์„ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋Š” ๋ชฉ๋ก ์ดํ•ด์ž…๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์ด ๋‚ด๊ฐ€ ํ•œ ์ผ์ด๋ฉฐ ์ง€๊ธˆ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”!

๋ช‡ ๋…„ ์ „์— py4j์™€ jnius๋ฅผ ๋น„๊ตํ•œ ๊ฒฐ๊ณผ jnius๊ฐ€ ํ›จ์”ฌ ๋น ๋ฆ…๋‹ˆ๋‹ค.

์žฅ์†Œ์—์„œ ์–ธ๊ธ‰๋œ jpype๋ฅผ ๋ณด์•˜์„ ๋•Œ ํ•ญ์ƒ - http://jpype.sourceforge.net/ ์„ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ์œ ์ง€ ๊ด€๋ฆฌ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋ฏ€๋กœ ๋ฉ€๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค(์ƒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ์ด์ƒํ•˜๊ฒŒ ๋ณด์ง€ ๋ชปํ•จ)

์ด ์Šค๋ ˆ๋“œ๋ฅผ ์ฝ์œผ๋ฉด์„œ ๋ฒค์น˜๋งˆํฌ๋ฅผ ๋‹ค์‹œ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค.
์ผ๋ถ€ ๊ฒฐ๊ณผ:
https://gist.github.com/AbdealiJK/1dd5b7677435ba22f9ab3e26016bb3e7

# jpype
# createjvm: 0.550s
# loadmodel: tot=1.466451 max=1.064521s avg=0.014665s
# fields   : tot=0.019881 max=0.009795s avg=0.000199s
# score    : tot=0.033356 max=0.023338s avg=0.000334s

# jnius
# createjvm: 0.249s
# loadmodel: tot=1.773011 max=1.385274s avg=0.017730s
# fields   : tot=0.039058 max=0.012234s avg=0.000391s
# score    : tot=0.067590 max=0.031904s avg=0.000676s

# py4j
# createjvm: 0.222s
# loadmodel: tot=0.616913 max=0.027464s avg=0.006169s
# fields   : tot=0.699152 max=0.026426s avg=0.006992s
# score    : tot=0.389583 max=0.017620s avg=0.003896s

๊ณต์ •ํ•˜๊ฒŒ ๋งํ•˜์ž๋ฉด, JPype๋Š” 2020๋…„ 3์›”๊นŒ์ง€ Python(CPython๊ณผ ๋ฐ˜๋Œ€)์œผ๋กœ ์ž‘์„ฑ๋œ ํ”„๋ŸฐํŠธ ์—”๋“œ API๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ JPype๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์— ๋น„ํ•ด ๋‹ค์†Œ ๋Š๋ฆฌ๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์—ฌ์ฃผ๋Š” ์ด์ „ ๋ฒค์น˜๋งˆํฌ๊ฐ€ ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋กœ ํ•ด๊ฒฐํ•ด์•ผ ํ•˜๋Š” ๋ฐฑ์—”๋“œ ๋ฌธ์ œ๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์•˜๊ณ  Ruby, ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ๋“ฑ์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ์ „์ฒด ๋‹ค์ธต ๋ž˜ํผ๋ฅผ ์ œ๊ฑฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์†๋„๊ฐ€ ๋งˆ์ง€๋ง‰ ์ž‘์—…์ด์—ˆ์Šต๋‹ˆ๋‹ค.

์ด ์‹œ์ ์—์„œ ๊ฝค ๋นจ๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‹ค๋ฅธ ํŒจํ‚ค์ง€์™€ ๊ด€๋ จํ•˜์—ฌ ์ถ”๊ฐ€ ์ž‘์—…์ด ํ•„์š”ํ•œ ๊ฒƒ์„ ๋ฐœ๊ฒฌํ•˜๋ฉด ๋ฌธ์ œ์— ๋ฉ”๋ชจ๋ฅผ ๋‚จ๊ฒจ์ฃผ์„ธ์š”. ๋ฐ˜ํ™˜ ๊ณ„์•ฝ์œผ๋กœ ์ธํ•ด ๋ช‡ ๊ฐ€์ง€ ์ œํ•œ ์‚ฌํ•ญ์ด ์žˆ์ง€๋งŒ ํ˜ธ์ถœ, ๋ฐฐ์—ด ์ „์†ก ๋ฐ ๋ฉ”๋ชจ๋ฆฌ ๋ฒ„ํผ๋ง์„ ์œ„ํ•œ ๊ธฐ๋ณธ ๊ฒฝ๋กœ๋Š” ์ด ์‹œ์ ์—์„œ ๊ฝค ์ž˜ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

JPype์—์„œ๋„ ์ข‹์€ ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ, numpy ๋ฐฐ์—ด๊ณผ์˜ ํ†ตํ•ฉ์—์„œ ์ข‹์€ ๊ฐ€์น˜๋ฅผ ์–ป๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ „์—๋Š” ํ•  ์ˆ˜ ์—†์—ˆ๋˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์˜๋ฏธ ์žˆ๋Š” ๋ฐฉ์‹์œผ๋กœ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋ˆ„๊ตฌ๋“ ์ง€ kivy-remote-shell ๋„๊ตฌ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜์—ฌ ํ˜„์žฌ Python3 ๋ฐ buildozer๋กœ ๋นŒ๋“œํ•˜๊ณ  ์ง€์นจ์„ ๋‹จ๊ณ„์ ์œผ๋กœ ๊ฐœ์„ ํ•˜๋„๋ก ์นœ์ ˆํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด JPype ์ด์‹ ๋…ธ๋ ฅ์— ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งค์šฐ. ๋ถ€ํŒ… ๋ฐ ํ…Œ์ŠคํŠธ ๋‹จ๊ณ„๊นŒ์ง€ ๋ชจ๋“  ํ•„์ˆ˜ ๋‹จ๊ณ„๋ฅผ ์™„๋ฃŒํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ ํ”„๋กœ์„ธ์Šค๋ฅผ ์™„๋ฃŒํ•  ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ์ด ์—†์œผ๋ฉด ์ง„ํ–‰ํ•˜๊ธฐ ์–ด๋ ค์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ฒˆ ์ฃผ๋ง์— ์›๊ฒฉ ์…ธ ๋„๊ตฌ ์—…๋ฐ์ดํŠธ๋ฅผ ๋‹ค์‹œ ์‹œ๋„ํ•˜๊ฑฐ๋‚˜(์„ฑ๊ณตํ•  ์ˆ˜ ์žˆ์Œ) kivy์— ๋Œ€ํ•ด ๋” ์ž˜ ์•Œ๊ณ  ์žˆ๋Š” ์ดํ•ด ๋‹น์‚ฌ์ž๊ฐ€ ์ด ์ „์ œ ์กฐ๊ฑด ์ž‘์—…์„ ์™„๋ฃŒํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ฃผ๋ง์— ๋‚ด๊ฐ€ ๊ฐ€์žฅ ์™„์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ์ˆ  ์ž‘์—…์„ ์™„๋ฃŒํ•˜๋Š” ๋ฐ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. . ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์„ ๋•๊ธฐ ์œ„ํ•ด ๋‚ด ์‹œ๊ฐ„์„ ์ž์œ ๋กญ๊ฒŒ ์ œ๊ณตํ•˜์ง€๋งŒ, ๋ฆฌ์†Œ์Šค๋Š” ์œ ํ•œํ•˜๋ฉฐ Android ์ด์‹ ์ž‘์—…์—์„œ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ชจ๋“  ์ž‘์—…์€ ๋‹ค๋ฅธ ๋งŽ์€ ์‚ฌ๋žŒ๋“ค๋„ ๊ด€์‹ฌ์„ ๊ฐ–๊ณ  ์žˆ๋Š” Python from Java ๋ธŒ๋ฆฌ์ง€์— ๋Œ€ํ•œ ์ง€์—ฐ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ ํฌํŒ… ๋…ธ๋ ฅ์ด ์ฐจ์ด์ ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ต์‹ฌ ์ฝ”๋“œ๋ฅผ ์žฌ์ž‘์—…ํ•˜๋Š” ๋ฐ ๋ช‡ ์ฃผ๋ฅผ ๋ณด๋‚ธ PyPy ํฌํŒ… ๋…ธ๋ ฅ์˜ ๊ธธ์„ ๊ฐ€๋Š” ๊ฒƒ์„ ํ”ผํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ฐœ์ฒด ์‹œ์Šคํ…œ์˜ ์‚ฌ์†Œํ•œ ์ฐจ์ด๊ฐ€ ์˜ค๋ฅ˜๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ธฐ์ˆ ์  ๋ฌธ์ œ์— ๋ถ€๋”ช์ณค์Šต๋‹ˆ๋‹ค. ์ƒ์„ฑ๋œ ์ฝ”๋“œ์—์„œ ์ƒ์„ฑ๋œ ์˜ค๋ฅ˜ ๋ณด๊ณ ์„œ๋ฅผ ๋””๋ฒ„๊ทธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ถ”์ ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ์‚ฌ๋žŒ์„ ์ฐพ์„ ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์—Ž์งˆ๋Ÿฌ์ง„ ์šฐ์œ ์— ๋Œ€ํ•ด ์šธ์ง€ ์•Š๊ณ  JPype ์ฝ”๋“œ๋ฅผ ๋‹ค๋ฅธ ์˜๋ฏธ ์žˆ๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ๊ทธ ๋ชจ๋“  ๋…ธ๋ ฅ์„ ๊ธฐ์šธ์˜€์ง€๋งŒ ๊ฒฐ๊ตญ JPype๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋Š” ์‚ฌ์šฉ์ž๋Š” ๋†’๊ณ  ๋ฉ”๋งˆ๋ฅธ ์ƒํƒœ๋กœ ๋‚จ์•˜์Šต๋‹ˆ๋‹ค. ์ด ๋…ธ๋ ฅ์ด ์‹คํŒจํ•˜๋ฉด ๋‹ค์‹œ ๋Œ์•„๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ๊ฒƒ์ด ์†์‹ค๋˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ, ๋Œ€๊ธฐ์—ด์˜ ๋งจ ๋์— ๋ฌด์–ธ๊ฐ€๊ฐ€ ์žˆ์œผ๋ฉด ๋ˆ„๊ตฐ๊ฐ€ ์‹œ๊ฐ„์„ ๋‚ด์„œ ๋‚˜๋ฅผ ๋„์™€์ค„ ์ˆ˜ ์—†๋‹ค๋ฉด 6๊ฐœ์›” ๋™์•ˆ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. .

์ดํ•ด ๊ด€๊ณ„์ž๋ฅผ ์œ„ํ•œ ์ง„ํ–‰ ์ƒํ™ฉ ์—…๋ฐ์ดํŠธ.

pythonforandroid ๋‚ด์—์„œ JPype๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๋ถ€ํŒ…ํ•˜๊ณ  ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์„ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. JVM์˜ ์ฐจ์ด๋กœ ์ธํ•ด ์ผ๋ถ€ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์ด ๊ฐ€๋Šฅํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์˜ JPype๋Š” Android ํ”Œ๋žซํผ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํฌํŠธ๋Š” buildozer ๋ฐ pythonforandroid ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ์ผ๋ถ€ ์—…๊ทธ๋ ˆ์ด๋“œ๊ฐ€ ํ•„์š”ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹œ๊ฐ„์ด ์ข€ ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค(๋”ฐ๋ผ์„œ ์†Œ์Šค๋ฅผ ๋งŽ์ด ์ฝ๊ณ  ๋„์›€์„ ์š”์ฒญํ•ด์•ผ ํ•จ). ํ•œ ์ฃผ๋ง์— ํ”„๋กœ์„ธ์Šค์˜ ๊ฐ€์žฅ ์–ด๋ ค์šด ๋ถ€๋ถ„์„ ์™„๋ฃŒํ•  ์ˆ˜ ์žˆ๋„๋ก ์‘๋‹ตํ•ด ์ฃผ์‹  ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ๊นŠ์€ ๊ฐ์‚ฌ๋ฅผ ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ์˜๊ฒฌ์ด ์—†์—ˆ๋‹ค๋ฉด ๋ถˆ๊ฐ€๋Šฅํ–ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ด€๋ จ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ PR๋กœ ๋„ฃ์—ˆ์ง€๋งŒ PR์˜ ๋ฐฑ๋กœ๊ทธ๋ฅผ ๋ณด๋ฉด ๊ณ ๋ ค ๋Œ€์ƒ์ด ๋˜๊ธฐ๊นŒ์ง€ ์‹œ๊ฐ„์ด ์ข€ ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ํ•„์š”ํ•œ ํ•ต์‹ฌ ๊ธฐ์ˆ  ์‚ฌ์–‘์ด ์žˆ์œผ๋ฏ€๋กœ ์ด๋ฅผ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋ฉฐ ๋ช…๋ชฉ์ƒ ๋Šฆ๊ฐ€์„ ๋‹ฌ๋ ฅ์— JPype 1.2 ์ •๋„์˜ ์ž‘์—… ๋ฆด๋ฆฌ์Šค ์ฝ”๋“œ๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์˜ ๊ด€์‹ฌ์ด ํฌ๋‹ค๋ฉด ์ถ”์ง„ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์˜ ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์ธ Python from Java์™€ ๊ฒฝ์Ÿํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ๋…ธ๋ ฅ์„ ๊ฐ€์†ํ™”ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ฃผ๊ณ  ์‹ถ๋‹ค๋ฉด, ๋‹ค์Œ ์–ด๋ ค์šด ๋‹จ๊ณ„๋Š” ๋นŒ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ , ์—๋ฎฌ๋ ˆ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•˜๊ณ , ํ…Œ์ŠคํŠธ ๋ฒค์น˜๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ถ€๋ถ„ ๋นŒ๋“œ ์‹œ์Šคํ…œ์œผ๋กœ ๋ชจ๋“  ๊ฒƒ์ด ์ œ์ž๋ฆฌ์— ์žˆ๋Š” ๋„์ปค ์ด๋ฏธ์ง€๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋‚ด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. azure ํŒŒ์ดํ”„๋ผ์ธ(๋˜๋Š” ์ผ๋ถ€ ๋‹ค๋ฅธ CI ์‹œ์Šคํ…œ)์˜ Android. ์ž‘๋™ํ•˜๋Š” ๊ฒƒ๊ณผ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ๋Š” ์ž‘๋™ํ•˜๋Š” CI๊ฐ€ ์žˆ์œผ๋ฉด ์•ˆ์ •์ ์ธ ์†Œํ”„ํŠธ์›จ์–ด๋กœ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ ํ›จ์”ฌ ๋” ๊ฐ€๊นŒ์›Œ์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด JPype ํ”„๋กœ์ ํŠธ์— ํฌํ•จ๋˜์–ด์•ผ ํ•˜๋Š”์ง€ ๋˜๋Š” ๋ณ„๋„์˜ Android ํ…Œ์ŠคํŠธ ํ”„๋กœ์ ํŠธ๊ฐ€ ์žˆ์–ด์•ผ ํ•˜๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰