Jak rozwiązać problem „Zduplikowane pliki skopiowane w pliku APK META-INF / *”

91

Pracuję nad komercyjną aplikacją na Androida. Korzystam również z niektórych bibliotek licencjonowanych na podstawie różnych typów licencji, z których niektóre zawierają następujące informacje:

Jeśli w bibliotece znajduje się plik „UWAGI” z uwagami dotyczącymi źródła, należy dołączyć to UWAGĘ podczas dystrybucji

(Na przykład jeden z nich jest objęty licencją Apache License 2.0 ).

Istnieje więcej niż jedna biblioteka. Kiedy wykonuję kompilację za pomocą gradle lub Android Studio , otrzymuję następujący błąd kompilacji:

* What went wrong:
Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'.
> com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK META-INF/license.txt

Odpowiedzi, które znalazłem do tej pory w Internecie i stackoverflow, sugerują usunięcie pliku license.txt (notice.txt lub innych plików, które mogą w ten sposób przeszkadzać) z opakowania, dodając do build.gradlepliku:

packagingOptions {
    exclude 'META-INF/DEPENDENCIES.txt'
    exclude 'META-INF/LICENSE.txt'
    exclude 'META-INF/NOTICE.txt'
    exclude 'META-INF/NOTICE'
    exclude 'META-INF/LICENSE'
    exclude 'META-INF/DEPENDENCIES'
    exclude 'META-INF/notice.txt'
    exclude 'META-INF/license.txt'
    exclude 'META-INF/dependencies.txt'
    exclude 'META-INF/LGPL2.1'
}

Zobacz na przykład: Android Studio 0.4 Duplikaty plików skopiowane w APK META-INF / LICENSE.txt

Zgodnie z licencją tych bibliotek ( Apache License 2.0 na przykład), pliki licencji i zawiadomienie powinno być włączone .

Moje pytanie: Jak mogę dodać wiele plików związanych z licencją (takich jak license.txt , notice.txt itp.) Z gradle do mojego projektu, aby zachować zgodność z licencjami ( szczegóły techniczne: teksty licencji będą łączone)?

Flowryn
źródło
2
Czy z technicznego punktu widzenia nie możesz spakować rzeczy tak, aby wszystkie pliki „must include” każdej biblioteki znajdowały się w ich własnym katalogu? Alternatywą, którą widziałem w przypadku niektórych aplikacji, jest to, że możesz (ręcznie) połączyć wszystkie odpowiednie pliki licencji / powiadomień w jeden zasób i dołączyć / wyświetlić to (gdy dwie lub więcej bibliotek ma tę samą wersję licencji, powinieneś być w stanie je zgrupować , „Biblioteka A i Biblioteka B są objęte następującą licencją:…”).
TripeHound
@TripeHound to jest to, co obecnie robię jako obejście, podczas gdy w procesie tworzenia wykluczam je, a jeśli chodzi o wydanie: komentuj wszystkie „wykluczenia” i rozwiązuj licencje ręcznie.
Flowryn,
1
szukanie odpowiedzi „opakowanieOpcje - wykluczenie” zasługuje na pochwałę
Ahmed Adel Ismail

Odpowiedzi:

47

Jest rozwiązanie, jeśli masz tylko jedną licencję używającą nazwy license.txt(czytaj: wszystkie license.txtkopie są identyczne):

packagingOptions {
   pickFirst  'META-INF/license.txt'
}

W przeciwnym razie firma Google wydała również wtyczkę Gradle do zarządzania licencjami na zależności. Zobacz tutaj . Nie próbowałem tego, ale wygląda na to, że jest w stanie agregować każdą zależność, a nawet generować aktywność wyświetlającą wszystkie te licencje.

Marc Plano-Lesay
źródło
1
W tej chwili mam 2 licencje, jedna pochodzi z Apache 2.0, druga z GPL 3.0. Moje obecne obejście polega na wykluczeniu ich w fazie opracowywania i ręcznym dołączeniu ich po wydaniu. Cały plik license.txt zostanie połączony. To samo dotyczy notice.txt W każdym razie podoba mi się twoje podejście do pickFirst na wypadek, gdyby licencja była identyczna!
Flowryn
3
Jeśli kiedykolwiek znajdziesz sposób na automatyczne łączenie licencji, mam uszy!
Marc Plano-Lesay
To jest to, co teraz badam. Najpierw muszę dowiedzieć się, co (i jak) wykonuje zadanie gradle, które wygenerowało konflikt (w tym celu zadałem to pytanie: stackoverflow.com/questions/34287701/ ... ) A potem je wymienić
Flowryn
@Flowryn, jak ręcznie dołączyć wszystkie notice.txt, po prostu skopiuj je w jednym notice.txt? nie mogę zmodyfikować tego, który w jarpliku
chinaanihchen
wspomniałeś, że problem tkwi w używanych bibliotekach… w moim przypadku jestem odpowiedzialny za tworzenie bibliotek, których używam… co mogę zrobić źle, kiedy je tworzę? Dzięki
Eric
32

Dodaj następujące elementy do odpowiedniego pliku build.gradle

packagingOptions {
        exclude 'META-INF/ASL2.0'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/MANIFEST.MF'
    }
Max Droid
źródło
1
Wyklucza to licencje, które w przypadku większości z nich są wyraźnie sprzeczne z ich warunkami.
Marc Plano-Lesay
1
Powinno to znajdować się w zamknięciu Androida {} dla bieżących (2. *) wersji Gradle
mijiturka
4

W przypadku mojej aplikacji napotkałem ten sam problem. Musisz się upewnić, że nie dodałeś dwukrotnie żadnych bibliotek. Jeśli postępowałeś zgodnie z dokumentacją Firebase https://firebase.google.com/docs/android/setup

W takim przypadku nie należy dodawać biblioteki Firebase w Android Studio, tj. Plik-> struktura projektu-> chmura-> firebase

Musisz zrobić tylko jedno z obu, aby używać Firebase w swojej aplikacji na Androida.

Na koniec wyczyść i uruchom ponownie aplikację.

potężny
źródło
2
Jeśli używasz jackson-databind, problem pojawia się, gdy dodasz go raz.
Niesamowity
0

Możesz dodać wiele licencji w gradle, zobacz to

Akhil Jayakumar
źródło
0

Myślę, że musisz uwzględnić tylko te opcje w pliku build.gradle:

android {
    packagingOptions {
        exclude 'META-INF/DEPENDENCIES.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
    }
}
S.sadham hussain
źródło
-2

Na pewno zadziała

packagingOptions {
 exclude 'META-INF/LICENSE.txt'
 exclude 'META-INF/NOTICE.txt'   }
Mahendran Candy
źródło
1
Nie, nie będzie: to wyklucza licencje. Zgodnie z warunkami licencji jest to nielegalne.
Marc Plano-Lesay,
Nie, to rozwiązanie tmp do natychmiastowej kompilacji projektu
Mahendran Candy,
1
Niezależnie od zastosowania, przeczytaj licencje: w większości z nich to, co osiągasz dzięki zasadzie wykluczenia, jest nielegalne.
Marc Plano-Lesay