Ich verbrachte einige Tage, dieses Problem zu entdecken, und ich würde gerne meinen Fund hier posten.Gradle ANTLR4-Plugin in Android App: Build fehlschlägt
Ich baue eine Android-App mit mehreren Modulen, von denen eines das ANTLR-Plugin verwendet. Während das Modul mit ANTLR OK baut, da es ein Java-Modul ist, schlägt das Android-Modul in transformClassesWithDexForDebug
Aufgabe:
* What went wrong:
Execution failed for task ':Android:transformClassesWithDexForDebug'.
> com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: java.lang.RuntimeException: Translation has been interrupted
Wenn ich versuche, build.gradle zu ermöglichen multiDexEnabled
in ich eine andere Meldung:
* What went wrong:
Execution failed for task ':Android:transformClassesWithJarMergingForDebug'.
> com.android.build.api.transform.TransformException: java.util.zip.ZipException: duplicate entry: org/abego/treelayout/Configuration$AlignmentInLevel.class
Einige Antworten hier schlägt vor, Java-RAM für Dexing zu erhöhen, Abhängigkeiten wie Google-Play-Bibliothek zu reduzieren - das habe ich gemacht, aber keine Freude.
hier gehen build.gradle Proben verwendet:
ANTLR4 Modul:
apply plugin: 'antlr'
apply plugin: 'java'
apply plugin: 'maven'
sourceCompatibility = 1.7
targetCompatibility = 1.7
final GENERATED_MAIN = "src-gen/main/java"
final GENERATED_TEST = "src-gen/test/java"
sourceSets {
main {
java { srcDirs += [GENERATED_MAIN] }
}
main {
java { srcDirs += [GENERATED_TEST] }
}
}
repositories {
mavenCentral()
}
dependencies {
antlr("org.antlr:antlr4:4.5") {
exclude group: 'org.antlr', module:'antlr-runtime'
// exclude group: 'org.antlr', module:'antlr4-runtime'
exclude group: 'org.antlr', module:'ST4'
}
compile ('com.yuvalshavit:antlr-denter:1.0') {
exclude group: 'org.antlr', module:'antlr4-runtime'
}
testCompile group: 'junit', name: 'junit', version:'4.11'
}
generateGrammarSource.doFirst {
outputDirectory = new File(GENERATED_MAIN)
}
generateGrammarSource.doLast {
moveAntlrGeneratedFilesToTheirPackages(source, GENERATED_MAIN)
}
generateTestGrammarSource.doFirst {
outputDirectory = new File(GENERATED_TEST)
}
generateTestGrammarSource.doLast {
moveAntlrGeneratedFilesToTheirPackages(source, GENERATED_TEST)
}
def moveAntlrGeneratedFilesToTheirPackages(FileTree grammarFiles, generatedFolder) {
grammarFiles.each {File file ->
final grammarName = file.name.lastIndexOf('.')>=0 ? file.name[0 .. file.name.lastIndexOf('.')-1] : file.name
final grammarPackage = extractPackageNameFromGrammerFile(file)
copy {
from generatedFolder
include "${grammarName}*.*"
into generatedFolder + "/" + grammarPackage.replaceAll("\\.", "/")
}
}
project.delete fileTree(generatedFolder).include('*.*')
}
def extractPackageNameFromGrammerFile(File grammarFile) {
def grammarPackage = "unknown.package"
def packageRegex = ~/[ ]*package[ ]*([a-zA-Z]+[a-zA-Z0-9.-_]*)[ ]*;/
grammarFile.eachLine { line ->
def matcher = packageRegex.matcher(line)
if (matcher.find()){
grammarPackage = matcher.group(1)
}
}
return grammarPackage
}
android Modul:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "<some package name here>"
minSdkVersion 14
targetSdkVersion 22
// multiDexEnabled true
}
dexOptions {
// javaMaxHeapSize "4g"
preDexLibraries = false
}
lintOptions {
abortOnError false
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['iadl']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
}
}
dependencies {
compile project(':texas-board') // this references the ANTLR module mentioned above
...
}
root build.gradle:
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.2'
}
}
Analyseabhängigkeiten (gradle dependencies
) zeigt, dass das Problem ist, dass antlr gradle Plugin org.abego.treelayout
Klassen sowohl über antlr4
Bibliothek für die Kompilierung verwendet wird, umfasst und antlr4-Laufzeit:
+--- project :texas-board
| \--- project :rules_engine
| +--- org.antlr:antlr4:4.5
| | +--- org.antlr:antlr4-runtime:4.5
| | | \--- org.abego.treelayout:org.abego.treelayout.core:1.0.1
| | \--- org.antlr:antlr-runtime:3.5.2
| \--- com.yuvalshavit:antlr-denter:1.0
wieder einmal - die Sache ist, dass die org.abego.treelayout
Klassen vorhanden sind beide in org.antlr:antlr4:4.5
, org.antlr:antlr4-runtime:4.5
und wahrscheinlich sogar in org.abego.treelayout:org.abego.treelayout.core:1.0.1
. Ich vermute, dass es ein Fehler mit dem AntiLR4-Plugin für Gradle ist - sie haben diese Klassen fälschlicherweise im Hauptpaket hinzugefügt, während sie nur in Abhängigkeiten stehen sollten. Wahrscheinlich sollte ich einen Bug an den Plugin-Tracker senden.
Darüber hinaus fügt Antlr4-Plugin sogar Antlr3-Laufzeitabhängigkeit, die org.abego.treelayout
Klassen ebenfalls neu definieren (so dass ich auch ausgeschlossen).
Während Java-Anwendungen zusätzliche Kopien von Java-Klassen akzeptieren (sie nehmen die erste von Classpath glaube ich), Android-Plugin scheitert in Dex-Stufe Bericht Fehler oben erwähnt.