Gradle создать пустой объект консоли

Я пытаюсь получить мои сборки gradle для запроса на консоль для пароля с использованием примеров из

Когда у меня есть статут, например:

def password = System.console().readLine("Enter keystore password ")

Когда я запускаю, я получаю сообщение об ошибке

Cannot invoke method readLine() on null object

Кажется, консоль выходит как null. То, что я прочитал, требует java 6, который, если я перейду в командную строку и введите java -version, я запускаю среду выполнения Java (TM) SE (сборка 1.6.0_27-b07).

Эта проблема отслеживается в gradle Github repo: Невозможно использовать System.console() с помощью gradle Daemon.

Ответ 1

Хорошо, причина в том, что это не сработало, было глупо, но на всякий случай кто-то сталкивался с этим, я думал, что отправлю.

Я запускал задачу через студию Android и не понимал, что объект консоли всегда будет нулевым. При запуске из командной строки объект "command" не равен null, и он работает нормально.

Ответ 2

По какой-то причине запуск gradle в режиме демона вызывает нулевой объект консоли. Если вы укажете соответствующий флаг командной строки,

./gradlew assembleRelease --no-daemon

он будет работать.

Ответ 3

Я нашел решение здесь в https://www.timroes.de/2014/01/19/using-password-prompts-with-gradle-build-files и немного изменил его. Тем не менее, все кредиты идут к Тиму Роусу!

gradle.taskGraph.whenReady { taskGraph ->
if(taskGraph.hasTask(':app:assembleRelease')) {
    def storePass = ''
    def keyPass = ''
    if(System.console() == null) {
        new SwingBuilder().edt {
            dialog(modal: true, title: 'Enter password', alwaysOnTop: true, resizable: false, locationRelativeTo: null, pack: true, show: true) {
                vbox { // Put everything below each other
                    label(text: "Please enter store passphrase:")
                    def input1 = passwordField()
                    label(text: "Please enter key passphrase:")
                    def input2 = passwordField()
                    button(defaultButton: true, text: 'OK', actionPerformed: {
                        storePass = input1.password;
                        keyPass = input2.password;
                        dispose();
                    })
                }
            }
        }
    } else {
        storePass = System.console().readPassword("\nPlease enter store passphrase: ")
        keyPass = System.console().readPassword("\nPlease enter key passphrase: ")
    }

    if(storePass.size() <= 0 || keyPass.size() <= 0) {
        throw new InvalidUserDataException("You must enter the passwords to proceed.")
    }

    storePass = new String(storePass)
    keyPass = new String(keyPass)

    android.signingConfigs.release.storePassword = storePass
    android.signingConfigs.release.keyPassword = keyPass
    }
}

Где-то в некотором gradle файле, у вас есть конфигурация для определения подписания релиза.

android {
...
signingConfigs {
    ...
    release {
        storeFile file(System.getProperty("user.home")+"\\android-key")
        storePassword ''
        keyAlias "standard"
        keyPassword ''
    }
}

...
}

(Не забудьте import groovy.swing.SwingBuilder.)

Что касается второй части, вы можете также взглянуть на Как создать файл apk с подписанным выпуском с помощью Gradle?

Ответ 4

Взгляните на это сообщение в блоге (https://www.timroes.de/2013/09/22/handling-signing-configs-with-gradle/).

В нем описывается несколько способов обработки подписанных конфигураций, и один из них - именно ваш вопрос относительно ввода консоли для пароля.

Ответ 5

Выполнение System.getConsole() из Gradle, когда свойство org.gradle.daemon равно true, или когда оно выполняется из среды IDE, такой как IntelliJ или Android Studio, возвращает null. Так, например, сделать System.console().readLine() становится невозможным.

Кроме того, начиная с Gradle 3.0 gradle.daemon включен по умолчанию.

Тогда вместо обходного пути для использования System.getConsole() я хочу использовать альтернативу, используйте ant.input так:

task avoidNullOnConsole << {
    ant.input(message: 'Enter keystore password:', addproperty: 'userInputPassword', defaultValue : '1234')
    def password = ant.properties.userInputPassword
}

В этом случае ant.input показывает message и добавляет пользовательский ввод в ant.properties, используя в качестве имени свойства значение, определенное в addProperty. Если пользовательский ввод отсутствует, используется значение, определенное в атрибуте default.

После выполнения вы можете получить ввод пользователя с помощью ant.properties.yourProperty или ant.properties['yourProperty'].

Здесь вы можете проверить остальные атрибуты ant.input.

Примечание.. Если вы хотите использовать ant.input несколько раз, считайте, что вы не можете переопределить и существующее свойство, поэтому атрибут addProperty должен быть различным для каждого из них.

Ответ 6

Простым решением этого является проверка объекта консоли на null:

def password = null
def console = System.console()
if (console != null) {
    password = console.readLine("Enter keystore password: ")
}

Android Studio больше не жалуется на null object.

Чтобы скрыть типизированные символы, используйте readPassword() вместо readLine():

password = new String(console.readPassword("\nEnter key password: "))

Ответ 7

Вы можете выполнить свой script также с помощью

-Dorg.gradle.daemon = ложь