[DO NOT MERGE] Compile using Jack.

This allows to compile dex targeted java sources using Jack and Jill.
Default is still to compile with the legacy toolchain. Default can be
switched to the new toolchain by setting environement variable:
export ANDROID_COMPILE_WITH_JACK=true
Toolchain can also be forced for one module by defining
LOCAL_JACK_ENABLED:=full # disabled, full, incremental
in the mk portion defining the module.

Jack execution environement can be controlled with:

Global variable ANDROID_JACK_VM allow to change the jvm executing Jack.
Global variable ANDROID_JACK_VM_ARGS allows to change default args given
to the jvm.
Global variable ANDROID_JACK_EXTRA_ARGS allows to define some default args
to give to Jack

LOCAL_JACK_VM_ARGS allows to override default args given to the jvm for
the module.
LOCAL_JACK_EXTRA_ARGS allows to override default args passed to Jack.

This includes cherry-picks of the following changes:
b4c49cba57dafdcdfb693a549c5a1dc1beb71c25
22c3fa6d73adcf14b38c7cf03446d4e2a892f682
138768c1bbb49d549c4b14281fa5f0bffac7d933
5dd3e1d31293aaaae7c0c213743a7ca77d2dd688
83d5d040479e09a3dea6b7f88ca9a57c4ae984ac
8bc90fd2d6ccf70b65d2d3aad22b0453b86a262d
140274707e31c9585aa28b0de2f1418c64ecd272
0fbc9ff2a2eed243aabaa75e911e55c4cf4b8d4c
833b427d72c91c1d1b7f8ac99fb87a6742eb6f43
f9a27f45b49f670c0258c1b6c19056ae85ac1e45
2809666941aceea4af65ec6f9cea8cce1c1392ed
37822c443d3d2ba88dd009c994f088906a0f5568
c6b44d43c38b80a52ed9ade7f9b503685dd129a7
d2a76c14bf60f45a4bf19721a09a10f758c42a66
06744f60fc48d0a33bd538497e77b624adee7d75
95573d5036e3de1ff26d1a9fc9e832c1b0a476a1
b821391614896e6156ffa3e4c2b0f4aef7e80793
2794e7b5824ba1ea5687c7dcaaf7c7062edfa2bb
801f2c44d0a919284c72eca2be708aedb3a79d88
c76d99dca10bd41a30cbfce4699866716a1d4eaf
f528e132d60fc8c982e41c242017beb6d4f7df76
76a5e0bd1abc19d9d5664a59b9602bb24e15c259
e25b3984ff5c74aa2a49d14b7df7aa9527096c32 Partially, only Jack related parts werekept
ec46a3b71f2746ec209d60ca03f6129d5b129f75
abee3a9f4171a7aaf39c743e7032721b02f43f07
77cbe10fd9c27747f98825f4923a0cfc65b28faf
daf07db4cd5d10b706164904a28323e6223b8aa3
b6bfb5893a64dc23dd4dbcbcbe62fe885bd68632

Ie all Jack related changes untill
b6bfb5893a64dc23dd4dbcbcbe62fe885bd68632
except
a96cc59ab508c1c803c15f4e5f22ab2415b6ac26 "Use Jack by default"

