Использование Proguard в Gradle - не удается найти ссылочный класс java.lang.String

Я пытаюсь настроить ProGuard как часть моих сценариев сборки Gradle для java-приложения в Ubuntu, доступ к которому осуществляется через bash, но я не могу понять это правильно. Я никогда раньше не использовал ни одну из этих технологий. Используя Руководство по ProGuard, я написал следующую задачу, которую сейчас вызываю уже существующий файл jar, пока я пытаюсь что-то сделать.

task obfuscate(type: proguard.gradle.ProGuardTask) {
  injars         'build/libs/myapplication.jar'
  outjars        'build/libs/myapplication_out.jar'
  libraryjars    '<java.home>/lib/rt.jar'
  printmapping   'myapplication.map'

  keep 'public class mypackage.MyMainClass {  \
    public static void main(java.lang.String[]);  \
  }'
}

Я получаю много строк с указанием отсутствующих встроенных файлов библиотеки Java, таких как:

Warning: myclasses: can't find referenced class java.lang.String

Внизу списка я также вижу:

Could not call ProGuardTask.proguard()

Если я проверю свой выходной каталог, я увижу, что он создал структуру каталогов, но не файл jar, и это то, что я вижу, если я запускаю свою задачу gradle с трассировкой стека:

Caused by: org.gradle.api.GradleException: Could not call ProGuardTask.proguard() on task

Я просмотрел страницу устранения неполадок proguard, и там было сказано, что я должен убедиться, что я указываю библиотеку времени выполнения моей платформы, а для JSE это lib/rt.jar. Вы можете увидеть это в аргументе библиотечных банок. Что я неправильно понял?


person Nickel    schedule 02.04.2014    source источник
comment
Первое, что нужно выяснить, это исходит ли Could not call ProGuardTask.proguard() от Gradle или ProGuard. Возможно, покажите полную трассировку стека. can't find referenced class java.lang.String похоже, что ProGuard настроен неправильно.   -  person Peter Niederwieser    schedule 02.04.2014


Ответы (2)


ProGuard не читает jar среды выполнения, потому что его имя должно быть указано по-другому.

В конфигурационных файлах ProGuard вы можете написать:

-libraryjars <java.home>/lib/rt.jar

В файлах сборки Gradle вы должны использовать стиль Gradle:

libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
person Eric Lafortune    schedule 30.04.2014
comment
Вы знаете, где найти rt.jar или аналог с JDK 10? Кажется, он больше не поставляется с JDK - person MariusVolkhart; 14.05.2018
comment
@MariusVolkhart rt.jar был удален с jdk 9 - person G. Ciardini; 21.05.2021

Вот что я сделал, чтобы настроить свой путь к классам для моей задачи gradle proguard. Использовал задачу копирования, чтобы собрать все файлы jar в игре, а затем сослался на них в задаче proguard.

task prepare(type: Copy) {

    dependsOn 'jar'

    destinationDir = file("$buildDir/assemble/izpack")
    includeEmptyDirs = true

    into('lib') {
        from configurations.compile
    }
    into('proguard') {
        from configurations.runtime {  include '*truelicense*.jar' }
    }
}


task proguard (type: proguard.gradle.ProGuardTask) {

    dependsOn 'prepare'

    configuration "proguard.conf"

    injars jar.archivePath
    fileTree("$buildDir/assemble/izpack/proguard").include("*.jar").each { f ->
        injars f.path, filter: '!META-INF/MANIFEST.MF'
    }

    outjars "$buildDir/assemble/izpack/web/WEB-INF/lib/${jar.baseName}-${jar.version}.${jar.extension}"

    libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
    libraryjars "${System.getProperty('java.home')}/lib/jce.jar"
    fileTree("$buildDir/assemble/izpack/lib").include("**/*.jar").collect { f -> libraryjars f.path }
    fileTree("$buildDir/assemble/izpack/web").include("**/*.jar").collect { f -> libraryjars f.path }
}
person chenson42    schedule 05.12.2014