我寫了一小部分小型庫供我內部使用。這是使用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
打破了目標應用程序構建具有:Maven:在裝有retrolambda-maven-plugin和DEX-ed的應用程序中使用Java 8庫與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
儀器的依賴關係。比方說:
STEP 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>
STEP 2:儀器使用Retrolambda
調用retrolambda-maven-plugin
STEP 3:編譯DEX文件
調用android-maven-plugin
排除被複制到目標目錄的依賴,因爲他們都應該被定位在目標目錄
但這也失敗,因爲我無法找到一種方法來排除工件因android-maven-plugin
而遭到DEX處理。
我該如何抑制工件從存儲在非工具狀態的存儲庫中獲取?
我的插件配置:
- org.apache.maven.plugins:Maven的依賴關係的插件:2.10
- net.orfjackal.retrolambda:retrolambda - Maven的插件:2.0.2
- com.jayway.maven.plugins.android.generation2:Android的Maven的插件:3.9.0-rc.3
更新#2
Simpligility團隊發佈了Android Maven Plugin 4.4.1,其特點如下所述。請參閱插件changelog。
<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
偉大的問題和解決方案!拯救了我的一天... – MWiesner