Groovy 使用继承的命令无法在 Spring 远程引导中编译 shell
Groovy command using inheritance cannot compile in Spring Boot remote shell
我有一个抽象 groovy class,其中包含一些我想从其他 groovy 命令 classes 扩展的实用方法(用于 Spring 启动的远程 shell)。但是,当我尝试 运行 groovy 命令 class 时,我得到 CommandException
.
我的 groovy 摘要 class 如下所示。
package commands
import com.xyz.MyService
import org.crsh.command.InvocationContext
import org.springframework.beans.factory.BeanFactory
abstract class abstractcmd {
private static final String SPRING_FACTORY = "spring.beanfactory"
protected MyService getMyService(InvocationContext context) {
return getBeanFactory(context).getBean(MyService.class);
}
private BeanFactory getBeanFactory(InvocationContext context) {
return context.attributes[SPRING_FACTORY];
}
}
我的 groovy 命令 class 如下所示。
package commands
import org.crsh.cli.Command
import org.crsh.cli.Usage
import org.crsh.command.InvocationContext
@Usage("do something commands")
class foo extends abstractcmd {
@Command
@Usage("bar")
def String bar(InvocationContext context) {
try {
getMyService(context).bar()
return "did bar"
} catch (Exception e) {
return String.format("could not do bar: %s", e.toString())
}
}
}
当我通过 SSH 进入 shell 并执行 foo bar
时,出现以下异常。
org.crsh.shell.impl.command.spi.CommandException: Could not create command foo instance
at org.crsh.lang.impl.groovy.GroovyCompiler.getCommand(GroovyCompiler.java:192) ~[crash.shell-1.3.2.jar:?]
at org.crsh.lang.LanguageCommandResolver.resolveCommand(LanguageCommandResolver.java:101) ~[crash.shell-1.3.2.jar:?]
at org.crsh.shell.impl.command.CRaSH.getCommand(CRaSH.java:100) ~[crash.shell-1.3.2.jar:?]
at org.crsh.shell.impl.command.CRaSHSession.getCommand(CRaSHSession.java:96) ~[crash.shell-1.3.2.jar:?]
at org.crsh.lang.impl.script.PipeLineFactory.create(PipeLineFactory.java:89) ~[crash.shell-1.3.2.jar:?]
at org.crsh.lang.impl.script.ScriptRepl.eval(ScriptRepl.java:88) ~[crash.shell-1.3.2.jar:?]
at org.crsh.shell.impl.command.CRaSHSession.createProcess(CRaSHSession.java:163) ~[crash.shell-1.3.2.jar:?]
at org.crsh.shell.impl.async.AsyncProcess.execute(AsyncProcess.java:172) ~[crash.shell-1.3.2.jar:?]
at org.crsh.console.Console.iterate(Console.java:219) ~[crash.shell-1.3.2.jar:?]
at org.crsh.console.Console.on(Console.java:158) ~[crash.shell-1.3.2.jar:?]
at org.crsh.console.Console.on(Console.java:135) ~[crash.shell-1.3.2.jar:?]
at org.crsh.console.jline.JLineProcessor.run(JLineProcessor.java:204) ~[crash.shell-1.3.2.jar:?]
at org.crsh.ssh.term.CRaSHCommand.run(CRaSHCommand.java:99) ~[crash.connectors.ssh-1.3.2.jar:?]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_111]
如果我从 abstractcmd
和 foo
classes 中删除 package commands
行,那么 IDE (IntelliJ) 和 shell 都抱怨 abstractcmd
找不到。
2017-03-19 19:34:06 ERROR org.crsh.shell.impl.command.CRaSHProcess.execute:84 - Error while evaluating request 'foo' Could not compile command script foo
org.crsh.shell.impl.command.spi.CommandException: Could not compile command script foo
at org.crsh.lang.impl.groovy.GroovyClassFactory.parse(GroovyClassFactory.java:65) ~[crash.shell-1.3.2.jar:?]
at org.crsh.lang.impl.groovy.GroovyCompiler.getCommand(GroovyCompiler.java:172) ~[crash.shell-1.3.2.jar:?]
at org.crsh.lang.LanguageCommandResolver.resolveCommand(LanguageCommandResolver.java:101) ~[crash.shell-1.3.2.jar:?]
at org.crsh.shell.impl.command.CRaSH.getCommand(CRaSH.java:100) ~[crash.shell-1.3.2.jar:?]
at org.crsh.shell.impl.command.CRaSHSession.getCommand(CRaSHSession.java:96) ~[crash.shell-1.3.2.jar:?]
at org.crsh.lang.impl.script.PipeLineFactory.create(PipeLineFactory.java:89) ~[crash.shell-1.3.2.jar:?]
at org.crsh.lang.impl.script.ScriptRepl.eval(ScriptRepl.java:88) ~[crash.shell-1.3.2.jar:?]
at org.crsh.shell.impl.command.CRaSHSession.createProcess(CRaSHSession.java:163) ~[crash.shell-1.3.2.jar:?]
at org.crsh.shell.impl.async.AsyncProcess.execute(AsyncProcess.java:172) ~[crash.shell-1.3.2.jar:?]
at org.crsh.console.Console.iterate(Console.java:219) ~[crash.shell-1.3.2.jar:?]
at org.crsh.console.Console.on(Console.java:158) ~[crash.shell-1.3.2.jar:?]
at org.crsh.console.Console.on(Console.java:135) ~[crash.shell-1.3.2.jar:?]
at org.crsh.console.jline.JLineProcessor.run(JLineProcessor.java:204) ~[crash.shell-1.3.2.jar:?]
at org.crsh.ssh.term.CRaSHCommand.run(CRaSHCommand.java:99) ~[crash.connectors.ssh-1.3.2.jar:?]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_111]
Caused by: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
foo: 9: unable to resolve class abstractcmd
@ line 9, column 1.
@Usage("bar")
^
1 error
at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310) ~[groovy-2.4.7.jar:2.4.7]
at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:946) ~[groovy-2.4.7.jar:2.4.7]
at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:593) ~[groovy-2.4.7.jar:2.4.7]
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:542) ~[groovy-2.4.7.jar:2.4.7]
at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298) ~[groovy-2.4.7.jar:2.4.7]
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268) ~[groovy-2.4.7.jar:2.4.7]
at org.crsh.lang.impl.groovy.GroovyClassFactory.parse(GroovyClassFactory.java:59) ~[crash.shell-1.3.2.jar:?]
... 14 more
如果我不扩展 abstractcmd
(从而在命令 class 中实现 "util" 方法,我能够使自定义命令正常工作的唯一方法) 并删除 package
行。
我正在使用 Spring Boot v1.5.1.RELEASE。
对我做错了什么有什么想法吗?
看起来 CRaSH 在 groovy classes 扩展其他 groovy classes 方面有问题,因为如果你不扩展一个,它工作得很好。
很抱歉,我没有时间全面调查如何以及为什么(corrections/updates 非常受欢迎),并且在 docs but the good news is that you can extend an abstract java class to achieve the same thing. I stumbled upon such a sample for the cron
command that extends a GroovyCommand
摘要中没有找到任何内容 class 与以下 javadoc:
/**
* The base command for Groovy class based commands.
*/
public abstract class GroovyCommand extends BaseCommand implements GroovyObject
因此,长话短说,您可以使用以下解决方法:
摘要SpringAwareCommand
javaclass
package crash.commands;
import org.crsh.command.BaseCommand;
import org.springframework.beans.factory.BeanFactory;
public abstract class SpringAwareCommand extends BaseCommand {
private static final String SPRING_BEAN_FACTORY = "spring.beanfactory";
protected <T> T getBean(Class<T> beanClass) {
return ((BeanFactory) this.context.getAttributes().get(SPRING_BEAN_FACTORY)).getBean(beanClass);
}
}
已更新foo
groovyclass
package crash.commands
import com.xyz.MyService
import org.crsh.cli.Command
import org.crsh.cli.Usage
@Usage("do something commands")
class foo extends SpringAwareCommand {
@Command
@Usage("bar")
def String bar() {
try {
getBean(MyService.class).bar()
return "did bar"
} catch (Exception e) {
return String.format("could not do bar: %s", e.toString())
}
}
}
我有一个抽象 groovy class,其中包含一些我想从其他 groovy 命令 classes 扩展的实用方法(用于 Spring 启动的远程 shell)。但是,当我尝试 运行 groovy 命令 class 时,我得到 CommandException
.
我的 groovy 摘要 class 如下所示。
package commands
import com.xyz.MyService
import org.crsh.command.InvocationContext
import org.springframework.beans.factory.BeanFactory
abstract class abstractcmd {
private static final String SPRING_FACTORY = "spring.beanfactory"
protected MyService getMyService(InvocationContext context) {
return getBeanFactory(context).getBean(MyService.class);
}
private BeanFactory getBeanFactory(InvocationContext context) {
return context.attributes[SPRING_FACTORY];
}
}
我的 groovy 命令 class 如下所示。
package commands
import org.crsh.cli.Command
import org.crsh.cli.Usage
import org.crsh.command.InvocationContext
@Usage("do something commands")
class foo extends abstractcmd {
@Command
@Usage("bar")
def String bar(InvocationContext context) {
try {
getMyService(context).bar()
return "did bar"
} catch (Exception e) {
return String.format("could not do bar: %s", e.toString())
}
}
}
当我通过 SSH 进入 shell 并执行 foo bar
时,出现以下异常。
org.crsh.shell.impl.command.spi.CommandException: Could not create command foo instance at org.crsh.lang.impl.groovy.GroovyCompiler.getCommand(GroovyCompiler.java:192) ~[crash.shell-1.3.2.jar:?] at org.crsh.lang.LanguageCommandResolver.resolveCommand(LanguageCommandResolver.java:101) ~[crash.shell-1.3.2.jar:?] at org.crsh.shell.impl.command.CRaSH.getCommand(CRaSH.java:100) ~[crash.shell-1.3.2.jar:?] at org.crsh.shell.impl.command.CRaSHSession.getCommand(CRaSHSession.java:96) ~[crash.shell-1.3.2.jar:?] at org.crsh.lang.impl.script.PipeLineFactory.create(PipeLineFactory.java:89) ~[crash.shell-1.3.2.jar:?] at org.crsh.lang.impl.script.ScriptRepl.eval(ScriptRepl.java:88) ~[crash.shell-1.3.2.jar:?] at org.crsh.shell.impl.command.CRaSHSession.createProcess(CRaSHSession.java:163) ~[crash.shell-1.3.2.jar:?] at org.crsh.shell.impl.async.AsyncProcess.execute(AsyncProcess.java:172) ~[crash.shell-1.3.2.jar:?] at org.crsh.console.Console.iterate(Console.java:219) ~[crash.shell-1.3.2.jar:?] at org.crsh.console.Console.on(Console.java:158) ~[crash.shell-1.3.2.jar:?] at org.crsh.console.Console.on(Console.java:135) ~[crash.shell-1.3.2.jar:?] at org.crsh.console.jline.JLineProcessor.run(JLineProcessor.java:204) ~[crash.shell-1.3.2.jar:?] at org.crsh.ssh.term.CRaSHCommand.run(CRaSHCommand.java:99) ~[crash.connectors.ssh-1.3.2.jar:?] at java.lang.Thread.run(Thread.java:745) [?:1.8.0_111]
如果我从 abstractcmd
和 foo
classes 中删除 package commands
行,那么 IDE (IntelliJ) 和 shell 都抱怨 abstractcmd
找不到。
2017-03-19 19:34:06 ERROR org.crsh.shell.impl.command.CRaSHProcess.execute:84 - Error while evaluating request 'foo' Could not compile command script foo org.crsh.shell.impl.command.spi.CommandException: Could not compile command script foo at org.crsh.lang.impl.groovy.GroovyClassFactory.parse(GroovyClassFactory.java:65) ~[crash.shell-1.3.2.jar:?] at org.crsh.lang.impl.groovy.GroovyCompiler.getCommand(GroovyCompiler.java:172) ~[crash.shell-1.3.2.jar:?] at org.crsh.lang.LanguageCommandResolver.resolveCommand(LanguageCommandResolver.java:101) ~[crash.shell-1.3.2.jar:?] at org.crsh.shell.impl.command.CRaSH.getCommand(CRaSH.java:100) ~[crash.shell-1.3.2.jar:?] at org.crsh.shell.impl.command.CRaSHSession.getCommand(CRaSHSession.java:96) ~[crash.shell-1.3.2.jar:?] at org.crsh.lang.impl.script.PipeLineFactory.create(PipeLineFactory.java:89) ~[crash.shell-1.3.2.jar:?] at org.crsh.lang.impl.script.ScriptRepl.eval(ScriptRepl.java:88) ~[crash.shell-1.3.2.jar:?] at org.crsh.shell.impl.command.CRaSHSession.createProcess(CRaSHSession.java:163) ~[crash.shell-1.3.2.jar:?] at org.crsh.shell.impl.async.AsyncProcess.execute(AsyncProcess.java:172) ~[crash.shell-1.3.2.jar:?] at org.crsh.console.Console.iterate(Console.java:219) ~[crash.shell-1.3.2.jar:?] at org.crsh.console.Console.on(Console.java:158) ~[crash.shell-1.3.2.jar:?] at org.crsh.console.Console.on(Console.java:135) ~[crash.shell-1.3.2.jar:?] at org.crsh.console.jline.JLineProcessor.run(JLineProcessor.java:204) ~[crash.shell-1.3.2.jar:?] at org.crsh.ssh.term.CRaSHCommand.run(CRaSHCommand.java:99) ~[crash.connectors.ssh-1.3.2.jar:?] at java.lang.Thread.run(Thread.java:745) [?:1.8.0_111] Caused by: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: foo: 9: unable to resolve class abstractcmd @ line 9, column 1. @Usage("bar") ^ 1 error at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310) ~[groovy-2.4.7.jar:2.4.7] at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:946) ~[groovy-2.4.7.jar:2.4.7] at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:593) ~[groovy-2.4.7.jar:2.4.7] at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:542) ~[groovy-2.4.7.jar:2.4.7] at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298) ~[groovy-2.4.7.jar:2.4.7] at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268) ~[groovy-2.4.7.jar:2.4.7] at org.crsh.lang.impl.groovy.GroovyClassFactory.parse(GroovyClassFactory.java:59) ~[crash.shell-1.3.2.jar:?] ... 14 more
如果我不扩展 abstractcmd
(从而在命令 class 中实现 "util" 方法,我能够使自定义命令正常工作的唯一方法) 并删除 package
行。
我正在使用 Spring Boot v1.5.1.RELEASE。
对我做错了什么有什么想法吗?
看起来 CRaSH 在 groovy classes 扩展其他 groovy classes 方面有问题,因为如果你不扩展一个,它工作得很好。
很抱歉,我没有时间全面调查如何以及为什么(corrections/updates 非常受欢迎),并且在 docs but the good news is that you can extend an abstract java class to achieve the same thing. I stumbled upon such a sample for the cron
command that extends a GroovyCommand
摘要中没有找到任何内容 class 与以下 javadoc:
/**
* The base command for Groovy class based commands.
*/
public abstract class GroovyCommand extends BaseCommand implements GroovyObject
因此,长话短说,您可以使用以下解决方法:
摘要SpringAwareCommand
javaclass
package crash.commands;
import org.crsh.command.BaseCommand;
import org.springframework.beans.factory.BeanFactory;
public abstract class SpringAwareCommand extends BaseCommand {
private static final String SPRING_BEAN_FACTORY = "spring.beanfactory";
protected <T> T getBean(Class<T> beanClass) {
return ((BeanFactory) this.context.getAttributes().get(SPRING_BEAN_FACTORY)).getBean(beanClass);
}
}
已更新foo
groovyclass
package crash.commands
import com.xyz.MyService
import org.crsh.cli.Command
import org.crsh.cli.Usage
@Usage("do something commands")
class foo extends SpringAwareCommand {
@Command
@Usage("bar")
def String bar() {
try {
getBean(MyService.class).bar()
return "did bar"
} catch (Exception e) {
return String.format("could not do bar: %s", e.toString())
}
}
}