問題描述
昨天同事在項(xiàng)目中集成一個(gè) aar 文件時(shí)遇到編譯報(bào)錯(cuò)的問題,搜遍網(wǎng)絡(luò)也沒找到解決方案,最后抱著試試的心態(tài)發(fā)郵件給Google Jack team,意外的收到了回復(fù),解決了問題,給 Jack team 大大的贊。
aar(android archive)是Android項(xiàng)目的二進(jìn)制歸檔文件,關(guān)于aar跟jar包的區(qū)別大家可以自行搜索。aar 文件的集成主要有 Android studio 環(huán)境下的集成和源碼環(huán)境下的集成,我們關(guān)注的是后者。集成方案參考這篇文章 Android.mk引用aar文件。
Android.mk 修改如下:
+LOCAL_STATIC_JAVA_AAR_LIBRARIES += libsmf
+LOCAL_AAPT_FLAGS := --auto-add-overlay --extra-packages com.sprint.ms.smf
+
@@ -32,12 +37,24 @@ include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
com.redbend.android:libs/com.redbend.android.jar \
- com.redbend.vdm.comm:libs/com.redbend.vdm.comm.jar
+ com.redbend.vdm.comm:libs/com.redbend.vdm.comm.jar \
+ libsmf:libs/libsmf-4.7.3.aar
編譯報(bào)錯(cuò)如下:
com.android.sched.scheduler.RunnerProcessException: Error during 'CodeItemBuilder' runner on 'public java.util.List com.sprint.ms.smf.messaging.ShortCodeManager.getShortCodeInfo(@android.support.annotation.NonNull() com.sprint.ms.smf.oauth.OAuthToken token, java.lang.String mdn) (SourceFile:106-153)': no mapping specified for register
at com.android.sched.scheduler.ScheduleInstance.runWithLog(ScheduleInstance.java:163)
at com.android.sched.scheduler.MultiWorkersScheduleInstance$SequentialTask.process(MultiWorkersScheduleInstance.java:442)
at com.android.sched.scheduler.MultiWorkersScheduleInstance$Worker.run(MultiWorkersScheduleInstance.java:162)
Caused by: java.lang.RuntimeException: no mapping specified for register
at com.android.jack.dx.ssa.BasicRegisterMapper.map(BasicRegisterMapper.java:64)
at com.android.jack.dx.ssa.RegisterMapper.map(RegisterMapper.java:53)
at com.android.jack.dx.ssa.NormalSsaInsn.mapSourceRegisters(NormalSsaInsn.java:48)
at com.android.jack.dx.ssa.SsaInsn.mapRegisters(SsaInsn.java:159)
at com.android.jack.dx.ssa.SsaMethod.mapRegisters(SsaMethod.java:389)
at com.android.jack.dx.ssa.back.SsaToRop.convert(SsaToRop.java:100)
at com.android.jack.dx.ssa.back.SsaToRop.convertToRopMethod(SsaToRop.java:61)
at com.android.jack.dx.ssa.Optimizer.optimize(Optimizer.java:107)
at com.android.jack.dx.ssa.Optimizer.optimize(Optimizer.java:71)
at com.android.jack.backend.dex.rop.CodeItemBuilder.run(CodeItemBuilder.java:373)
at com.android.jack.backend.dex.rop.CodeItemBuilder.run(CodeItemBuilder.java:116)
at com.android.sched.scheduler.ScheduleInstance.runWithLog(ScheduleInstance.java:161)
... 2 more
Internal compiler error (version 1.2-rc4 'Carnac' (298900 f95d7bdecfceb327f9d201a1348397ed8a843843 by android-jack-team@google.com)).
no mapping specified for register.
可以看到是在進(jìn)行 Jack 編譯時(shí)解析 Java8 語法報(bào)錯(cuò)。報(bào)錯(cuò)信息里很 nice 的包含了版本信息和聯(lián)系郵箱。
關(guān)于JACK
關(guān)于Jack工具的介紹可以參考這篇文章Android 新一代編譯 toolchain Jack & Jill 簡介 , 基本是對官方文檔的翻譯。
在14 March 2017,官方發(fā)布了一份廢棄Jack的聲明,原文如下:
At Google, we always try to do the right thing. Sometimes this means adjusting our plans. We know how much our Android developer community cares about good support for Java 8 language features, and we're changing the way we support them.<br />
We've decided to add support for Java 8 language features directly into the current javac and dx set of tools, and deprecate the Jack toolchain. With this new direction, existing tools and plugins dependent on the Java class file format should continue to work. Moving forward, Java 8 language features will be natively supported by the Android build system. We're aiming to launch this as part of Android Studio in the coming weeks, and we wanted to share this decision early with you.<br />
We initially tested adding Java 8 support via the Jack toolchain. Over time, we realized the cost of switching to Jack was too high for our community when we considered the annotation processors, bytecode analyzers and rewriters impacted. Thank you for trying the Jack toolchain and giving us great feedback. You can continue using Jack to build your Java 8 code until we release the new support. Migrating from Jack should require little or no work.<br />
We hope the new plan will pave a smooth path for everybody to take advantage of Java 8 language features on Android. We'll share more details when we release the new support in Android Studio.
大概意思是推行 Jack 工具遇到了極大的困難,對Java 8 特性的支持方式將轉(zhuǎn)向 javac和dx,將會在Android Studio中做相關(guān)支持。
問題解決
我們回到 Jack team 的回復(fù)(發(fā)送郵件到android-jack-team@google.com),回復(fù)如下:
Hi,
Looks like invalid debug info in a prebuilt jar, you should try to ignore the debug info of the problematic jar (the one defining com.sprint.ms.smf.messaging.ShortCodeManager).
To ignore those debug info you should add "LOCAL_JACK_FLAGS := -D jack.import.jar.debug-info=false" to the Android.mk declaring it.
If the jar is declared with a BUILD_MULTI_PREBUILT, see https://android.googlesource.com/platform/external/jetty/+/3dddeb0b1333408963a5ec550cd9cc64cd9c646d%5E%21/#F0 as an exemple how to it.
鏈接里的內(nèi)容如下:
Ignore debug info of jetty-util prebuilt<br />To workaround a Jack failure, possibly caused by malformed debug info.<br />Bug: 27242662<br />(cherry picked from commit d8b7db714ff75c37a6fe5b228a1373e9300022f0)<br />Change-Id: <br />I82bb302498abcad741a18e42f73cd2331233cc78<br />
diff --git [a/Android.mk]<br />(https://android.googlesource.com/platform/external/jetty/+/806b0b93225bdf4a36d560351642126100e1950e/Android.mk) b/Android.mkindex f7ed668..d4859ec 100644--- a/Android.mk+++ b/Android.mk
@@ -48,8 +48,18 @@ <br />
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=
servlet-api:lib/javax.servlet-3.0.0.v201112011016.jar
- jetty-util:lib/jetty-util-6.1.26.jar
slf4j-api:lib/slf4j-api-1.6.1.jar
slf4j-jdk14:lib/slf4j-jdk14-1.6.1.jar \
include $(BUILD_MULTI_PREBUILT)
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_MODULE := jetty-util
+LOCAL_SRC_FILES := lib/jetty-util-6.1.26.jar
+LOCAL_JACK_FLAGS := -D jack.import.jar.debug-info=false
+include $(BUILD_PREBUILT)
可以看到問題是jar包里無效的debug信息導(dǎo)致的,需要忽略掉debug信息。在 Android.mk 里添加 LOCAL_JACK_FLAGS := -D jack.import.jar.debug-info=false 這句;另外如果使用了 BUILD_MULTI_PREBUILT,需要將新增的 jar 改成單獨(dú)的 BUILD_PREBUILT 的形式。
嘗試了以后發(fā)現(xiàn)還是報(bào)錯(cuò),但是同事在include $(BUILD_PREBUILT)前加入了下面的語句后編譯成功。
LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX)
LOCAL_BUILT_MODULE_STEM := javalib.jar
LOCAL_UNINSTALLABLE_MODULE := false
總結(jié)
1 Jack 的目的是讓 Android 支持更多的 Java 8 特性;
2 Google 將會把 Jack 的功能轉(zhuǎn)移到 javac 和 dx 上;
3 如果遇到 Jack 相關(guān)的問題,可以郵件到 android-jack-team@google.com 咨詢;