Napisałem mały zestaw minilibli na mój wewnętrzny użytek. Ten zestaw jest zbudowany przy użyciu Maven. Biblioteki są adresowane do "zwykłej" Javy, GWT i Androida. Niektóre z nich są napisane w języku Java 8, ponieważ nie miałem zamiaru uruchamiać ich na GWT lub Androidzie, dlatego inne biblioteki są napisane w starej wersji 6, aby obsługiwać te dwa. Mam plan pełnej migracji moich bibliotek do Java 8 (pod względem funkcji językowych) i udało mi się uruchomić biblioteki przepisane w języku Java 8 na jeszcze nie wydanym GWT 2.8.0. Nie mogę jednak przepisać bibliotek Java 8 do kompilacji dla aplikacji na Androida. Problem polega na tym, że Retrolambda (wtyczka retrolambda-maven-plugin
) wydaje się być w stanie przetworzyć tylko obecne klasy modułów Maven i całkowicie ignoruje klasy zależności. Zatem android-maven-plugin
łamie aplikacja docelowa budować z:Maven: Używanie bibliotek Java 8 w aplikacjach wyposażonych w retrofambdę-maven-plugin i DEX-ed z androidem-maven-pluginem
[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
jest skonfigurowany w następujący sposób:
<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>
to możliwe, aby skonfigurować wtyczkę Retrolambda na przetwarzanie klas bibliotecznych jak dobrze więc wszystkie zależności ? A może po prostu mógłbym użyć innego narzędzia do przetwarzania kodu bajtowego?
Aktualizacja # 1
Chyba, że się mylę o Retrolambda niepowodzeniem. Zagłębiając się w to jeszcze trochę, doszedłem do wniosku, że za to można winić android-maven-plugin
, ponieważ wybiera bezpośrednio niesystemowe pliki JAR z repozytorium Maven, a nie z katalogu target
. Umożliwiając pełne rejestrowanie odkryliśmy to polecenie pseudo-kod wywoływany przez 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
Mój pomysł jest wykonywany wtyczki maven-dependency-plugin
aby uzyskać te trzy artefakty do katalogu $BUILD_DIRECTORY/classes
pozwolić instrumentu retrolambda-maven-plugin
zależności. Powiedzmy:
KROK 1: Skopiuj zależności do katalogu docelowego
<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>
Krok 2: Instrument skopiowane zależności wykorzystujące Retrolambda
Invoke retrolambda-maven-plugin
KROK 3: Kompilacja pliku DEX
Invoke android-maven-plugin
wyłączeniem zależności, które zostały skopiowane do katalogu docelowego, ponieważ wszystkie one są podobno znajdować się w katalogu docelowym
Ale to nie zbyt , ponieważ nie mogę znaleźć sposobu na wykluczenie artefaktów z DEXed z android-maven-plugin
.
W jaki sposób mogę zablokować pobieranie artefaktów z repozytorium, w którym są przechowywane w stanie nieprzygotowanym?konfiguracja
Moi wtyczek:
- org.apache.maven.plugins: Maven zależność-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
UPDATE # 2
Zespół Simpligility wydał plugin Android Maven 4.4.1 ze scenariuszem opisanym poniżej. Zobacz więcej na wtyczce changelog.
<plugin>
<groupId>com.simpligility.maven.plugins</groupId>
<artifactId>android-maven-plugin</artifactId>
<version>4.4.1</version>
</plugin>
Przykładowy scenariusz można znaleźć na http://simpligility.github.io/android-maven-plugin/instrumentation.html
świetne pytanie i rozwiązanie! uratowałeś mój dzień ... – MWiesner