Android 新一代编译 toolchain Jack 初探

问题描述

昨天同事在项目中集成一个 aar 文件时遇到编译报错的问题,搜遍网络也没找到解决方案,最后抱着试试的心态发邮件给Google Jack team,意外的收到了回复,解决了问题,给 Jack team 大大的赞。
  aar(android archive)是Android项目的二进制归档文件,关于aar跟jar包的区别大家可以自行搜索。aar 文件的集成主要有 Android studio 环境下的集成和源码环境下的集成,我们关注的是后者。集成方案参考这篇文章 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

编译报错如下:

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.

可以看到是在进行 Jack 编译时解析 Java8 语法报错。报错信息里很 nice 的包含了版本信息和联系邮箱。

关于JACK

关于Jack工具的介绍可以参考这篇文章Android 新一代编译 toolchain Jack & Jill 简介 , 基本是对官方文档的翻译。
  在14 March 2017,官方发布了一份废弃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 特性的支持方式将转向 javac和dx,将会在Android Studio中做相关支持。

问题解决

我们回到 Jack team 的回复(发送邮件到android-jack-team@google.com),回复如下:

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.

链接里的内容如下:

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信息导致的,需要忽略掉debug信息。在 Android.mk 里添加 LOCAL_JACK_FLAGS := -D jack.import.jar.debug-info=false 这句;另外如果使用了 BUILD_MULTI_PREBUILT,需要将新增的 jar 改成单独的 BUILD_PREBUILT 的形式。
  尝试了以后发现还是报错,但是同事在include $(BUILD_PREBUILT)前加入了下面的语句后编译成功。

LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX)
LOCAL_BUILT_MODULE_STEM := javalib.jar
LOCAL_UNINSTALLABLE_MODULE := false 

总结

1 Jack 的目的是让 Android 支持更多的 Java 8 特性;
2 Google 将会把 Jack 的功能转移到 javac 和 dx 上;
3 如果遇到 Jack 相关的问题,可以邮件到 android-jack-team@google.com 咨询;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容