🛫 프로젝트의 서막
회사에서 진행하는 프로젝트에서 AWS의 Iot Core 서비스를 안드로이드 앱에 적용해볼 기회가 생겼다.
AWS는 취준하면서 잠깐 토이 프로젝트를 진행할때 사용해봤었는데 레퍼런스를 따라하다가 git에 access key를 올려놓고 잊어서 과금될 뻔 했던 기억이 있다...😱

어쨋든 실무 프로젝트에서 AWS 서비스를 적용해볼 수 있다니 재밌는 경험이 될 것 같았다. (졸작도 사물 인터넷 관련 프로젝트를 했었는데 감회가 새롭다.)
🐠 AWS Iot Core 를 찾아서

AWS는 클라우드 컴퓨팅 서비스 제공 업체답게(?) 다양한 서비스마다 샘플 코드를 다운받아 서비스를 테스트해 볼 수 있는데 이번 프로젝트에서 AWS Iot Core 서비스를 이용하기 때문에 아래 git 샘플 코드를 참고해 개발을 진행하는 중이다.
아래 레포지토리에서 android 폴더를 참고하면 된다.
https://github.com/aws/aws-iot-device-sdk-java-v2
💻 AWS Iot Core 샘플 코드
일하다 보면 (특히 프로젝트 구조 설계에 대한 고민을 하다보면) 안드로이드 개발자 사이트의 샘플 코드를 다운받아 보기도 하고 많은 github의 레포지토리를 참고하게 되는 것 같다. 이번 샘플 코드는 재밌는 형태로 구현되어 있었는데 앱을 실행하고 리스트 아이템을 클릭하면 SAMPLES로 선언된 패키지의 자바 파일을 실행하는 구조로 개발이 되어 있었다.
val SAMPLES = mapOf(
"BasicConnect" to "basicconnect.BasicConnect",
"Publish/Subscribe Sample" to "pubsub.PubSub",
"Jobs Client Sample" to "jobs.JobsSample",
"Shadow Client Sample" to "shadow.ShadowSample",
"Publish/Subscribe Load Test" to "pubsubstress.PubSubStress"
)
class MainActivity : AppCompatActivity(), AdapterView.OnItemSelectedListener {
//~~ 중략 ~~
override fun onItemSelected(parent: AdapterView<*>?, view: View?, pos: Int, id: Long) {
clearConsole()
val sampleName = parent?.getItemAtPosition(pos).toString()
val sampleClassName = SAMPLES[sampleName]
if (sampleClassName != null) {
return runSample(sampleClassName)
}
}
}
⚙️ AWS Iot Core 안드로이드 SDK 삽질 기록
샘플 프로젝트에는 AWSIotDevice Sdk 가 라이브러리로 포함되어 있었는데 우리 프로젝트에 그대로 적용할 수는 없고 build.gradle에 의존성을 연결해주기 위해 좀 고생을 했다.
의존성 추가하기
: git 페이지에 안내된 의존성 추가 -> 이것만으로는 필요한 클래스 import가 안됨.
dependencies {
implementation 'software.amazon.awssdk.crt:android:0.16.14'
}
import 해야할 클래스의 패키지(의존성) 확인
: Aws Iot Core MQTT 연동에 필요한 클래스 의존성 확인해서 build.gradle에 추가 -> Duplicate class 에러 발생 (이때, 에러 코드를 잘 살폈어야 했는데 다른 방식으로 이해했다.)
dependencies {
implementation 'software.amazon.awssdk.iotdevicesdk:aws-iot-device-sdk:1.9.3'
}

Duplicate class 에러 해결 임시 방편
: 에러 발생한 의존성 해결 (crt-android를 crt로 변경) -> 빌드 성공하나 앱 실행해서 MqttClient를 생성하는 코드가 호출되면 UnknownPlatform Exception 발생
dependencies {
implementation 'software.amazon.awssdk.crt:0.16.16'
}
UnknownPlatform Exception 발생 원인을 찾아..
: 한 번 끝까지 가보자. 에러 발생한 코드 타고타고 들어가기. -> 여기서 System.getProperty(”os.arch”)를 찍어보니 정의되지 않은 armv8l로 나와서 에러 발생하고 있었다.


