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());
       }

    [기타 참고]

    if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                .detectNonSdkApiUsage()
                .penaltyLog()
                .build());
    }

    댓글

    이 블로그의 인기 게시물

    [DevTip] Windows에서 tail 쓰기...

    환경개선부담금

    Electropermanent Magnets: Programmable Magnets with Zero Static Power Consumption Enable Smallest Modular Robots Yet