에러(error)
Program type already present
에러 기록(error log)
Build : build failed org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'. at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:100) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:70) ... Caused by: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: at com.android.builder.profile.Recorder$Block.handleException(Recorder.java:55) at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:104) ... 107 more Caused by: com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: ... 122 more Caused by: com.android.tools.r8.CompilationFailedException: Compilation failed to complete at com.android.tools.r8.utils.ExceptionUtils.withCompilationHandler(ExceptionUtils.java:76) at com.android.tools.r8.utils.ExceptionUtils.withD8CompilationHandler(ExceptionUtils.java:45) ... 127 more Caused by: com.android.tools.r8.utils.AbortException at com.android.tools.r8.utils.Reporter.failIfPendingErrors(Reporter.java:77) at com.android.tools.r8.utils.Reporter.fatalError(Reporter.java:58) ... 130 more
Android issues : Program type already present: org.apache.http.auth.AUTH Message{kind=ERROR, text=Program type already present: org.apache.http.auth.AUTH, sources=[Unknown source file], tool name=Optional.of(D8)} |
개발 환경(platform)
OS : Windows 10
1) Application(apk) 개발
- IDE : Android Studio 3.1 / (Compile) Android SDK 27 / Java 1.8
- Build Setting : mltidex 사용
- Dependency 라이브러리 (maven) : org.apache.httpcomponents:httpclient:4.5.6
2) Android Archive(aar) 개발
- IDE : Android Studio 3.1 / (Compile) Android SDK 23 / Java 1.6
- Build Setting : mltidex 사용
- Dependency 라이브러리 (maven) : org.apache.httpcomponents:httpclient:4.5.6
3) Library(jar) 개발
- IDE : Eclipse (Neon.1a Release 4.6.1) / Java 1.8
- Dependency 라이브러리 (maven) : jsonld-java
상황(situation)
APK는 AAR를 사용하고, AAR은 JAR를 사용하는 구조로 Dependency 되어 개발 중이다. 그리고 3개 모듈 모두 로컬에 메이븐 레포지토리(maven repository)를 만들어서 사용 중이다. 참고로, 이렇게 Maven을 사용하면 각 모듈 프로젝트에서 사용하는 라이브러리들을 한 곳에서 참조해서 사용하므로 개발을 편하게 할 수 있다.
원인(cause)
에러로그를 보면 두 가지 중 하나가 원인이라는 것을 추측할 수 있다. 하나는 Library 안에 함수가 너무 많아서 하나의 Dex로 만들기 힘들 때 발생하는 Multidex 에러이고, 다른 하나는 사용하려는 Library 중에 이미 선언된 것이 있는데 이걸 또 사용하려고 해서 충돌이 발생하는 에러이다.
나같은 경우, Multidex를 이미 설정해서 사용하고 있었기 떄문에, 첫번째 이유는 아니었다. 따라서 두번째 문제일 가능성이 크기 때문에, 이 문제일 것으로 가정하고 접근했고, 아래처럼 에러를 해결할 수 있었다.
해결 접근(approach)
1) Program type already present 에러로 충돌(collusion)이 발생했다는 것을 짐작한다.
2) Program type already present: org.apache.http.?? 에러로 apache.http 관련 Library가 충돌이 났다는 것을 짐작한다.
해결(solution)
[해결방법] 동일한 Library가 2개 이상이어서 충돌난 것이므로 중복되는 부분을 제거하고 하나만 사용하도록 없애주면 된다. 앞에 개발환경에서 언급했듯이, 현재 내 개발환경에서는 apk를 빌드할 때 jar와 aar 모두를 사용하고 있으니, 3개 모듈안에 Dependency로 포함되어 있는 모든 Library들을 살펴봐야 한다. Android Studio 프로젝트에서 아래처럼 빌드하려는 모듈(Module)에 Dependency가 걸려져 있는 모든 Library들을 gradlew를 통해 볼 수 있다.
1) gradlew로 모든 dependency libraries 확인
$ ./gradlew app:dependencies
… +--- project :sample_aar +--- org.apache.httpcomponents:httpclient:4.5.6 | +--- org.apache.httpcomponents:httpcore:4.4.10 | … +--- com.sample.jar:test:1.0 | … | \--- com.github.jsonld-java:jsonld-java:0.12.3 | +--- com.fasterxml.jackson.core:jackson-core:2.9.7 | +--- com.fasterxml.jackson.core:jackson-databind:2.9.7 | | +--- com.fasterxml.jackson.core:jackson-annotations:2.9.0 | | \--- com.fasterxml.jackson.core:jackson-core:2.9.7 | +--- org.apache.httpcomponents:httpclient-osgi:4.5.6 | | +--- org.apache.httpcomponents:httpclient:4.5.6 (*) | | +--- commons-codec:commons-codec:1.10 | | +--- org.apache.httpcomponents:httpmime:4.5.6 | | | \--- org.apache.httpcomponents:httpclient:4.5.6 (*) | | +--- org.apache.httpcomponents:httpclient-cache:4.5.6 | | | \--- org.apache.httpcomponents:httpclient:4.5.6 (*) | | \--- org.apache.httpcomponents:fluent-hc:4.5.6 | | \--- org.apache.httpcomponents:httpclient:4.5.6 (*) … |
2) 중복되어 있는 라이브러리(org.apache.http..) 제거
위 로그 처럼 aar 모듈과 jar 모듈 두 곳에서 org.apache.http.. 를 사용하는 것을 볼 수 있다. (참고로, apk에서도 사용중인데 나오지 않는다. 아마도 같은 프로젝트 내에서 빌드해서 잡히지 않는 것 같다. 여기서 포인트는 동일한 library가 여러곳에서 중복되서 사용된다는 것이다.) Eclipse 프로젝트에서 java 테스트 코드를 실행하면 문제 없었지만, Android Studio에서는 이 jar를 같이 dependency로 포함해서 빌드하면 에러가 발생하는 것 같다. (참고로, aar에서 있는 http를 없애고 Eclipse에 있는 jsonld-java만 남겨도 에러가 발생한다.) 현재, 내 상황에서 Eclipse에서 사용하는 jsonld-java library를 사용하지 않아도 되므로 이를 Dependency 목록에서 제거한 후, 다시 빌드해서 최종 apk 빌드할 때 발생했던 오류를 없앨 수 있었다.
Program type already present 에러의 근본적인 해결책은 빌드할때 사용하려는 의존성으로 있는 모든 라이브러리들을 직접 확인해 보고 충돌부분을 찾아서 해결해주어야 한다는 것이다.