Gradle构buildnull控制台对象

我试图让我的gradle构build提示在控制台input密码使用堆栈溢出的例子

当我有一个表述如:

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库中进行跟踪: 无法将System.console()与Gradle守护程序一起使用 。

出于某种原因,在守护进程模式下运行gradle会导致一个空的控制台对象。 如果你指定了适当的命令行标志,

./gradlew assembleRelease --no-daemon

它会工作。

我在https://www.timroes.de/2014/01/19/using-password-prompts-with-gradle-build-filesfind了一个解决scheme,稍作修改。; 尽pipe如此,所有的信用都去蒂姆罗斯!

 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文件的某个地方,您已经定义了版本签名的configuration。

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

(别忘了import groovy.swing.SwingBuilder 。)

关于第二部分,您可能还会看看如何使用Gradle创build一个发布已签名的apk文件?

好吧,这不起作用的原因是愚蠢的,但以防万一遇到它,我想我会张贴。

我通过android studio运行任务,并没有意识到控制台对象将始终为空。 从命令行运行时,“命令”对象不为空,它工作正常。

看看这个博客文章( https://www.timroes.de/2013/09/22/handling-signing-configs-with-gradle/ )。

它描述了处理签名configuration的多种方式,其中之一就是关于密码input控制台的问题。

org.gradle.daemon属性为true ,从Gradle执行System.getConsole() ,或者从IDE(如IntelliJAndroid 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并使用addProperty定义的值作为属性名称添加ant.input中的用户input。 如果没有用户input,则使用default属性中定义的值。

一旦执行,您可以使用ant.properties.yourPropertyant.properties['yourProperty']获取用户input。

你可以在这里检查其余的ant.input属性 。

注意:如果你想多次使用ant.input考虑到你不能覆盖和现有的属性,所以addProperty属性必须是不同的每一个。

简单的解决scheme是检查控制台对象为空:

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

Android Studio不再抱怨null object

要隐藏types化字符,请使用readPassword()而不是readLine()

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

您也可以使用以下命令执行脚本:

-Dorg.gradle.daemon = FALSE