Gradle构建空控制台对象

时间:2013-10-21 06:27:07

标签: gradle android-gradle build.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回购中正在跟踪此问题:Can't use System.console() with the Gradle Daemon

10 个答案:

答案 0 :(得分:43)

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

./gradlew assembleRelease --no-daemon

它会工作。

答案 1 :(得分:19)

我在https://www.timroes.de/2014/01/19/using-password-prompts-with-gradle-build-files处找到了一个解决方案并略微修改了它。尽管如此,所有学分都归Tim Roes所有!

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。)

关于第二部分,您还可以查看How to create a release signed apk file using Gradle?

答案 2 :(得分:16)

好吧,之所以不起作用的原因是愚蠢的,但为了防止其他人遇到它,我以为我会发帖。

我是通过android studio运行任务的,并没有意识到控制台对象总是为空。从命令行运行时,“command”对象不为null,并且工作正常。

答案 3 :(得分:9)

System.getConsole()属性为org.gradle.daemon时,或者从 IntelliJ 执行时,从 Gradle 执行true Android Studio 它会返回null。因此,例如,System.console().readLine()变得不可能。

此外,从Gradle 3.0 gradle.daemon is turned on by default开始。

然后使用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 attributes here的其余部分。

注意:如果您想多次使用addProperty,请考虑到您无法覆盖和现有属性,因此每个属性的.container属性必须不同。

答案 4 :(得分:7)

查看此博文(https://www.timroes.de/2013/09/22/handling-signing-configs-with-gradle/)。

它描述了处理签名配置的多种方法,其中一种方法正是关于密码的控制台输入的问题。

答案 5 :(得分:3)

对此的简单解决方案是检查控制台对象是否为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: "))

答案 6 :(得分:3)

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

-Dorg.gradle.daemon =假

答案 7 :(得分:3)

要解决此问题,我将标准输入流用作下一个:

println "Enter keystore password"
def password = System.in.newReader().readLine()

答案 8 :(得分:1)

创建一个简单的函数来请求密码:

import javax.swing.JOptionPane

def askPass() {
  def msg = 'Enter keystore password'
  if (System.console() != null) {
    return System.console().readLine(msg)
  } else {
    return javax.swing.JOptionPane.showInputDialog(msg)
  }
}

或者如果你想要答案:

import javax.swing.JOptionPane

def ask(msg) {
  if (System.console() != null) {
    return System.console().readLine(msg + ' [y/n]') == 'y'
  } else {
    def res = JOptionPane.showConfirmDialog(null, msg, "Confirm operation", JOptionPane.YES_NO_OPTION)
    return res == JOptionPane.YES_OPTION
  }
}

// usage:

task run() {
  doFirst {
    if (file('out.txt').exists() && !ask('overwrite output?')) {
      System.exit(2)
    }
  }
  ...
}

答案 9 :(得分:-1)

password System.console() != null ? System.console().readLine("\ password: ") : ""