OwlAPI and HermiT on Android (> Android P, SDK 28)
[Implementation Issues on OwlAPI and HermiT on > Android P]
[문제 현상]
- Android 9 (P, SDK 28) 이상에서 Owl API 이용하기 위해서,
- Gradle 설정 변경
- compiledSdkVersion, targetSdkVerison 들을 28로 변경
- 기존 코드 실행 시 에러
- OWL 초기화 시 다음과 같은 오류 발생함
W/System.err: SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
W/edependencytes: Accessing hidden field Lsun/misc/Unsafe;->theUnsafe:Lsun/misc/Unsafe; (light greylist, reflection)
W/edependencytes: Accessing hidden field Ljava/lang/Thread;->threadLocalRandomProbe:I (dark greylist, reflection)
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: {패키지}.gradledependencytest, PID: 23725
java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java:203)
- SLF5J 관련한 로그 메시지는 일반 Java 환경에서도 동일하게 출력되는 것으로, 안전하게 무시 가능함
- FATAL EXCEPTION 이후는 OWL Ontology Manager를 생성하지 못해 발생한 문제
- 원인은 Accessing hidden field 관련한 에러?
-> Android 9 (P, API 28) 이상부터는 플랫폼에서 비 SDK 인터페이스 사용을 제한. 비 SDK 인터페이스를 참조하거나 리플렉션 또는 JNI를 이용해 SDK 인터페이스 핸들을 가져오려 할 때 오류 발생
(참고: https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces)
[회피 방법]
- 코드 상에서 StrictMode API를 이용해 비 SDK 인터페이스를 테스트할 수 있는데, dependency 때문에 참조한 라이브러리에서 참조하는 경우에는 코드 적용하기 어려움
-> 공개 요청을 할 수도 있긴 하지만, 장담 못 함. (링크) - 개발 기기에서 비 SDK 인터페이스에 접근할 수 있도록 설정하기 (링크)
- 루팅 된 기기가 필요 없음
- 설정하기
adb shell settings put global hidden_api_policy_pre_p_apps 1
adb shell settings put global hidden_api_policy_p_apps 1
- 기본 설정으로 재설정 할 때는,
adb shell settings delete global hidden_api_policy_pre_p_apps
adb shell settings delete global hidden_api_policy_p_apps
- API 시행 정책의 정수는 다음 값 중 하나로 설정
- 0: 비 SDK 인터페이스의 모든 감지를 사용 중지합니다. 이 설정을 사용하면 비 SDK 인터페이스 사용에 관한 모든 로그 메시지가 사용 중지되고 StrictMode API를 사용해 앱을 테스트할 수 없습니다. 이 설정은 사용하지 않는 것이 좋습니다.
- 1: 모든 비 SDK 인터페이스에 액세스할 수 있지만 비 SDK 인터페이스를 사용하면 경고와 함께 로그 메시지가 인쇄됩니다. 이 설정을 사용하면 StrictMode API를 사용해 앱을 테스트해도 됩니다.
- 2: 블랙리스트 또는 그레이리스트에 속하고 타겟 API 수준에서 제한되는 비 SDK 인터페이스의 사용이 금지됩니다.
- 3: 블랙리스트에 속한 비 SDK 인터페이스의 사용은 금지되지만, 그레이리스트에 속하고 타겟 API 수준에서 제한되는 인터페이스의 사용은 허용됩니다.
[실제로 적용한 방법]
- Non-SDK 인터페이스를 이용할 수 있도록 허용
- adb를 이용해 장치의 정책 변경
adb shell settings put global hidden_api_policy_pre_p_apps 1
adb shell settings put global hidden_api_policy_p_apps 1
- 앱 실행 시, 허가 부여
- onCreate 등, Non-SDK 인터페이스 시작 전에 아래 코드로 허가 부여
if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.permitNonSdkApiUsage()
.build());
}
[기타 참고]
- Android P displaying API compatibility error message: https://stackoverflow.com/questions/51210633/android-p-displaying-api-compatibility-error-message/54191551
- onCreate() 값은 곳에 아래 코드를 등록해 두면 어디에서 violation을 일으키는지 로그 출력됨
if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectNonSdkApiUsage()
.penaltyLog()
.build());
}
댓글
댓글 쓰기