Aws-crt 커밋 메시지 확인
: 나중에 crt github 커밋 로그를 확인해보니 안드로이드에서 항상 발생하는 문제라고 적혀있었다..
: Remove loadFromJar for android that will always fail

다시 원점에서 고민..
: 하지만 샘플 프로젝트는 정상 실행되니 'software.amazon.awssdk.crt:android:0.16.14'에서는 발생하지 않는 문제이지 않을까?라는 생각에 다시 2번으로 돌아가서 에러 코드 자세히 확인.
-> 'software.amazon.awssdk.crt:aws-crt:0.16.16'는 의존성을 넣지 않는데 어디에서 추가되고 있는 것일까?
중복 의존성 원인 발견
: 답은 app > project Structure를 확인해보니까 dependecies all module에 crt 가 어디에 중복으로 들어가 있는지 확인할 수 있다.
-> 모듈화된 라이브러리 'software.amazon.awssdk.iotdevicesdk:aws-iot-device-sdk:1.9.3'에 crt 의존성이 포함되어 있었다.
본질적인 원인 해결을 위한 고민
: 하지만 중복 포함을 제거하기 위해 'software.amazon.awssdk.crt:android:0.16.14' 의존성을 제거하고 빌드 해보니 빌드는 되지만 여전히 platform 알 수 없다고 나오는 런타임 에러는 그대로였다.
-> aws-iot-device-sdk:1.9.3 의 crt 를 제거하고 에러가 발생하지 않는 안드로이드 용 crt 의존성을 추가하고 싶었다.
해결 방법
: 중복 의존성을 제거하기 위한 방법을 찾던 중 아래 블로그를 발견하게 되었다. -> aws-iot-device-sdk:1.9.3 의 crt 를 제거하고 에러가 발생하지 않는 안드로이드 용 crt 의존성을 추가하여 해결 완료!! 🎉🎉🎉
dependencies {
implementation 'software.amazon.awssdk.crt:aws-crt-android:0.16.14'
implementation("software.amazon.awssdk.iotdevicesdk:aws-iot-device-sdk:1.9.3") {
exclude group: "software.amazon.awssdk.crt"
}
}
-> 위 코드를 통해 AWS Iot Core Android Sdk를 추가했을때 발생했던 UnknownPlatformException과 전이 의존성 문제를 해결할 수 있었다.
🤦 후기
긴 삽질 기록을 적느라고 글이 길어지게 되었지만 2번에서 에러 코드를 보고 해결 방법을 떠올릴 수 있었다면 9번까지 고민할 필요는 없었을 것이다. 앞으로 또 이런 문제를 만나거나 비슷한 에러가 발생했을때 같은 고민을 반복하는 일이 없도록 오늘의 문제 해결 흐름을 글로 남겨보았다. AWS는 훌륭한 서비스이기 때문에 기술 블로그, 샘플 코드가 정말 잘 되어있지만 각자 프로젝트에 맞게 사용하기 위해선 조금이라도 수정이 필요한 상황이 생기고 이런 문제와 관련해서 한글로 설명해주는 글이 누군가에게는 도움이 되지 않을까 생각한다.
✍️ 다짐.
- 에러 코드를 보고 무작정 검색해서 단편적인 해결 방법을 찾기보단, 본질적인 원인을 스스로 유추해보자.
- 영어에 익숙해지자(?..!)
2022년 7월 19일 벨로그에 작성된 내용을 티스토리로 옮겨왔습니다.
'개발 > 안드로이드' 카테고리의 다른 글
| [Android] 안드로이드 기본 개념 정리 (0) | 2023.01.02 |
|---|