Gradle生成空控制台对象

Gradle生成空控制台对象,gradle,android-gradle-plugin,build.gradle,Gradle,Android Gradle Plugin,Build.gradle,我试图使用stack overflow中的示例,让我的gradle构建在控制台上提示输入密码 当我有一个陈述,例如: def password = System.console().readLine("Enter keystore password ") 当我运行时,我得到了错误 Cannot invoke method readLine() on null object 控制台显示为null。我读到这篇文章需要java 6,如果我在命令提示符下键入java-version我正在运行java

我试图使用stack overflow中的示例,让我的gradle构建在控制台上提示输入密码

当我有一个陈述,例如:

def password = System.console().readLine("Enter keystore password ")
当我运行时,我得到了错误

Cannot invoke method readLine() on null object
控制台显示为
null
。我读到这篇文章需要java 6,如果我在命令提示符下键入
java-version
我正在运行java(TM)SE运行时环境(build 1.6.0_27-b07)


Gradle的Github repo中正在跟踪这一问题:。

看看这篇博文()


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

好的,这不起作用的原因很愚蠢,但为了防止其他人遇到它,我想我会发布


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

简单的解决方案是检查console对象是否为空:

def password = null
def console = System.console()
if (console != null) {
    password = console.readLine("Enter keystore password: ")
}
Android Studio不再抱怨
空对象

要隐藏键入的字符,请使用
readPassword()
而不是
readLine()


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

/gradlew assembleerelease--没有守护进程


它会起作用的。

我在这里找到了一个解决方案,并对其进行了轻微修改。然而,所有的功劳都归蒂姆·罗斯所有

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
    }
}
(不要忘记导入groovy.swing.SwingBuilder)


关于第二部分,您还可以查看一下

您还可以使用以下工具执行脚本:


-Dorg.gradle.daemon=false

org.gradle.daemon
属性为
true
或从IntelliJ或Android Studio等IDE执行时,从gradle执行
System.getConsole()
。例如,do
System.console().readLine()
变得不可能

而且是从,

然后,不要使用
System.getConsole()
I替代方法,而是使用
ant.input
如下所示:

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

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

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)
    }
  }
  ...
}

为了解决这个问题,我使用标准输入流作为下一步:

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

这并不能解决没有控制台的问题。您希望通过命令行或控制台输入密码。现在您将遇到空密码的问题。在从两个位置运行时,您是否找到解决方法使其工作?在我的情况下,即使通过终端运行,对象也是空的。我没有尝试通过AS.Lol运行,这在一个项目上有效,但在另一个项目上无效。使用gradle 4.2>无法在null object上调用readPassword()方法Tim Roes解决方案不起作用,因为这是非常好的产品级修改,谢谢。不要忘记导入groovy.swing.SwingBuilder
,因为现在显示了一个关于导入groovy.swing.SwingBuilder的错误。幸运的是,它仍然可以进行调试构建,并且命令行gradlew仍然可以导入groovy。请看,哇,简单一点,只需使用:def pass=javax.swing.JOptionPane.showInputDialog(“请输入密码”)对我不起作用,我得到一个
无法为“dialog”创建组件的原因:java.awt.HeadlessException>java.awt.HeadlessException(无错误消息)
工作正常,有没有办法隐藏用户键入的内容?如果您使用的是
ant.version>1.8
,则向
ant.input添加
handler(type:'secure')
似乎很有效。。。我在
build.xml
中使用
进行检查,效果很好,但是在
build.gradle
中,等效的
ant.input(消息:“输入一些用户输入数据?”,addproperty:'userInput',defaultValue:'nothing'){handler(type:'secure')}
不隐藏用户输入:(这似乎是官方的解决方案:有效。但是,如何读取密码?
readPassword()
Console
类的函数。@galcyurio,
readPassword()
给了你什么
readLine()
没有的?它只是隐藏输入吗?根本不设置密码没有帮助。
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)
    }
  }
  ...
}
println "Enter keystore password"
def password = System.in.newReader().readLine()
password System.console() != null ? System.console().readLine("\ password: ") : ""