2016-03-07 16 views
5

Mam projekt biblioteki Android, który zależy od innych projektów biblioteki Android. Potrzebuję wygenerować javadoc dla biblioteki, ale nie powiedzie się, ponieważ gradle umieszcza ścieżkę classpath javadoc w lokalizacjach .aar, ale javadoc oczekuje plików .jar.Jak wygenerować javadoc dla biblioteki Android, gdy ma zależności, które są również bibliotekami aar?

uproszczony plik Gradle:

android { 
    compileSdkVersion 23 
    buildToolsVersion "23.0.2" 

    configurations { 
     javadocDeps 
    } 

    defaultConfig { 
     minSdkVersion 7 
     targetSdkVersion 23 
     versionCode 1 
     versionName "0.1.0" 
    } 
} 

dependencies { 
    compile 'com.android.support:support-v4:23.2.0' 
    compile 'com.android.support:appcompat-v7:23.2.0' 
    compile 'com.nineoldandroids:library:2.4.0' 
    compile 'com.annimon:stream:1.0.7' 
    javadocDeps 'com.android.support:support-annotations:23.2.0' 
    javadocDeps 'com.nineoldandroids:library:2.4.0' 
    javadocDeps 'com.android.support:support-v4:23.2.0' 
} 

task sourcesJar(type: Jar) { 
    from android.sourceSets.main.java.srcDirs 
    classifier = 'sources' 
}  

task javadoc(type: Javadoc, dependsOn: explodeAars) { 
    source = android.sourceSets.main.java.srcDirs 
    classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 
    classpath += configurations.javadocDeps 
} 

task javadocJar(type: Jar, dependsOn: javadoc) { 
    classifier = 'javadoc' 
    from javadoc.destinationDir 
} 

artifacts { 
    archives javadocJar 
    archives sourcesJar 
} 

3 rozwiązania możliwe:

1) jakoś dodać do classes.jar ścieżka ścieżka klasy z każdego aar biblioteki to zależy Build/intermidiates/eksplodowała-AAR/biblioteka /version/jars/classes.jar Nie wiem, jak uwzględnić te ścieżki w zadaniu javadoc.

2) ręcznie rozpakować classes.jar z pliku aar i dodać je do ścieżki klasy zadania javadoc

3) bardzo brudne hakerskich - sztywno ścieżki do biblioteki - ale myślę, że jest tak źle.

Jak uzyskać 1 lub 2 z gradle dsl?

+0

Czy używasz Android Studio? Znajduje się w menu Narzędzia> Generuj JavaDoc wygodnym narzędziem do wybrania tego, co musi wykonać javadoc. – xiaomi

+0

Używam Android Studio, ale to zadanie musi zostać wykonane automatycznie na zdalnej instancji Jennkins. To zadanie służy do przesyłania biblioteki do jcenter/mavenCentral – curioushikhov

Odpowiedz

4

Rozwiązanie z @rve jest teraz uszkodzone w Androidzie Studio 2.3/Gradle 3.3, ponieważ exploded-aar już nie istnieje (bez alternatywy wewnątrz katalogu budowania).

Jeśli obiekt, na którym polegasz, nie jest modułem w twoim projekcie, będziesz potrzebował najpierw wyodrębnić plik classes.jar przed odniesieniem go do ścieżki klasy (w zasadzie ponownie ręcznie utworzyć intermediates/exploded-aar).

Jeśli zależność, której możesz polegać, jest kolejnym modułem w twoim projekcie, możesz również ustawić zadanie javadoc na podstawie zadania kompilacji tego modułu i odwołać się do intermediates/classes/release tego modułu (jeśli zrobisz javadoc na przykład na assembleRelease) . Przykład tego obejścia: https://github.com/Microsoft/mobile-center-sdk-android/pull/345/files

Naprawdę chciałbym, żeby ktoś wymyślił lepsze rozwiązanie.

5

Zadziała tylko dla Androida Studio starsze niż 2.3 i/lub Gradle starsze niż 3.3

Aby dodać słoiki z USR można dodać następujący doFirst do zadania javadoc:

task javadoc(type: Javadoc) { 
    source = android.sourceSets.main.java.srcDirs 
} 
.doFirst { 
    classpath += fileTree(dir: "$buildDir/intermediates/exploded-aar/", include:"**/classes.jar") 
} 

Dodaje wszystkie pliki .jar ze wszystkich plików AAR do ścieżki klas javadoc. (opcja 1 z proponowanych rozwiązań)

+4

To jest teraz zepsute w Androidzie 2.3/Gradle 3.3. Katalog eksplodowanych-aar już nie istnieje. –

+0

Uwaga: to nie działa dla projektów bibliotecznych przy użyciu wtyczki gradle Android 2.3.3 – NemoOudeis

6

udało się zautomatyzować rozwiązanie Guillaume Perrot przez ekstrakcję classes.jar zawarty w każdym pliku AAR i dodanie go do ścieżki klasy zadania javadoc.

wydaje się działać na zależnościach AAR i modułów AAR na Androida Studio 2.3 i Gradle 3,3

import java.nio.file.Files 
import java.nio.file.Paths 
import java.io.FileOutputStream 
import java.util.zip.ZipFile 

