我编写了一小部分供我内部使用的小型库。这是使用 Maven 构建的。这些库针对“常规”Java、GWT 和 Android。其中一些是用 Java 8 编写的,因为我无意在 GWT 或 Android 上运行它们,因此其他库是用旧的 Java 6 编写的以支持这两个。我有一个将我的库完全迁移到 Java 8(就语言特性而言)的计划,并且我成功地在尚未发布的 GWT 2.8.0 上运行了 Java 8 重写的库。但是,我不能让 Java 8 重写的库为 Android 应用程序编译。问题是 Retrolambda(retrolambda-maven-plugin
插件)似乎只能处理当前的 Maven 模块类,并完全忽略依赖类。因此,android-maven-plugin
目标应用程序构建的中断:
[INFO] UNEXPECTED TOP-LEVEL EXCEPTION:
[INFO] com.android.dx.cf.iface.ParseException: bad class file magic (cafebabe) or version (0034.0000)
[INFO] at com.android.dx.cf.direct.DirectClassFile.parse0(DirectClassFile.java:472)
[INFO] at com.android.dx.cf.direct.DirectClassFile.parse(DirectClassFile.java:406)
[INFO] at com.android.dx.cf.direct.DirectClassFile.parseToInterfacesIfNecessary(DirectClassFile.java:388)
[INFO] at com.android.dx.cf.direct.DirectClassFile.getMagic(DirectClassFile.java:251)
[INFO] at com.android.dx.command.dexer.Main.processClass(Main.java:665)
[INFO] at com.android.dx.command.dexer.Main.processFileBytes(Main.java:634)
[INFO] at com.android.dx.command.dexer.Main.access$600(Main.java:78)
[INFO] at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:572)
[INFO] at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:284)
[INFO] at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:166)
[INFO] at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144)
[INFO] at com.android.dx.command.dexer.Main.processOne(Main.java:596)
[INFO] at com.android.dx.command.dexer.Main.processAllFiles(Main.java:498)
[INFO] at com.android.dx.command.dexer.Main.runMonoDex(Main.java:264)
[INFO] at com.android.dx.command.dexer.Main.run(Main.java:230)
[INFO] at com.android.dx.command.dexer.Main.main(Main.java:199)
[INFO] at com.android.dx.command.Main.main(Main.java:103)
[INFO] ...while parsing foo/bar/FooBar.class
配置retrolambda-maven-plugin
如下:
<plugin>
<groupId>net.orfjackal.retrolambda</groupId>
<artifactId>retrolambda-maven-plugin</artifactId>
<version>2.0.2</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>process-main</goal>
<goal>process-test</goal>
</goals>
</execution>
</executions>
<configuration>
<target>1.6</target>
<defaultMethods>true</defaultMethods>
</configuration>
</plugin>
是否可以配置 Retrolambda 插件来处理库类以及所有依赖项?或者也许我可以使用另一个字节码处理工具?
更新#1
我认为我对 Retrolambda 失败的看法是错误的。再深入研究一下,我发现这android-maven-plugin
可能是罪魁祸首,因为它直接从 Maven 存储库中选择未检测的 JAR 文件,而不是从target
目录中。启用详细日志记录发现了由以下命令调用的伪代码命令android-maven-plugin
:
$JAVA_HOME/jre/bin/java
-Xmx1024M
-jar "$ANDROID_HOME/sdk/build-tools/android-4.4/lib/dx.jar"
--dex
--output=$BUILD_DIRECTORY/classes.dex
$BUILD_DIRECTORY/classes
$M2_REPO/foo1/bar1/0.1-SNAPSHOT/bar1-0.1-SNAPSHOT.jar
$M2_REPO/foo2/bar2/0.1-SNAPSHOT/bar2-0.1-SNAPSHOT.jar
$M2_REPO/foo3/bar3/0.1-JAVA-8-SNAPSHOT/bar3-0.1-JAVA-8-SNAPSHOT.jar
我的想法是执行maven-dependency-plugin
插件以将这三个工件获取到$BUILD_DIRECTORY/classes
目录中,以使retrolambda-maven-plugin
仪器具有依赖关系。比方说:
步骤 1:将依赖项复制到目标目录
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeScope>runtime</includeScope>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
第 2 步:使用 Retrolambda 检测复制的依赖项
调用retrolambda-maven-plugin
第 3 步:编译 DEX 文件
调用android-maven-plugin
排除复制到目标目录的依赖项,因为它们都应该位于目标目录中
但这也失败了,因为我找不到一种方法来排除工件与android-maven-plugin
.
如何禁止从以非检测状态存储它们的存储库中获取工件?
我的插件配置:
- org.apache.maven.plugins:maven-dependency-plugin:2.10
- net.orfjackal.retrolambda:retrolambda-maven-plugin:2.0.2
- com.jayway.maven.plugins.android.generation2:android-maven-plugin:3.9.0-rc.3
更新#2
Simpligility 团队发布了 Android Maven 插件 4.4.1,具有以下描述的场景。在插件更改日志中查看更多信息。
<plugin>
<groupId>com.simpligility.maven.plugins</groupId>
<artifactId>android-maven-plugin</artifactId>
<version>4.4.1</version>
</plugin>
示例场景可以在http://simpligility.github.io/android-maven-plugin/instrumentation.html找到