0

我们使用以下技术堆栈开发了一个应用程序:

Struts 2.1 
Springs 3.1 
Groovy 1.8 
Tomcat 6.0.26 - For deployment 

我们的要求是将应用程序的特定层迁移到 Groovy。我们已经将该层迁移到 groovy 并且应用程序运行良好。迁移 groovy bean 后由 spring 容器正确初始化,但我们无法利用 Groovy 的“动态语言”功能。也就是说,当我们修改 Groovy 脚本时,更新的更改不会动态地反映回应用程序。

作为参考,我附上了一个 groovy 脚本的方法(GroovyConnection.groovy):

@Component 
class GroovyConnection implements EndPointManager, Serializable{ 
private static final long serialVersionUID = 1481681752777429674L; 
private final static Logger log = Logger.getLogger(GroovyConnection.class); 
private static final String DESTINATION_DIR = ARTIFACT_DIR_PATH.toString()+"/"; 
private static final String JIVE_USER = "";  //"jivescpt"; 
/** 
* @param default 
*/ 
public GroovyConnection() { 
    super(); 
    jschInstance = new JSch(); 
} 

public String executeCommands(Session session, String inputCommand, Device device) { 
log.info("Entering executeCommand() device:" + inputCommand); 
Channel channel = null; 
PipedOutputStream commandIO = null; 
InputStream sessionInput = null; 
InputStream sessionOutput = null; 
InputStream sessionError = null; 
String commandResponse = null; 
try { 
    channel = session.openChannel("shell"); 
    commandIO = new PipedOutputStream(); 
    sessionInput = new PipedInputStream(commandIO); 
    channel.setInputStream(sessionInput); 
    sessionOutput = channel.getInputStream(); 
    sessionError = channel.getExtInputStream(); 
    channel.connect(); 

    return fireCommandsOnTerminal(session, commandIO, sessionOutput, sessionError, inputCommand, device); 
} 
catch (JSchException e) { 
    log.error(AutomationConstants.ERROR_MSG.toString(), e); 
} 
catch (IOException e) { 
    log.error(AutomationConstants.ERROR_MSG.toString(), e); 
} 
catch (InterruptedException e) { 
    log.error(AutomationConstants.ERROR_MSG.toString(), e); 
} 
finally { 
    boolean isClosed = GroovyConnectionHelper.closeAll(session, channel, commandIO, sessionInput, sessionOutput, sessionError); 
    if (!isClosed) { 
        return AutomationUtils.getPropertyValue("jive.vpn.error.msg"); 
    } 
} 
log.info("Exiting executeCommand() device:" + inputCommand); 
return commandResponse; 
} 
} 

Groovy 上下文文件:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:lang="http://www.springframework.org/schema/lang"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd">
<lang:defaults refresh-check-delay="2000"/>
<lang:groovy id="endPointManager" 
             script-source="classpath:GroovyConnection.groovy" refresh-check-delay="1000">
</lang:groovy>
</beans>

即使在给定 1 秒的刷新检查延迟时间之后,groovy bean 在运行时也没有相应地表现。我必须重新启动 Tomcat 才能重新部署更新的 groovy 更改。看起来应用程序将 groovy bean 视为 java bean。

除此之外,如果我在不使用 Springs 的情况下执行 groovy 脚本,它会按预期执行。修改后的 groovy 脚本更改会动态反映回来。这是供参考的代码:

常规脚本:

package com
public class test1 {
def hello_world() {
    println "Connectddded"
    }
}

主类:

