spring-shell
spring-shell copied to clipboard
BaseComponentContext containsKey is not accurate with get
ComponentFlow.ComponentFlowResult result = componentFlowBuilder.clone().reset()
.withConfirmationInput("id")
.name("确认删除?")
.and()
.build()
.run();
//输入y/n 之外的其他任意字符
//此时 Context {"id":null}
Boolean containsKey = result.getContext().containsKey("id"); // containsKey true
Boolean id = result.getContext().get("id"); // throw NoSuchElementException
问题原因: org.springframework.shell.component.context.BaseComponentContext.java
...
@Override
public Object get(Object key) {
Object o = super.get(key);
if (o != null) {
return o;
}
throw new NoSuchElementException("Context does not contain key: " + key);
}
...
期望将两个方法语义统一! 3q
I'm sorry but it is a bit difficult to understand a question what appears to be Chinese language?
ComponentFlow.ComponentFlowResult result = componentFlowBuilder.clone().reset()
.withConfirmationInput("id")
.name("confirm?")
.and()
.build()
.run();
//When entering any character other than y/n
//Now result.getContext() looks like this: Context {"id":null}
// containsKey return true
Boolean containsKey = result.getContext().containsKey("id");
// But it throw an exception when get the value(throw NoSuchElementException)
Boolean id = result.getContext().get("id");
because: org.springframework.shell.component.context.BaseComponentContext.java extends LinkedHashMap and override get() function
...
@Override
public Object get(Object key) {
Object o = super.get(key);
if (o != null) {
return o;
}
throw new NoSuchElementException("Context does not contain key: " + key);
}
...
can only be used like this:
try {
Boolean r = result.getContext().get("id");
if (r != null && r) {
...
return "done";
} else {
return "canceled";
}
} catch (NoSuchElementException e) {
return "invalid input";
}
expected usage:
if (result.getContext().containsKey("id")) {
boolean r = result.getContext().get("id");
return r ? "done" : "canceled";
} else {
return "invalid input";
}
Thanks clarifying your case and you're right. If containsKey is telling there is a key then it's expected that get returns something.
Hello @jvalkeal, can you provide any update to this issue? I am facing this issue at the moment too.
For me it occurs if i run or debug the spring-shell application from Intellij IDEA. If i run the application with java -jar target/app.jar it works as expected.
Hello, I got the same issue with the latest version of spring shell (3.3.3) and GraalVM 21 with native image, in Windows Powershell terminal. When i launch a command that use a ComponentFlow, I got the following exception : java.util.NoSuchElementException: Context does not contain key: serverPort
ComponentFlow flow = componentFlowBuilder.clone().reset()
.withConfirmationInput("changePassword")
.name("Souhaitez-vous changer le mot de passe de l'utilisateur admin par 'admin' ?")
.defaultValue(true)
.and()
.withStringInput("serverPort")
.name("Veuillez saisir un numéro de port pour le serveur :")
.defaultValue("auto")
.and()
.build();
ComponentFlow.ComponentFlowResult result = flow.run();
int serverPort = result.getContext().get("serverPort") == "auto" ? PortUtil.getNextAvailablePort(8080) : Integer.parseInt(result.getContext().get("serverPort"));
However, when using Windows Git Bash, this issue doesn't occurs. But the flow output is a bit broken... When using the jar version, everything works fine, even in Powershell.