task javadoc(type: Javadoc) { 
    source = android.sourceSets.main.java.srcDirs 
    classpath += configurations.compile 
    classpath += configurations.provided 

    afterEvaluate { 
     // Wait after evaluation to add the android classpath 
     // to avoid "buildToolsVersion is not specified" error 
     classpath += files(android.getBootClasspath()) 

     // Process AAR dependencies 
     def aarDependencies = classpath.filter { it.name.endsWith('.aar') } 
     classpath -= aarDependencies 
     aarDependencies.each { aar -> 
      // Extract classes.jar from the AAR dependency, and add it to the javadoc classpath 
      def outputPath = "$buildDir/tmp/aarJar/${aar.name.replace('.aar', '.jar')}" 
      classpath += files(outputPath) 

      // Use a task so the actual extraction only happens before the javadoc task is run 
      dependsOn task(name: "extract ${aar.name}").doLast { 
       extractEntry(aar, 'classes.jar', outputPath) 
      } 
     } 
    } 
} 

// Utility method to extract only one entry in a zip file 
private def extractEntry(archive, entryPath, outputPath) { 
    if (!archive.exists()) { 
     throw new GradleException("archive $archive not found") 
    } 

    def zip = new ZipFile(archive) 
    zip.entries().each { 
     if (it.name == entryPath) { 
      def path = Paths.get(outputPath) 
      if (!Files.exists(path)) { 
       Files.createDirectories(path.getParent()) 
       Files.copy(zip.getInputStream(it), path) 
      } 
     } 
    } 
    zip.close() 
} 
+0

Świetna robota! Wydaje się to dobrze dla mnie! Korzystanie z gradle 3.3. –

+0

Nie działa to dla mnie, ale używam wtyczki gradle 3.0 na kanale kanarkowym (Android Studio 3.0-beta 7). Musiałem usunąć "dostarczoną" konfigurację, aby ją skompilować, ale wynik jest taki jak poprzednio - generowanie javadoc nie działa, ponieważ zewnętrzne zależności nie zostały rozwiązane. – JHH

+0

Z com.android.tools.build:gradle:3.0.0-beta7, a więc gradle-4.1, dostaję kilka różnych problemów. Przede wszystkim niektóre klasy java.nio nie są dostępne, więc przepisałem twój kod bez 'Paths' i' Files'. Kolejnym problemem było to, że nowe konfiguracje 'api' i' implementation' nie są możliwe do rozwiązania, więc musiałem uciekać się do używania zależności 'compile'. Po wykonaniu tej czynności nadal się nie powiedzie, ponieważ nie może znaleźć własnej klasy R. Po ręcznym dodaniu/kompilacji/wygenerowaniu/źródle/r/debugu otrzymałem działający javadoc. Ale naprawdę potrzebuję nowych dyrektyw do pracy. – JHH

1

Używam nowy Android Studio 3.0-p7 i próbował użyć @ odpowiedź nicopico, ale nie udało się z wieloma różnymi błędami, więc jest to jego adaptacja, która nie polega na nieistniejących programach.

task javadoc(type: Javadoc) { 
    failOnError false 
    source = android.sourceSets.main.java.srcDirs 
    // Also add the generated R class to avoid errors... 
    // TODO: debug is hard-coded 
    source += "$buildDir/generated/source/r/debug/" 
    // ... but exclude the R classes from the docs 
    excludes += "**/R.java" 

    // TODO: "compile" is deprecated in Gradle 4.1, 
    // but "implementation" and "api" are not resolvable :(
    classpath += configurations.compile 

    afterEvaluate { 
     // Wait after evaluation to add the android classpath 
     // to avoid "buildToolsVersion is not specified" error 
     classpath += files(android.getBootClasspath()) 

     // Process AAR dependencies 
     def aarDependencies = classpath.filter { it.name.endsWith('.aar') } 
     classpath -= aarDependencies 
     aarDependencies.each { aar -> 
      System.out.println("Adding classpath for aar: " + aar.name) 
      // Extract classes.jar from the AAR dependency, and add it to the javadoc classpath 
      def outputPath = "$buildDir/tmp/exploded-aar/${aar.name.replace('.aar', '.jar')}" 
      classpath += files(outputPath) 

      // Use a task so the actual extraction only happens before the javadoc task is run 
      dependsOn task(name: "extract ${aar.name}").doLast { 
       extractEntry(aar, 'classes.jar', outputPath) 
      } 
     } 
    } 
} 

// Utility method to extract only one entry in a zip file 
private def extractEntry(archive, entryPath, outputPath) { 
    if (!archive.exists()) { 
     throw new GradleException("archive $archive not found") 
    } 

    def zip = new java.util.zip.ZipFile(archive) 

    zip.entries().each { 
     if (it.name == entryPath) { 
      def path = new File(outputPath) 

      if (!path.exists()) { 
       path.getParentFile().mkdirs() 

       // Surely there's a simpler is->os utility except 
       // the one in java.nio.Files? Ah well... 
       def buf = new byte[1024] 
       def is = zip.getInputStream(it) 
       def os = new FileOutputStream(path) 
       def len 

       while ((len = is.read(buf)) != -1) { 
        os.write(buf, 0, len) 
       } 
       os.close() 
      } 
     } 
    } 
    zip.close() 
} 

Martwi mnie, że musimy cały ten kod do wytworzenia niecodzienna javadoc dla biblioteki, ale przynajmniej mam tej pracy. Jednak muszę znaleźć obejście problemu, ponieważ konfiguracja.api i konfiguracja.implementacja nie mogą być rozwiązywane.

+0

Oddzielne pytanie również: https://stackoverflow.com/questions/46810769/how-to-get-dependencies- from-a-gradle-plugin-using-api-or-implementation-dir – JHH

Powiązane problemy