public static void main(String arg[]) {
 try {
        new GroovyShell().parse(newFile("test1.groovy")).invokeMethod("hello_world", null);              
    } catch (CompilationFailedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

根据我的理解,我们在 Spring-Groovy 集成配置中遗漏了一些允许我们刷新 Groovy bean 修改的内容,或者 Tomcat 不允许我们刷新更新的 groovy 脚本。

如果有人可以就此提供任何建议会有所帮助。提前致谢。

问候, Divya Garg

4

1 回答 1

1

感谢所有花时间阅读我的帖子的人。问题已解决。

实际上,我们同时使用了@component 和 groovy-context.xml 文件,因为我们遇到了这个问题。我已删除注释并将我的 groovy 文件放在类路径中。现在一切都按预期工作。Groovy bean 正在正确刷新。但是我无法使用弹簧注释来实现相同的效果。

现在我面临另一个问题,我为此做了很多尝试。我有另一个 groovy bean,其中我的所有静态方法都称为 (GroovyConnectionHelper.groovy)。我无法在 GroovyConnection.script 中调用这些静态方法。当应用程序执行应用程序时,在执行到达 GroovyConnectionHelper 静态方法的地方挂起。

为了解决我试图在 GroovyConnection 中注入 GroovyConnectionHelper bean 的问题,如下所示(这不是好的方法):

groovy-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:lang="http://www.springframework.org/schema/lang"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd">
    <lang:defaults refresh-check-delay="1000"/>
    <lang:groovy name="endPointManager" script-source="classpath:GroovyConnection.groovy">
         <lang:property name="groovyConnectionHelper" ref="groovyConnectionHelper"/>
    </lang:groovy>

    <lang:groovy id="groovyConnectionHelper" script-source="classpath:GroovyConnectionHelper.groovy"/>
</beans>

我将相同的设置器放在 GroovyConnection.groovy 中:

public void setGroovyConnectionHelper(GroovyConnectionHelper groovyConnectionHelper) {
    System.out.println( "Setting ----------------------------------------- groovyConnectionHelper : " + groovyConnectionHelper  );
    if ( null != groovyConnectionHelper ){
        System.out.println( "Object groovyConnectionHelper: ::: " + groovyConnectionHelper.dump() );
    }
    this.groovyConnectionHelper = groovyConnectionHelper;
} 

但这行不通。面对这个错误:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.scripting.groovy.GroovyScriptFactory#0': BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scriptedObject.org.springframework.scripting.groovy.GroovyScriptFactory#0': Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'groovyConnectionHelper' of bean class [GroovyConnection]: Bean property 'groovyConnectionHelper' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:452)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:848)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:790)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)
    ... 71 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scriptedObject.org.springframework.scripting.groovy.GroovyScriptFactory#0': Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'groovyConnectionHelper' of bean class [GroovyConnection]: Bean property 'groovyConnectionHelper' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1396)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1118)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:313)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.aop.target.dynamic.BeanFactoryRefreshableTargetSource.obtainFreshBean(BeanFactoryRefreshableTargetSource.java:77)
    at org.springframework.scripting.support.RefreshableScriptTargetSource.obtainFreshBean(RefreshableScriptTargetSource.java:79)
    at org.springframework.aop.target.dynamic.BeanFactoryRefreshableTargetSource.freshTarget(BeanFactoryRefreshableTargetSource.java:66)
    at org.springframework.aop.target.dynamic.AbstractRefreshableTargetSource.refresh(AbstractRefreshableTargetSource.java:97)
    at org.springframework.aop.target.dynamic.AbstractRefreshableTargetSource.getTargetClass(AbstractRefreshableTargetSource.java:68)
    at org.springframework.scripting.support.ScriptFactoryPostProcessor.createRefreshableProxy(ScriptFactoryPostProcessor.java:553)
    at org.springframework.scripting.support.ScriptFactoryPostProcessor.postProcessBeforeInstantiation(ScriptFactoryPostProcessor.java:322)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:880)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:852)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:446)
    ... 79 more
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'groovyConnectionHelper' of bean class [GroovyConnection]: Bean property 'groovyConnectionHelper' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
    at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1064)
    at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:924)
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:76)
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:58)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1393)
    ... 94 more

请建议我应该为此使用 Groovy Bean Injection 还是我们可以直接调用 groovy 静态方法。提前致谢

问候, Divya Garg

于 2013-01-25T15:01:25.917 回答