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 = ложь