Change-Id: If9d47ef1c4fd1e6765ad2a47d816c1ad3cfab0e3
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 0294cf2..f3a5a81 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -418,10 +418,11 @@
 #                 be up-to-date.
 ifdef LOCAL_IS_HOST_MODULE
 ifeq ($(USE_CORE_LIB_BOOTCLASSPATH),true)
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH := -bootclasspath $(call java-lib-deps,core-libart-hostdex,$(LOCAL_IS_HOST_MODULE))
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH := -bootclasspath $(call java-lib-files,core-libart-hostdex,$(LOCAL_IS_HOST_MODULE))
 
 full_shared_java_libs := $(call java-lib-files,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
-full_java_lib_deps := $(call java-lib-deps,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
+full_java_lib_deps := $(call java-lib-deps,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE)) \
+    $(full_shared_java_libs)
 else
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH :=
 
@@ -695,6 +696,86 @@
 endif
 
 ###########################################################
+# JACK
+###########################################################
+ifdef LOCAL_JACK_ENABLED
+ifdef need_compile_java
+
+full_static_jack_libs := \
+    $(foreach lib,$(LOCAL_STATIC_JAVA_LIBRARIES), \
+      $(call intermediates-dir-for, \
+        JAVA_LIBRARIES,$(lib),$(LOCAL_IS_HOST_MODULE),COMMON)/classes.jack)
+
+ifeq ($(my_prefix),TARGET_)
+ifeq ($(LOCAL_SDK_VERSION),)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH_JAVA_LIBRARIES := $(call jack-lib-files,core-libart)
+else
+ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),current)
+# LOCAL_SDK_VERSION is current and no TARGET_BUILD_APPS.
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH_JAVA_LIBRARIES := $(call jack-lib-files,android_stubs_current)
+else ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),system_current)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH_JAVA_LIBRARIES := $(call jack-lib-files,android_system_stubs_current)
+else
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH_JAVA_LIBRARIES := $(call jack-lib-files,sdk_v$(LOCAL_SDK_VERSION))
+endif # current or system_current
+endif # LOCAL_SDK_VERSION
+endif # TARGET_
+
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_STATIC_JACK_LIBRARIES := $(full_static_jack_libs)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JACK_VM_ARGS := $(LOCAL_JACK_VM_ARGS)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JACK_EXTRA_ARGS := $(LOCAL_JACK_EXTRA_ARGS)
+
+ifdef LOCAL_IS_HOST_MODULE
+ifeq ($(USE_CORE_LIB_BOOTCLASSPATH),true)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH_JAVA_LIBRARIES := $(call jack-lib-files,core-libart-hostdex,$(LOCAL_IS_HOST_MODULE))
+full_shared_jack_libs := $(call jack-lib-files,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
+full_jack_lib_deps := $(call jack-lib-deps,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
+else
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH_JAVA_LIBRARIES :=
+full_shared_jack_libs := $(call jack-lib-deps,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
+full_jack_lib_deps := $(full_shared_jack_libs)
+endif # USE_CORE_LIB_BOOTCLASSPATH
+else # !LOCAL_IS_HOST_MODULE
+full_shared_jack_libs := $(call jack-lib-files,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
+full_jack_lib_deps := $(call jack-lib-deps,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
+endif # !LOCAL_IS_HOST_MODULE
+full_jack_libs := $(full_shared_jack_libs) $(full_static_jack_libs) $(LOCAL_JACK_CLASSPATH)
+full_jack_lib_deps += $(full_static_jack_libs) $(LOCAL_JACK_CLASSPATH)
+
+# This is set by packages that are linking to other packages that export
+# shared libraries, allowing them to make use of the code in the linked apk.
+ifneq ($(apk_libraries),)
+  link_apk_jack_libraries := \
+      $(foreach lib,$(apk_libraries), \
+        $(call intermediates-dir-for, \
+              APPS,$(lib),,COMMON)/classes.jack)
+
+  # link against the jar with full original names (before proguard processing).
+  full_shared_jack_libs += $(link_apk_jack_libraries)
+  full_jack_libs += $(link_apk_jack_libraries)
+  full_jack_lib_deps += $(link_apk_jack_libraries)
+endif
+
+# This is set by packages that contain instrumentation, allowing them to
+# link against the package they are instrumenting.  Currently only one such
+# package is allowed.
+ifdef LOCAL_INSTRUMENTATION_FOR
+
+   # link against the jar with full original names (before proguard processing).
+   link_instr_classes_jack := $(link_instr_intermediates_dir.COMMON)/classes.noshrob.jack
+   full_jack_libs += $(link_instr_classes_jack)
+   full_jack_lib_deps += $(link_instr_classes_jack)
+endif
+
+endif  # need_compile_java
+
+# Propagate local configuration options to this target.
+$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_ALL_JACK_LIBRARIES:= $(full_jack_libs)
+$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
+
+endif # LOCAL_JACK_ENABLED
+
+###########################################################
 ## NOTICE files
 ###########################################################
 
diff --git a/core/cleanbuild.mk b/core/cleanbuild.mk
index cf980d8..159d66d 100644
--- a/core/cleanbuild.mk
+++ b/core/cleanbuild.mk
@@ -247,3 +247,22 @@
   $(info *** Done with the cleaning, now starting the real build.)
 endif
 force_installclean :=
+
+.PHONY: clean-jack-files
+clean-jack-files: clean-dex-files
+	$(hide) find $(OUT_DIR) -name "*.jack" | xargs rm -f
+	$(hide) find $(OUT_DIR) -type d -name "jack" | xargs rm -rf
+	@echo "All jack files have been removed."
+
+.PHONY: clean-dex-files
+clean-dex-files:
+	$(hide) find $(OUT_DIR) -name "*.dex" ! -path "*/jack-incremental/*" | xargs rm -f
+	$(hide) for i in `find $(OUT_DIR) -name "*.jar" -o -name "*.apk"` ; do ((unzip -l $$i 2> /dev/null | \
+				grep -q "\.dex$$" && rm -f $$i) || continue ) ; done
+	@echo "All dex files and archives containing dex files have been removed."
+
+.PHONY: clean-jack-incremental
+clean-jack-incremental:
+	$(hide) find $(OUT_DIR) -name "jack-incremental" -type d | xargs rm -rf
+	@echo "All jack incremental dirs have been removed."
+
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 1357b39..ad925a6 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -74,6 +74,7 @@
 LOCAL_JAVA_LAYERS_FILE:=
 LOCAL_NO_STANDARD_LIBRARIES:=
 LOCAL_CLASSPATH:=
+LOCAL_JACK_CLASSPATH:=
 LOCAL_DROIDDOC_USE_STANDARD_DOCLET:=
 LOCAL_DROIDDOC_SOURCE_PATH:=
 LOCAL_DROIDDOC_TEMPLATE_DIR:=
@@ -107,6 +108,11 @@
 LOCAL_ADDITIONAL_JAVA_DIR:=
 LOCAL_ALLOW_UNDEFINED_SYMBOLS:=
 LOCAL_DX_FLAGS:=
+LOCAL_JACK_ENABLED:=$(DEFAULT_JACK_ENABLED) # '' (ie disabled), disabled, full, incremental
+LOCAL_JACK_VM_ARGS := $(DEFAULT_JACK_VM_ARGS)
+LOCAL_JACK_EXTRA_ARGS := $(DEFAULT_JACK_EXTRA_ARGS)
+LOCAL_JACK_FLAGS:=
+LOCAL_JILL_FLAGS:=
 LOCAL_CERTIFICATE:=
 LOCAL_SDK_VERSION:=
 LOCAL_SDK_RES_VERSION:=
@@ -114,6 +120,7 @@
 LOCAL_EMMA_INSTRUMENT:=
 LOCAL_PROGUARD_ENABLED:= # '',full,custom,nosystem,disabled,obfuscation,optimization
 LOCAL_PROGUARD_FLAGS:=
+LOCAL_JACK_PROGUARD_FLAGS:=
 LOCAL_PROGUARD_FLAG_FILES:=
 LOCAL_TEST_MODULE_TO_PROGUARD_WITH:=
 LOCAL_EMMA_COVERAGE_FILTER:=
diff --git a/core/config.mk b/core/config.mk
index 83295d9..502dd7a 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -131,6 +131,12 @@
 # list of flags to turn specific warnings in to errors
 TARGET_ERROR_FLAGS := -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point
 
+ifdef TMPDIR
+JAVA_TMPDIR_ARG := -Djava.io.tmpdir=$(TMPDIR)
+else
+JAVA_TMPDIR_ARG :=
+endif
+
 # ###############################################################
 # Include sub-configuration files
 # ###############################################################
@@ -365,6 +371,11 @@
 
 # ---------------------------------------------------------------
 # Generic tools.
+JACK := $(HOST_OUT_EXECUTABLES)/jack
+JACK_JAR := $(HOST_OUT_JAVA_LIBRARIES)/jack.jar
+JACK_LAUNCHER_JAR := $(HOST_OUT_JAVA_LIBRARIES)/jack-launcher.jar
+JILL_JAR := $(HOST_OUT_JAVA_LIBRARIES)/jill.jar
+JACK_MULTIDEX_DEFAULT_PREPROCESSOR := frameworks/multidex/library/resources/JACK-INF/legacyMultidexInstallation.jpp
 
 LEX := prebuilts/misc/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/flex/flex-2.5.39
 # The default PKGDATADIR built in the prebuilt bison is a relative path
@@ -408,6 +419,42 @@
 TUNE2FS := $(HOST_OUT_EXECUTABLES)/tune2fs$(HOST_EXECUTABLE_SUFFIX)
 E2FSCK := $(HOST_OUT_EXECUTABLES)/e2fsck$(HOST_EXECUTABLE_SUFFIX)
 JARJAR := $(HOST_OUT_JAVA_LIBRARIES)/jarjar.jar
+
+ifeq ($(ANDROID_COMPILE_WITH_JACK),true)
+DEFAULT_JACK_ENABLED:=full
+else
+DEFAULT_JACK_ENABLED:=
+endif
+ifneq ($(strip $(ANDROID_JACK_VM)),)
+JACK_VM := $(ANDROID_JACK_VM)
+else
+JACK_VM := java
+endif
+# call jack
+#
+# $(1): vm arguments
+# $(2): jack perf arguments
+ifneq (,$(strip $(filter dist,$(MAKECMDGOALS))))
+JACK_SERVER_LOG_COMMAND := mkdir -p $(DIST_DIR)/logs/; SERVER_LOG=$(DIST_DIR)/logs/jack-server.log
+endif
+define call-jack
+$(JACK_SERVER_LOG_COMMAND) JACK_VM_COMMAND="$(JACK_VM) $(1) $(JAVA_TMPDIR_ARG) -jar $(JACK_LAUNCHER_JAR) " JACK_JAR="$(JACK_JAR)" $(JACK) $(2)
+endef
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JACK_VM_ARGS := $(DEFAULT_JACK_VM_ARGS)
+ifneq ($(ANDROID_JACK_VM_ARGS),)
+DEFAULT_JACK_VM_ARGS := $(ANDROID_JACK_VM_ARGS)
+else
+DEFAULT_JACK_VM_ARGS := -Dfile.encoding=UTF-8 -Xms2560m -XX:+TieredCompilation
+endif
+ifneq ($(ANDROID_JACK_EXTRA_ARGS),)
+DEFAULT_JACK_EXTRA_ARGS := $(ANDROID_JACK_EXTRA_ARGS)
+else
+DEFAULT_JACK_EXTRA_ARGS := @$(BUILD_SYSTEM)/jack-default.args
+endif
+# Turn off jack warnings by default.
+DEFAULT_JACK_EXTRA_ARGS += --verbose error
+
+JILL := java -jar $(JILL_JAR)
 PROGUARD := external/proguard/bin/proguard.sh
 JAVATAGS := build/tools/java-event-log-tags.py
 LLVM_RS_CC := $(HOST_OUT_EXECUTABLES)/llvm-rs-cc$(HOST_EXECUTABLE_SUFFIX)
diff --git a/core/configure_local_jack.mk b/core/configure_local_jack.mk
new file mode 100644
index 0000000..98b13d2
--- /dev/null
+++ b/core/configure_local_jack.mk
@@ -0,0 +1,30 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+ifdef ANDROID_FORCE_JACK_ENABLED
+LOCAL_JACK_ENABLED := $(ANDROID_FORCE_JACK_ENABLED)
+endif
+LOCAL_JACK_ENABLED := $(strip $(LOCAL_JACK_ENABLED))
+ifneq ($(LOCAL_JACK_ENABLED),full)
+ifneq ($(LOCAL_JACK_ENABLED),incremental)
+ifdef LOCAL_JACK_ENABLED
+ifneq ($(LOCAL_JACK_ENABLED),disabled)
+$(error $(LOCAL_PATH): invalid LOCAL_JACK_ENABLED "$(LOCAL_JACK_ENABLED)" for $(LOCAL_MODULE))
+endif
+endif
+LOCAL_JACK_ENABLED :=
+endif
+endif
diff --git a/core/definitions.mk b/core/definitions.mk
index b6e5277..6bb3a99 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -403,6 +403,14 @@
 endef
 
 ###########################################################
+## Reverse order of a list
+###########################################################
+
+define reverse-list
+$(if $(1),$(call reverse-list,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1))
+endef
+
+###########################################################
 ## The intermediates directory.  Where object files go for
 ## a given target.  We could technically get away without
 ## the "_intermediates" suffix on the directory, but it's
@@ -602,6 +610,36 @@
 endef
 
 ###########################################################
+## Convert "core ext framework" to "out/.../classes.jack ..."
+## $(1): library list
+## $(2): Non-empty if IS_HOST_MODULE
+###########################################################
+
+# $(1): library name
+# $(2): Non-empty if IS_HOST_MODULE
+define _jack-lib-full-classes
+$(call _java-lib-dir,$(1),$(2))/classes.jack
+endef
+
+# $(1): library name list
+# $(2): Non-empty if IS_HOST_MODULE
+define jack-lib-files
+$(foreach lib,$(1),$(call _jack-lib-full-classes,$(lib),$(2)))
+endef
+
+# $(1): library name
+# $(2): Non-empty if IS_HOST_MODULE
+define _jack-lib-full-dep
+$(call _jack-lib-full-classes,$(1),$(2))
+endef
+
+# $(1): library name list
+# $(2): Non-empty if IS_HOST_MODULE
+define jack-lib-deps
+$(foreach lib,$(1),$(call _jack-lib-full-dep,$(lib),$(2)))
+endef
+
+###########################################################
 ## Run rot13 on a string
 ## $(1): the string.  Must be one line.
 ###########################################################
@@ -1759,6 +1797,146 @@
 $(call compile-java,$(TARGET_JAVAC),$(PRIVATE_BOOTCLASSPATH))
 endef
 
+# Invoke Jack to compile java from source to dex and jack files.
+#
+# Some historical notes:
+# - below we write the list of java files to java-source-list to avoid argument
+#   list length problems with Cygwin
+# - we filter out duplicate java file names because Jack doesn't like them.
+# TODO (yroussel) PRIVATE_RMTYPEDEFS
+define jack-java-to-dex
+$(hide) rm -f $@
+$(hide) rm -f $(PRIVATE_CLASSES_JACK)
+$(hide) rm -rf $(PRIVATE_JACK_INTERMEDIATES_DIR)
+$(hide) mkdir -p $(dir $@)
+$(hide) mkdir -p $(dir $(PRIVATE_CLASSES_JACK))
+$(hide) mkdir -p $(PRIVATE_JACK_INTERMEDIATES_DIR)
+$(if $(PRIVATE_JACK_INCREMENTAL_DIR),$(hide) mkdir -p $(PRIVATE_JACK_INCREMENTAL_DIR))
+$(call dump-words-to-file,$(PRIVATE_JAVA_SOURCES),$(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list)
+$(hide) if [ -d "$(PRIVATE_SOURCE_INTERMEDIATES_DIR)" ]; then \
+          find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) -name '*.java' >> $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list; \
+fi
+$(hide) tr ' ' '\n' < $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list \
+    | sort -u > $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list-uniq
+$(if $(PRIVATE_JACK_PROGUARD_FLAGS), \
+    $(hide) echo -basedirectory $(CURDIR) > $@.flags; \
+    echo $(PRIVATE_JACK_PROGUARD_FLAGS) >> $@.flags; \
+)
+$(if $(PRIVATE_EXTRA_JAR_ARGS),
+    $(hide) mkdir -p $@.res.tmp
+    $(hide) $(call create-empty-package-at,$@.res.tmp.zip)
+    $(hide) $(call add-java-resources-to,$@.res.tmp.zip)
+    $(hide) $(call unzip-jar-files,$@.res.tmp.zip,$@.res.tmp)
+    $(hide) rm $@.res.tmp.zip)
+$(hide) if [ -s $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list-uniq ] ; then \
+    export tmpEcjArg="@$(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list-uniq"; \
+else \
+    export tmpEcjArg=""; \
+fi; \
+$(call call-jack,$(PRIVATE_JACK_VM_ARGS),$(PRIVATE_JACK_EXTRA_ARGS)) \
+    $(strip $(PRIVATE_JACK_FLAGS)) \
+    $(strip $(PRIVATE_JACK_DEBUG_FLAGS)) \
+    $(if $(NO_OPTIMIZE_DX), \
+        -D jack.dex.optimize="false") \
+    $(addprefix --classpath ,$(strip \
+        $(call normalize-path-list,$(PRIVATE_BOOTCLASSPATH_JAVA_LIBRARIES) $(PRIVATE_ALL_JACK_LIBRARIES)))) \
+    $(addprefix --import ,$(call reverse-list,$(PRIVATE_STATIC_JACK_LIBRARIES))) \
+    $(if $(PRIVATE_EXTRA_JAR_ARGS),--import-resource $@.res.tmp) \
+    -D jack.import.resource.policy=keep-first \
+    -D jack.import.type.policy=keep-first \
+    --output-jack $(PRIVATE_CLASSES_JACK) \
+    -D jack.java.source.version=1.7 \
+    $(if $(PRIVATE_JACK_INCREMENTAL_DIR),--incremental-folder $(PRIVATE_JACK_INCREMENTAL_DIR)) \
+    --output-dex $(PRIVATE_JACK_INTERMEDIATES_DIR) \
+    $(addprefix --config-jarjar ,$(strip $(PRIVATE_JARJAR_RULES))) \
+    $(if $(PRIVATE_JACK_PROGUARD_FLAGS),--config-proguard $@.flags) \
+    $$tmpEcjArg \
+    || ( rm -rf $(PRIVATE_CLASSES_JACK); rm -rf $(PRIVATE_JACK_INTERMEDIATES_DIR); exit 41 )
+$(hide) mv $(PRIVATE_JACK_INTERMEDIATES_DIR)/classes*.dex $(dir $@)
+$(hide) rm -f $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list
+$(if $(PRIVATE_EXTRA_JAR_ARGS),$(hide) rm -rf $@.res.tmp)
+$(hide) mv $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list-uniq $(PRIVATE_JACK_INTERMEDIATES_DIR).java-source-list
+$(if $(PRIVATE_JAR_PACKAGES), $(hide) echo unsupported options PRIVATE_JAR_PACKAGES in $@; exit 53)
+$(if $(PRIVATE_JAR_EXCLUDE_PACKAGES), $(hide) echo unsupported options JAR_EXCLUDE_PACKAGES in $@; exit 53)
+$(if $(PRIVATE_JAR_MANIFEST), $(hide) echo unsupported options JAR_MANIFEST in $@; exit 53)
+endef
+
+define transform-jar-to-jack
+	$(hide) mkdir -p $(dir $@)
+	$(JILL) $(PRIVATE_JILL_FLAGS) --output $@.tmpjill.jack $<
+	$(hide) mkdir -p $@.tmpjill.res
+	$(hide) $(call unzip-jar-files,$<,$@.tmpjill.res)
+	$(hide) find $@.tmpjill.res -iname "*.class" -delete
+	$(hide) $(call call-jack,$(PRIVATE_JACK_VM_ARGS),$(PRIVATE_JACK_EXTRA_ARGS)) \
+        -D jack.import.resource.policy=keep-first \
+        -D jack.import.type.policy=keep-first \
+	    --import $@.tmpjill.jack \
+	    --import-resource $@.tmpjill.res \
+	    --output-jack $@
+	$(hide) rm -rf $@.tmpjill.res
+	$(hide) rm $@.tmpjill.jack
+endef
+
+
+# Invoke Jack to compile java from source to jack files without shrink or obfuscation.
+#
+# Some historical notes:
+# - below we write the list of java files to java-source-list to avoid argument
+#   list length problems with Cygwin
+# - we filter out duplicate java file names because Jack doesn't like them.
+define java-to-jack
+$(hide) rm -f $@
+$(hide) rm -rf $(PRIVATE_JACK_INTERMEDIATES_DIR)
+$(hide) mkdir -p $(dir $@)
+$(hide) mkdir -p $(PRIVATE_JACK_INTERMEDIATES_DIR)
+$(if $(PRIVATE_JACK_INCREMENTAL_DIR),$(hide) mkdir -p $(PRIVATE_JACK_INCREMENTAL_DIR))
+$(call dump-words-to-file,$(PRIVATE_JAVA_SOURCES),$(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list)
+$(hide) if [ -d "$(PRIVATE_SOURCE_INTERMEDIATES_DIR)" ]; then \
+          find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) -name '*.java' >> $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list; \
+fi
+$(hide) tr ' ' '\n' < $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list \
+    | sort -u > $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list-uniq
+$(if $(PRIVATE_JACK_PROGUARD_FLAGS), \
+    $(hide) echo -basedirectory $(CURDIR) > $@.flags; \
+    echo $(PRIVATE_JACK_PROGUARD_FLAGS) >> $@.flags; \
+)
+$(if $(PRIVATE_EXTRA_JAR_ARGS),
+	$(hide) mkdir -p $@.res.tmp
+	$(hide) $(call create-empty-package-at,$@.res.tmp.zip)
+	$(hide) $(call add-java-resources-to,$@.res.tmp.zip)
+	$(hide) unzip -qo $@.res.tmp.zip -d $@.res.tmp
+	$(hide) rm $@.res.tmp.zip)
+$(hide) if [ -s $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list-uniq ] ; then \
+    export tmpEcjArg="@$(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list-uniq"; \
+else \
+    export tmpEcjArg=""; \
+fi; \
+$(call call-jack,$(PRIVATE_JACK_VM_ARGS),$(PRIVATE_JACK_EXTRA_ARGS)) \
+    $(strip $(PRIVATE_JACK_FLAGS)) \
+    $(strip $(PRIVATE_JACK_DEBUG_FLAGS)) \
+    $(if $(NO_OPTIMIZE_DX), \
+        -D jack.dex.optimize="false") \
+    $(addprefix --classpath ,$(strip \
+        $(call normalize-path-list,$(PRIVATE_BOOTCLASSPATH_JAVA_LIBRARIES) $(PRIVATE_ALL_JACK_LIBRARIES)))) \
+    $(addprefix --import ,$(call reverse-list,$(PRIVATE_STATIC_JACK_LIBRARIES))) \
+    $(if $(PRIVATE_EXTRA_JAR_ARGS),--import-resource $@.res.tmp) \
+    -D jack.import.resource.policy=keep-first \
+    -D jack.import.type.policy=keep-first \
+    -D jack.java.source.version=1.7 \
+    $(if $(PRIVATE_JACK_INCREMENTAL_DIR),--incremental-folder $(PRIVATE_JACK_INCREMENTAL_DIR)) \
+    --output-jack $@ \
+    $(addprefix --config-jarjar ,$(strip $(PRIVATE_JARJAR_RULES))) \
+    $(if $(PRIVATE_JACK_PROGUARD_FLAGS),--config-proguard $@.flags) \
+    $$tmpEcjArg \
+    || ( rm -f $@ ; exit 41 )
+$(hide) rm -f $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list
+$(if $(PRIVATE_EXTRA_JAR_ARGS),$(hide) rm -rf $@.res.tmp)
+$(hide) mv $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list-uniq $(PRIVATE_JACK_INTERMEDIATES_DIR).java-source-list
+$(if $(PRIVATE_JAR_PACKAGES), $(hide) echo unsupported options PRIVATE_JAR_PACKAGES in $@; exit 53)
+$(if $(PRIVATE_JAR_EXCLUDE_PACKAGES), $(hide) echo unsupported options JAR_EXCLUDE_PACKAGES in $@; exit 53)
+$(if $(PRIVATE_JAR_MANIFEST), $(hide) echo unsupported options JAR_MANIFEST in $@; exit 53)
+endef
+
 # Override the above definitions if we want to do incremetal javac
 ifeq (true, $(ENABLE_INCREMENTALJAVAC))
 define compile-java
@@ -1852,12 +2030,31 @@
 # Create a mostly-empty .jar file that we'll add to later.
 # The MacOS jar tool doesn't like creating empty jar files,
 # so we need to give it something.
+# $(1) package to create
+define create-empty-package-at
+@mkdir -p $(dir $(1))
+$(hide) touch $(dir $(1))dummy
+$(hide) (cd $(dir $(1)) && jar cf $(notdir $(1)) dummy)
+$(hide) zip -qd $(1) dummy
+$(hide) rm $(dir $(1))dummy
+endef
+
+# Create a mostly-empty .jar file that we'll add to later.
+# The MacOS jar tool doesn't like creating empty jar files,
+# so we need to give it something.
 define create-empty-package
-@mkdir -p $(dir $@)
-$(hide) touch $(dir $@)zipdummy
-$(hide) (cd $(dir $@) && jar cf $(notdir $@) zipdummy)
-$(hide) zip -qd $@ zipdummy
-$(hide) rm $(dir $@)zipdummy
+@mkdir -p $(dir $(1))
+$(hide) touch $(dir $(1))zipdummy
+$(hide) (cd $(dir $(1)) && jar cf $(notdir $(1)) zipdummy)
+$(hide) zip -qd $(1) zipdummy
+$(hide) rm $(dir $(1))zipdummy
+endef
+
+# Create a mostly-empty .jar file that we'll add to later.
+# The MacOS jar tool doesn't like creating empty jar files,
+# so we need to give it something.
+define create-empty-package
+$(call create-empty-package-at,$@)
 endef
 
 # Copy an arhchive file and delete any class files and empty folders inside.
@@ -1931,6 +2128,19 @@
 @rm -f $(1).jar-arg-list
 endef
 
+# Add resources carried by static Jack libraries.
+#
+define add-carried-jack-resources
+ $(hide) if [ -d $(PRIVATE_JACK_INTERMEDIATES_DIR) ] ; then \
+    jack_res_jar_flags=$$(find $(PRIVATE_JACK_INTERMEDIATES_DIR) -type f \
+        | sed -e "s?^$(PRIVATE_JACK_INTERMEDIATES_DIR)/? -C $(PRIVATE_JACK_INTERMEDIATES_DIR) ?"); \
+    if [ -n "$$jack_res_jar_flags" ] ; then \
+        echo $$jack_res_jar_flags >$(dir $@)jack_res_jar_flags; \
+        jar uf $@ $$jack_res_jar_flags; \
+    fi; \
+fi
+endef
+
 # Sign a package using the specified key/cert.
 #
 define sign-package
diff --git a/core/dpi_specific_apk.mk b/core/dpi_specific_apk.mk
index 06e498d..5d0b5bf 100644
--- a/core/dpi_specific_apk.mk
+++ b/core/dpi_specific_apk.mk
@@ -25,24 +25,35 @@
 $(built_dpi_apk): PRIVATE_MANIFEST_INSTRUMENTATION_FOR := $(LOCAL_INSTRUMENTATION_FOR)
 $(built_dpi_apk): PRIVATE_JNI_SHARED_LIBRARIES := $(jni_shared_libraries_with_abis)
 $(built_dpi_apk): PRIVATE_JNI_SHARED_LIBRARIES_ABI := $(jni_shared_libraries_abis)
-$(built_dpi_apk): PRIVATE_DEX_FILE := $(built_dex)
-# Note that PRIVATE_CLASS_INTERMEDIATES_DIR points to the base apk's intermediate dir.
-$(built_dpi_apk): PRIVATE_CLASS_INTERMEDIATES_DIR := $(intermediates)/classes
-$(built_dpi_apk): PRIVATE_EXTRA_JAR_ARGS := $(extra_jar_args)
 $(built_dpi_apk): PRIVATE_PRIVATE_KEY := $(private_key)
 $(built_dpi_apk): PRIVATE_CERTIFICATE := $(certificate)
 $(built_dpi_apk): PRIVATE_ADDITIONAL_CERTIFICATES := $(foreach c,\
     $(LOCAL_ADDITIONAL_CERTIFICATES), $(c).x509.pem $(c).pk8)
 
+$(built_dpi_apk): PRIVATE_SOURCE_ARCHIVE :=
+ifneq ($(full_classes_jar),)
+$(built_dpi_apk): PRIVATE_DEX_FILE := $(built_dex)
+ifndef LOCAL_JACK_ENABLED
+# Use the jarjar processed arhive as the initial package file.
+$(built_dpi_apk): PRIVATE_SOURCE_ARCHIVE := $(full_classes_jarjar_jar)
+else
+$(built_dpi_apk): PRIVATE_JACK_INTERMEDIATES_DIR := $(intermediates.COMMON)/jack-rsc
+endif # LOCAL_JACK_ENABLED
+$(built_dpi_apk): $(built_dex)
+else
+$(built_dpi_apk): PRIVATE_DEX_FILE :=
+endif # full_classes_jar
+
 # Set up dependenncies and the build recipe.
 $(built_dpi_apk) : $(R_file_stamp)
 $(built_dpi_apk) : $(all_library_res_package_export_deps)
-$(built_dpi_apk) : $(built_dex)
 $(built_dpi_apk) : $(private_key) $(certificate) $(SIGNAPK_JAR)
 $(built_dpi_apk) : $(AAPT) | $(ZIPALIGN)
 $(built_dpi_apk) : $(all_res_assets) $(jni_shared_libraries) $(full_android_manifest)
 	@echo "target Package: $(PRIVATE_MODULE) ($@)"
-	$(create-empty-package)
+	$(if $(PRIVATE_SOURCE_ARCHIVE),\
+	  $(call initialize-package-file,$(PRIVATE_SOURCE_ARCHIVE),$@),\
+	  $(create-empty-package))
 	$(add-assets-to-package)
 ifneq ($(jni_shared_libraries),)
 	$(add-jni-shared-libs-to-package)
@@ -52,10 +63,9 @@
 	$(if $(PRIVATE_EXTRA_JAR_ARGS),$(call add-java-resources-to,$@))
 else
 	$(add-dex-to-package)
+ifdef LOCAL_JACK_ENABLED
+	$(add-carried-jack-resources)
 endif
-	$(add-carried-java-resources)
-ifneq ($(extra_jar_args),)
-	$(add-java-resources-to-package)
 endif
 	$(sign-package)
 	$(align-package)
diff --git a/core/host_dalvik_java_library.mk b/core/host_dalvik_java_library.mk
index f8264ee..ff5ee1e 100644
--- a/core/host_dalvik_java_library.mk
+++ b/core/host_dalvik_java_library.mk
@@ -34,11 +34,13 @@
 full_classes_compiled_jar := $(intermediates.COMMON)/classes-full-debug.jar
 full_classes_jarjar_jar := $(intermediates.COMMON)/classes-jarjar.jar
 full_classes_jar := $(intermediates.COMMON)/classes.jar
+full_classes_jack := $(intermediates.COMMON)/classes.jack
 built_dex := $(intermediates.COMMON)/classes.dex
 
 LOCAL_INTERMEDIATE_TARGETS += \
     $(full_classes_compiled_jar) \
     $(full_classes_jarjar_jar) \
+    $(full_classes_jack) \
     $(full_classes_jar) \
     $(built_dex)
 
@@ -96,6 +98,7 @@
 	@echo Copying: $@
 	$(hide) $(ACP) -fp $< $@
 
+ifndef LOCAL_JACK_ENABLED
 $(built_dex): PRIVATE_INTERMEDIATES_DIR := $(intermediates.COMMON)
 $(built_dex): PRIVATE_DX_FLAGS := $(LOCAL_DX_FLAGS)
 $(built_dex): $(full_classes_jar) $(DX)
@@ -109,6 +112,42 @@
 	$(call initialize-package-file,$(PRIVATE_SOURCE_ARCHIVE),$@)
 	$(add-dex-to-package)
 
+else # LOCAL_JACK_ENABLED
+$(LOCAL_INTERMEDIATE_TARGETS): \
+	PRIVATE_JACK_INTERMEDIATES_DIR := $(intermediates.COMMON)/jack-rsc
+
+ifeq ($(LOCAL_JACK_ENABLED),incremental)
+$(LOCAL_INTERMEDIATE_TARGETS): \
+	PRIVATE_JACK_INCREMENTAL_DIR := $(intermediates.COMMON)/jack-incremental
+else
+$(LOCAL_INTERMEDIATE_TARGETS): \
+	PRIVATE_JACK_INCREMENTAL_DIR :=
+endif
+$(LOCAL_INTERMEDIATE_TARGETS):  PRIVATE_JACK_DEBUG_FLAGS := -g
+
+$(built_dex): PRIVATE_CLASSES_JACK := $(full_classes_jack)
+$(built_dex): PRIVATE_JACK_FLAGS := $(LOCAL_JACK_FLAGS)
+$(built_dex): $(java_sources) $(java_resource_sources) $(full_jack_lib_deps) \
+        $(jar_manifest_file) $(proto_java_sources_file_stamp) $(LOCAL_MODULE_MAKEFILE) \
+        $(LOCAL_MODULE_MAKEFILE) $(LOCAL_ADDITIONAL_DEPENDENCIES) $(JACK_JAR) $(JACK_LAUNCHER_JAR)
+	@echo Building with Jack: $@
+	$(jack-java-to-dex)
+
+# $(full_classes_jack) is just by-product of $(built_dex).
+# The dummy command was added because, without it, make misses the fact the $(built_dex) also
+# change $(full_classes_jack).
+$(full_classes_jack): $(built_dex)
+	$(hide) touch $@
+
+$(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE := $(built_dex)
+$(LOCAL_BUILT_MODULE): $(built_dex) $(java_resource_sources)
+	@echo "Host Jar: $(PRIVATE_MODULE) ($@)"
+	$(create-empty-package)
+	$(add-dex-to-package)
+	$(add-carried-jack-resources)
+
+endif # LOCAL_JACK_ENABLED
+
 USE_CORE_LIB_BOOTCLASSPATH :=
 
 endif
diff --git a/core/host_dalvik_static_java_library.mk b/core/host_dalvik_static_java_library.mk
index 9e5aaa3..90bcc12 100644
--- a/core/host_dalvik_static_java_library.mk
+++ b/core/host_dalvik_static_java_library.mk
@@ -21,11 +21,37 @@
 #
 ifeq ($(HOST_OS),linux)
 
+LOCAL_UNINSTALLABLE_MODULE := true
+LOCAL_IS_STATIC_JAVA_LIBRARY := true
 USE_CORE_LIB_BOOTCLASSPATH := true
 LOCAL_JAVA_LIBRARIES += core-libart-hostdex
 
+intermediates.COMMON := $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_MODULE),true,COMMON,)
+full_classes_jack := $(intermediates.COMMON)/classes.jack
+LOCAL_INTERMEDIATE_TARGETS += \
+    $(full_classes_jack)
+
 include $(BUILD_SYSTEM)/host_java_library.mk
+# proguard is not supported
+# *.proto files are not supported
+$(full_classes_jack): PRIVATE_JACK_FLAGS := $(LOCAL_JACK_FLAGS)
+$(full_classes_jack): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
+$(full_classes_jack): \
+	PRIVATE_JACK_INTERMEDIATES_DIR := $(intermediates.COMMON)/jack-rsc
+ifeq ($(LOCAL_JACK_ENABLED),incremental)
+$(full_classes_jack): \
+	PRIVATE_JACK_INCREMENTAL_DIR := $(intermediates.COMMON)/jack-incremental
+else
+$(full_classes_jack): \
+	PRIVATE_JACK_INCREMENTAL_DIR :=
+endif
+$(full_classes_jack): $(java_sources) $(java_resource_sources) $(full_jack_lib_deps) \
+        $(jar_manifest_file) $(layers_file) $(LOCAL_MODULE_MAKEFILE) \
+        $(LOCAL_ADDITIONAL_DEPENDENCIES) $(LOCAL_JARJAR_RULES) \
+        $(JACK_JAR) $(JACK_LAUNCHER_JAR)
+	@echo Building with Jack: $@
+	$(java-to-jack)
 
 USE_CORE_LIB_BOOTCLASSPATH :=
-
+LOCAL_IS_STATIC_JAVA_LIBRARY :=
 endif
diff --git a/core/host_java_library.mk b/core/host_java_library.mk
index b751c5f..513d185 100644
--- a/core/host_java_library.mk
+++ b/core/host_java_library.mk
@@ -58,13 +58,13 @@
 $(full_classes_emma_jar) : $(full_classes_compiled_jar) | $(EMMA_JAR)
 	$(transform-classes.jar-to-emma)
 
-$(LOCAL_BUILT_MODULE) : $(full_classes_emma_jar)
+$(built_javalib_jar) : $(full_classes_emma_jar)
 	@echo Copying: $@
 	$(hide) $(ACP) -fp $< $@
 
 else # LOCAL_EMMA_INSTRUMENT
-# Directly build into LOCAL_BUILT_MODULE.
-full_classes_compiled_jar := $(LOCAL_BUILT_MODULE)
+# Directly build into $(built_javalib_jar).
+full_classes_compiled_jar := $(built_javalib_jar)
 endif # LOCAL_EMMA_INSTRUMENT
 
 $(full_classes_compiled_jar): PRIVATE_JAVAC_DEBUG_FLAGS := -g
diff --git a/core/host_java_library_common.mk b/core/host_java_library_common.mk
index cd9e679..d077634 100644
--- a/core/host_java_library_common.mk
+++ b/core/host_java_library_common.mk
@@ -23,6 +23,22 @@
 LOCAL_IS_HOST_MODULE := true
 LOCAL_BUILT_MODULE_STEM := javalib.jar
 
+intermediates := $(call local-intermediates-dir)
+intermediates.COMMON := $(call local-intermediates-dir,COMMON)
+
+built_javalib_jar := $(intermediates)/javalib.jar
+
+#################################
+include $(BUILD_SYSTEM)/configure_local_jack.mk
+#################################
+
+ifdef LOCAL_JACK_ENABLED
+ifdef LOCAL_IS_STATIC_JAVA_LIBRARY
+LOCAL_BUILT_MODULE_STEM := classes.jack
+LOCAL_INTERMEDIATE_TARGETS += $(built_javalib_jar)
+endif
+endif
+
 # base_rules.mk looks at this
 all_res_assets :=
 
@@ -39,9 +55,6 @@
 endif
 endif
 
-intermediates := $(call local-intermediates-dir)
-intermediates.COMMON := $(call local-intermediates-dir,COMMON)
-
 LOCAL_INTERMEDIATE_SOURCE_DIR := $(intermediates.COMMON)/src
 LOCAL_JAVA_LIBRARIES := $(sort $(LOCAL_JAVA_LIBRARIES))
 
diff --git a/core/jack-default.args b/core/jack-default.args
new file mode 100644
index 0000000..8d70a82
--- /dev/null
+++ b/core/jack-default.args
@@ -0,0 +1,5 @@
+-D sched.runner=multi-threaded
+-D sched.runner.thread.kind=fixed
+-D sched.runner.thread.fixed.count=4
+--sanity-checks off
+-D jack.reporter.level.file=error=--,warning=-
\ No newline at end of file
diff --git a/core/java.mk b/core/java.mk
index fc4703c..944a685 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -112,6 +112,10 @@
 full_classes_jar := $(intermediates.COMMON)/classes.jar
 built_dex := $(intermediates.COMMON)/classes.dex
 endif
+# final Jack library, shrinked and obfuscated if it must be
+full_classes_jack := $(intermediates.COMMON)/classes.jack
+# intermediate Jack library without shrink and obfuscation
+noshrob_classes_jack := $(intermediates.COMMON)/classes.noshrob.jack
 
 LOCAL_INTERMEDIATE_TARGETS += \
     $(full_classes_compiled_jar) \
@@ -120,6 +124,8 @@
     $(full_classes_jar) \
     $(full_classes_proguard_jar) \
     $(built_dex_intermediate) \
+    $(full_classes_jack) \
+    $(noshrob_classes_jack) \
     $(built_dex) \
     $(full_classes_stubs_jar)
 
@@ -338,7 +344,7 @@
 # - This extra copy, with the dependency on LOCAL_BUILT_MODULE allows the
 #   PRIVATE_ vars to be preserved.
 $(full_classes_stubs_jar): PRIVATE_SOURCE_FILE := $(full_classes_jar)
-$(full_classes_stubs_jar) : $(LOCAL_BUILT_MODULE) | $(ACP)
+$(full_classes_stubs_jar) : $(full_classes_jar) | $(ACP)
 	@echo Copying $(PRIVATE_SOURCE_FILE)
 	$(hide) $(ACP) -fp $(PRIVATE_SOURCE_FILE) $@
 ALL_MODULES.$(LOCAL_MODULE).STUBS := $(full_classes_stubs_jar)
@@ -424,50 +430,57 @@
     $(error invalid value for LOCAL_PROGUARD_ENABLED: $(LOCAL_PROGUARD_ENABLED))
 endif
 proguard_dictionary := $(intermediates.COMMON)/proguard_dictionary
-proguard_flags := $(addprefix -libraryjars ,$(full_shared_java_libs)) \
+# jack already has the libraries in its classpath and doesn't support jars
+legacy_proguard_flags := $(addprefix -libraryjars ,$(full_shared_java_libs))
+common_proguard_flags :=  \
                   -forceprocessing \
                   -printmapping $(proguard_dictionary)
 
 ifeq ($(filter nosystem,$(LOCAL_PROGUARD_ENABLED)),)
-proguard_flags += -include $(BUILD_SYSTEM)/proguard.flags
+common_proguard_flags += -include $(BUILD_SYSTEM)/proguard.flags
 ifeq ($(LOCAL_EMMA_INSTRUMENT),true)
-proguard_flags += -include $(BUILD_SYSTEM)/proguard.emma.flags
+common_proguard_flags += -include $(BUILD_SYSTEM)/proguard.emma.flags
 endif
 # If this is a test package, add proguard keep flags for tests.
 ifneq ($(LOCAL_INSTRUMENTATION_FOR)$(filter tests,$(LOCAL_MODULE_TAGS)),)
-proguard_flags += -include $(BUILD_SYSTEM)/proguard_tests.flags
+common_proguard_flags += -include $(BUILD_SYSTEM)/proguard_tests.flags
 ifeq ($(filter shrinktests,$(LOCAL_PROGUARD_ENABLED)),)
-proguard_flags += -dontshrink # don't shrink tests by default
+common_proguard_flags += -dontshrink # don't shrink tests by default
 endif # shrinktests
 endif # test package
 ifeq ($(filter obfuscation,$(LOCAL_PROGUARD_ENABLED)),)
 # By default no obfuscation
-proguard_flags += -dontobfuscate
+common_proguard_flags += -dontobfuscate
 endif  # No obfuscation
 ifeq ($(filter optimization,$(LOCAL_PROGUARD_ENABLED)),)
 # By default no optimization
-proguard_flags += -dontoptimize
+common_proguard_flags += -dontoptimize
 endif  # No optimization
 
 ifdef LOCAL_INSTRUMENTATION_FOR
 ifeq ($(filter obfuscation,$(LOCAL_PROGUARD_ENABLED)),)
 # If no obfuscation, link in the instrmented package's classes.jar as a library.
 # link_instr_classes_jar is defined in base_rule.mk
-proguard_flags += -libraryjars $(link_instr_classes_jar)
+# jack already has this library in its classpath and doesn't support jars
+legacy_proguard_flags += -libraryjars $(link_instr_classes_jar)
 else # obfuscation
 # If obfuscation is enabled, the main app must be obfuscated too.
 # We need to run obfuscation using the main app's dictionary,
 # and treat the main app's class.jar as injars instead of libraryjars.
-proguard_flags := -injars  $(link_instr_classes_jar) \
+legacy_proguard_flags := -injars  $(link_instr_classes_jar) \
     -outjars $(intermediates.COMMON)/proguard.$(LOCAL_INSTRUMENTATION_FOR).jar \
     -include $(link_instr_intermediates_dir.COMMON)/proguard_options \
     -applymapping $(link_instr_intermediates_dir.COMMON)/proguard_dictionary \
     -verbose \
-    $(proguard_flags)
+    $(legacy_proguard_flags)
+# not supported with jack
+ifdef LOCAL_JACK_ENABLED
+    $(error $(LOCAL_MODULE): Build with jack of instrumentation when obfuscating is not yet supported)
+endif
 
 # Sometimes (test + main app) uses different keep rules from the main app -
 # apply the main app's dictionary anyway.
-proguard_flags += -ignorewarnings
+legacy_proguard_flags += -ignorewarnings
 
 # Make sure we run Proguard on the main app first
 $(full_classes_proguard_jar) : $(link_instr_intermediates_dir.COMMON)/proguard.classes.jar
@@ -485,7 +498,7 @@
 extra_input_jar :=
 endif
 $(full_classes_proguard_jar): PRIVATE_EXTRA_INPUT_JAR := $(extra_input_jar)
-$(full_classes_proguard_jar): PRIVATE_PROGUARD_FLAGS := $(proguard_flags) $(LOCAL_PROGUARD_FLAGS)
+$(full_classes_proguard_jar): PRIVATE_PROGUARD_FLAGS := $(legacy_proguard_flags) $(common_proguard_flags) $(LOCAL_PROGUARD_FLAGS)
 $(full_classes_proguard_jar) : $(full_classes_jar) $(extra_input_jar) $(proguard_flag_files) | $(ACP) $(PROGUARD)
 	$(call transform-jar-to-proguard)
 
@@ -496,7 +509,7 @@
 
 endif # LOCAL_PROGUARD_ENABLED defined
 
-
+ifndef LOCAL_JACK_ENABLED
 # Override PRIVATE_INTERMEDIATES_DIR so that install-dex-debug
 # will work even when intermediates != intermediates.COMMON.
 $(built_dex_intermediate): PRIVATE_INTERMEDIATES_DIR := $(intermediates.COMMON)
@@ -512,6 +525,8 @@
 endif
 $(built_dex_intermediate): $(full_classes_proguard_jar) $(DX)
 	$(transform-classes.jar-to-dex)
+endif # LOCAL_JACK_ENABLED is disabled
+
 $(built_dex): $(built_dex_intermediate) | $(ACP)
 	@echo Copying: $@
 	$(hide) mkdir -p $(dir $@)
@@ -522,17 +537,14 @@
 endif
 
 findbugs_xml := $(intermediates.COMMON)/findbugs.xml
-$(findbugs_xml) : PRIVATE_JAR_FILE := $(full_classes_jar)
 $(findbugs_xml) : PRIVATE_AUXCLASSPATH := $(addprefix -auxclasspath ,$(strip \
 								$(call normalize-path-list,$(filter %.jar,\
 										$(full_java_libs)))))
-# We can't depend directly on full_classes_jar because the PRIVATE_
-# vars won't be set up correctly.
-$(findbugs_xml) : $(LOCAL_BUILT_MODULE)
+$(findbugs_xml) : $(full_classes_jar)
 	@echo Findbugs: $@
 	$(hide) $(FINDBUGS) -textui -effort:min -xml:withMessages \
 		$(PRIVATE_AUXCLASSPATH) \
-		$(PRIVATE_JAR_FILE) \
+		$< \
 		> $@
 
 ALL_FINDBUGS_FILES += $(findbugs_xml)
@@ -549,3 +561,72 @@
 $(LOCAL_MODULE)-findbugs : $(findbugs_html)
 
 endif  # full_classes_jar is defined
+
+ifdef LOCAL_JACK_ENABLED
+$(LOCAL_INTERMEDIATE_TARGETS): \
+	PRIVATE_JACK_INTERMEDIATES_DIR := $(intermediates.COMMON)/jack-rsc
+ifeq ($(LOCAL_JACK_ENABLED),incremental)
+$(LOCAL_INTERMEDIATE_TARGETS): \
+	PRIVATE_JACK_INCREMENTAL_DIR := $(intermediates.COMMON)/jack-incremental
+else
+$(LOCAL_INTERMEDIATE_TARGETS): \
+	PRIVATE_JACK_INCREMENTAL_DIR :=
+endif
+
+ifdef full_classes_jar
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JACK_DEBUG_FLAGS := -g
+
+ifdef LOCAL_PROGUARD_ENABLED
+
+ifndef LOCAL_JACK_PROGUARD_FLAGS
+    LOCAL_JACK_PROGUARD_FLAGS := $(LOCAL_PROGUARD_FLAGS)
+endif
+LOCAL_JACK_PROGUARD_FLAGS += $(addprefix -include , $(proguard_flag_files))
+ifdef LOCAL_TEST_MODULE_TO_PROGUARD_WITH
+    $(error $(LOCAL_MODULE): Build with jack when LOCAL_TEST_MODULE_TO_PROGUARD_WITH is defined is not yet implemented)
+endif
+
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JACK_PROGUARD_FLAGS := $(common_proguard_flags) $(LOCAL_JACK_PROGUARD_FLAGS)
+else  # LOCAL_PROGUARD_ENABLED not defined
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JACK_PROGUARD_FLAGS :=
+endif # LOCAL_PROGUARD_ENABLED defined
+
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JACK_FLAGS := $(LOCAL_JACK_FLAGS)
+
+jack_all_deps := $(java_sources) $(java_resource_sources) $(full_jack_lib_deps) \
+        $(jar_manifest_file) $(layers_file) $(RenderScript_file_stamp) $(proguard_flag_files) \
+        $(proto_java_sources_file_stamp) $(LOCAL_ADDITIONAL_DEPENDENCIES) $(LOCAL_JARJAR_RULES) \
+        $(LOCAL_MODULE_MAKEFILE) $(JACK_JAR) $(JACK_LAUNCHER_JAR)
+
+ifeq ($(LOCAL_IS_STATIC_JAVA_LIBRARY),true)
+$(full_classes_jack): $(jack_all_deps)
+	@echo Building with Jack: $@
+	$(java-to-jack)
+
+else #LOCAL_IS_STATIC_JAVA_LIBRARY
+$(built_dex_intermediate): PRIVATE_CLASSES_JACK := $(full_classes_jack)
+
+$(built_dex_intermediate): $(jack_all_deps)
+	@echo Building with Jack: $@
+	$(jack-java-to-dex)
+
+# $(full_classes_jack) is just by-product of $(built_dex_intermediate).
+# The dummy command was added because, without it, make misses the fact the $(built_dex) also
+# change $(full_classes_jack).
+$(full_classes_jack): $(built_dex_intermediate)
+	$(hide) touch $@
+
+endif #LOCAL_IS_STATIC_JAVA_LIBRARY
+
+$(noshrob_classes_jack): PRIVATE_JACK_INTERMEDIATES_DIR := $(intermediates.COMMON)/jack-noshrob-rsc
+ifeq ($(LOCAL_JACK_ENABLED),incremental)
+$(noshrob_classes_jack): PRIVATE_JACK_INCREMENTAL_DIR := $(intermediates.COMMON)/jack-noshrob-incremental
+else
+$(noshrob_classes_jack): PRIVATE_JACK_INCREMENTAL_DIR :=
+endif
+$(noshrob_classes_jack): PRIVATE_JACK_PROGUARD_FLAGS :=
+$(noshrob_classes_jack): $(jack_all_deps)
+	@echo Building with Jack: $@
+	$(java-to-jack)
+endif  # full_classes_jar is defined
+endif # LOCAL_JACK_ENABLED
diff --git a/core/java_library.mk b/core/java_library.mk
index b4e3eaa..5a2d19b 100644
--- a/core/java_library.mk
+++ b/core/java_library.mk
@@ -24,10 +24,20 @@
 
 LOCAL_BUILT_MODULE_STEM := javalib.jar
 
+#################################
+include $(BUILD_SYSTEM)/configure_local_jack.mk
+#################################
+
+ifdef LOCAL_JACK_ENABLED
+ifdef LOCAL_IS_STATIC_JAVA_LIBRARY
+LOCAL_BUILT_MODULE_STEM := classes.jack
+endif
+endif
+
 intermediates.COMMON := $(call local-intermediates-dir,COMMON)
 
 # This file will be the one that other modules should depend on.
-common_javalib.jar := $(intermediates.COMMON)/$(LOCAL_BUILT_MODULE_STEM)
+common_javalib.jar := $(intermediates.COMMON)/javalib.jar
 LOCAL_INTERMEDIATE_TARGETS += $(common_javalib.jar)
 
 ifeq ($(LOCAL_PROGUARD_ENABLED),disabled)
@@ -59,7 +69,11 @@
 	@echo "target Static Jar: $(PRIVATE_MODULE) ($@)"
 	$(copy-file-to-target)
 
-$(LOCAL_BUILT_MODULE): $(common_javalib.jar)
+ifdef LOCAL_JACK_ENABLED
+$(LOCAL_BUILT_MODULE) : $(full_classes_jack)
+else
+$(LOCAL_BUILT_MODULE) : $(common_javalib.jar)
+endif
 	$(copy-file-to-target)
 
 else # !LOCAL_IS_STATIC_JAVA_LIBRARY
@@ -69,8 +83,15 @@
 $(common_javalib.jar): PRIVATE_DONT_DELETE_JAR_DIRS := $(LOCAL_DONT_DELETE_JAR_DIRS)
 $(common_javalib.jar) : $(built_dex) $(java_resource_sources)
 	@echo "target Jar: $(PRIVATE_MODULE) ($@)"
+ifdef LOCAL_JACK_ENABLED
+	$(create-empty-package)
+else
 	$(call initialize-package-file,$(PRIVATE_SOURCE_ARCHIVE),$@)
+endif
 	$(add-dex-to-package)
+ifdef LOCAL_JACK_ENABLED
+	$(add-carried-jack-resources)
+endif
 
 ifdef LOCAL_DEX_PREOPT
 ifneq ($(dexpreopt_boot_jar_module),) # boot jar
diff --git a/core/notice_files.mk b/core/notice_files.mk
index e63cd84..43a5435 100644
--- a/core/notice_files.mk
+++ b/core/notice_files.mk
@@ -43,7 +43,7 @@
       # javalib.jar is the default name for the build module (and isn't meaningful)
       # If that's what we have, substitute the module name instead.  These files
       # aren't included on the device, so this name is synthetic anyway.
-      ifeq ($(module_leaf),javalib.jar)
+      ifneq ($(filter javalib.jar classes.jack,$(module_leaf)),)
         module_leaf := $(LOCAL_MODULE).jar
       endif
       module_installed_filename := \
diff --git a/core/package_internal.mk b/core/package_internal.mk
index d52997b..fee484f 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -57,6 +57,10 @@
 endif
 LOCAL_MODULE_CLASS := APPS
 
+#################################
+include $(BUILD_SYSTEM)/configure_local_jack.mk
+#################################
+
 # Package LOCAL_MODULE_TAGS default to optional
 LOCAL_MODULE_TAGS := $(strip $(LOCAL_MODULE_TAGS))
 ifeq ($(LOCAL_MODULE_TAGS),)
@@ -162,6 +166,13 @@
 endif # !custom
 LOCAL_PROGUARD_FLAGS := $(addprefix -include ,$(proguard_options_file)) $(LOCAL_PROGUARD_FLAGS)
 
+ifdef LOCAL_JACK_ENABLED
+ifndef LOCAL_JACK_PROGUARD_FLAGS
+    LOCAL_JACK_PROGUARD_FLAGS := $(LOCAL_PROGUARD_FLAGS)
+endif
+LOCAL_JACK_PROGUARD_FLAGS := $(addprefix -include ,$(proguard_options_file)) $(LOCAL_JACK_PROGUARD_FLAGS)
+endif # LOCAL_JACK_ENABLED
+
 ifeq (true,$(EMMA_INSTRUMENT))
 ifndef LOCAL_EMMA_INSTRUMENT
 # No emma for test apks.
@@ -271,6 +282,18 @@
 # they want to use this module's R.java file.
 $(LOCAL_BUILT_MODULE): $(R_file_stamp)
 
+ifdef LOCAL_JACK_ENABLED
+ifneq ($(built_dex_intermediate),)
+$(built_dex_intermediate): $(R_file_stamp)
+endif
+ifneq ($(noshrob_classes_jack),)
+$(noshrob_classes_jack): $(R_file_stamp)
+endif
+ifneq ($(full_classes_jack),)
+$(full_classes_jack): $(R_file_stamp)
+endif
+endif # LOCAL_JACK_ENABLED
+
 ifneq ($(full_classes_jar),)
 # If full_classes_jar is non-empty, we're building sources.
 # If we're building sources, the initial javac step (which
@@ -388,9 +411,13 @@
 $(LOCAL_BUILT_MODULE): PRIVATE_DONT_DELETE_JAR_DIRS := $(LOCAL_DONT_DELETE_JAR_DIRS)
 $(LOCAL_BUILT_MODULE): $(all_res_assets) $(jni_shared_libraries) $(full_android_manifest)
 	@echo "target Package: $(PRIVATE_MODULE) ($@)"
+ifdef LOCAL_JACK_ENABLED
+	$(create-empty-package)
+else
 	$(if $(PRIVATE_SOURCE_ARCHIVE),\
 	  $(call initialize-package-file,$(PRIVATE_SOURCE_ARCHIVE),$@),\
 	  $(create-empty-package))
+endif
 	$(add-assets-to-package)
 ifneq ($(jni_shared_libraries),)
 	$(add-jni-shared-libs-to-package)
@@ -401,6 +428,9 @@
 else
 	$(add-dex-to-package)
 endif
+ifdef LOCAL_JACK_ENABLED
+	$(add-carried-jack-resources)
+endif
 ifdef LOCAL_DEX_PREOPT
 ifneq (nostripping,$(LOCAL_DEX_PREOPT))
 	$(call dexpreopt-remove-classes.dex,$@)
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index f85b0b8..d367828 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -302,6 +302,14 @@
 $(built_module) : $(common_javalib_jar)
 endif # TARGET JAVA_LIBRARIES
 
+ifeq ($(LOCAL_MODULE_CLASS),JAVA_LIBRARIES)
+$(intermediates.COMMON)/classes.jack : PRIVATE_JILL_FLAGS:=$(LOCAL_JILL_FLAGS)
+$(intermediates.COMMON)/classes.jack : $(my_prebuilt_src_file) $(LOCAL_MODULE_MAKEFILE) \
+        $(LOCAL_ADDITIONAL_DEPENDENCIES) $(JILL_JAR) $(JACK_JAR) $(JACK_LAUNCHER_JAR)
+	$(transform-jar-to-jack)
+
+endif # JAVA_LIBRARIES
+
 $(built_module) : $(LOCAL_MODULE_MAKEFILE) $(LOCAL_ADDITIONAL_DEPENDENCIES)
 
 my_prebuilt_src_file :=
diff --git a/core/static_java_library.mk b/core/static_java_library.mk
index 02078e0..69d6ebf 100644
--- a/core/static_java_library.mk
+++ b/core/static_java_library.mk
@@ -56,8 +56,20 @@
 ifneq ($(LOCAL_PROGUARD_ENABLED),custom)
   proguard_options_file := $(intermediates.COMMON)/proguard_options
 endif
+
 LOCAL_PROGUARD_FLAGS := $(addprefix -include ,$(proguard_options_file)) $(LOCAL_PROGUARD_FLAGS)
 
+#################################
+include $(BUILD_SYSTEM)/configure_local_jack.mk
+#################################
+
+ifdef LOCAL_JACK_ENABLED
+ifndef LOCAL_JACK_PROGUARD_FLAGS
+    LOCAL_JACK_PROGUARD_FLAGS := $(LOCAL_PROGUARD_FLAGS)
+endif
+LOCAL_JACK_PROGUARD_FLAGS := $(addprefix -include ,$(proguard_options_file)) $(LOCAL_JACK_PROGUARD_FLAGS)
+endif # LOCAL_JACK_ENABLED
+
 endif  # LOCAL_RESOURCE_DIR
 
 all_res_assets := $(all_resources)
@@ -114,9 +126,11 @@
 	$(hide) find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) -name R.java | xargs cat > $@
 
 $(LOCAL_BUILT_MODULE): $(R_file_stamp)
-ifneq ($(full_classes_jar),)
+ifdef LOCAL_JACK_ENABLED
+$(noshrob_classes_jack): $(R_file_stamp)
+$(full_classes_jack): $(R_file_stamp)
+endif # LOCAL_JACK_ENABLED
 $(full_classes_compiled_jar): $(R_file_stamp)
-endif
 
 endif  # need_compile_res