如何设置基于Java的Spring Boot应用程序以使用Groovy脚本

时间:2015-01-22 22:27:07

标签: groovy spring-boot

如何设置一个主要用java编写的Spring Boot应用程序,并且能够引用Groovy脚本?

我阅读了以下文章:

http://www.ibm.com/developerworks/library/j-groovierspring1/ http://www.ibm.com/developerworks/library/j-groovierspring2/

这些都是在Spring Boot之前编写的。我想在我的基于Java的Spring Boot应用程序中运行Groovy脚本的动态特性。我不想在带外编译我的Groovy类并引用它们。我想要脚本功能(如链接网页中所述)。

到目前为止我所做的只是创建一个简单的Spring Boot应用程序,它真的什么都不做,并试图让应用程序识别由Groovy脚本实现的bean。我使用了链接文章中提到的GroovyPdfGenerator的修改版本。

这就是我所拥有的:

// PdfGenerator.java, lives under demo
package demo;
public interface PdfGenerator {
    String pdfFor(String name);
}

// GroovyPdfGenerator.groovy, lives under demo
package demo
import demo.PdfGenerator
class GroovyPdfGenerator implements PdfGenerator {
    public String pdfFor(String name) {
        return "Hello, World!"
    }
}

// beans.xml, lives under src/main/resources
<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-4.1.xsd
    http://www.springframework.org/schema/lang
    http://www.springframework.org/schema/lang/spring-lang-2.0.xsd">
    <lang:groovy id="pdfGenerator" script source="classpath:GroovyPdfGenerator.groovy"/>
</beans>

// DemoGroovyTaskApplication.java, lives under demo
package demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
@SpringBootApplication
@ImportResource(value = { "classpath:beans.xml" })
public class DemoGroovyTaskApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoGroovyTaskApplication.class, args);
    }
}

我尝试将Groovy文件移动到资源/下但不起作用。另外,除了使用XML配置之外,我无法弄清楚如何让Spring Boot加载Groovy bean。

任何人都知道这可能有用吗?

忘记提及,我得到的代码是ClassNotFoundException。我打破了那个例外,Spring正在寻找scriptFactory.pdfGenerator

这是启用调试的堆栈跟踪(无负匹配):

2015-01-23 05:47:49.646  INFO 56013 --- [          main] demo.DemoGroovyTaskApplication        : Starting DemoGroovyTaskApplication on gary-fong2.local with PID 56013 (/Users/gary.fong/development/spring/experiments/my-workspace/demoGroovyTask/target/classes started by gary.fong in /Users/gary.fong/development/spring/experiments/my-workspace/demoGroovyTask)
2015-01-23 05:47:49.650 DEBUG 56013 --- [          main] o.s.boot.SpringApplication            : Loading source class demo.DemoGroovyTaskApplication
2015-01-23 05:47:49.694 DEBUG 56013 --- [          main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application.yaml' resource not found
2015-01-23 05:47:49.694 DEBUG 56013 --- [          main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application.xml' resource not found
2015-01-23 05:47:49.694 DEBUG 56013 --- [          main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application.properties' resource not found
2015-01-23 05:47:49.694 DEBUG 56013 --- [          main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application.yml' resource not found
2015-01-23 05:47:49.694 DEBUG 56013 --- [          main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application.yaml' resource not found
2015-01-23 05:47:49.694 DEBUG 56013 --- [          main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application.xml' resource not found
2015-01-23 05:47:49.694 DEBUG 56013 --- [          main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application.properties' resource not found
2015-01-23 05:47:49.695 DEBUG 56013 --- [          main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application.yml' resource not found
2015-01-23 05:47:49.695 DEBUG 56013 --- [          main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application.yaml' resource not found
2015-01-23 05:47:49.695 DEBUG 56013 --- [          main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application.xml' resource not found
2015-01-23 05:47:49.695 DEBUG 56013 --- [          main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application.properties' resource not found
2015-01-23 05:47:49.695 DEBUG 56013 --- [          main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application.yml' resource not found
2015-01-23 05:47:49.695 DEBUG 56013 --- [          main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application.yaml' resource not found
2015-01-23 05:47:49.695 DEBUG 56013 --- [          main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application.xml' resource not found
2015-01-23 05:47:49.695 DEBUG 56013 --- [          main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application.properties' 
2015-01-23 05:47:49.695 DEBUG 56013 --- [          main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application.yml' resource not found
2015-01-23 05:47:49.700  INFO 56013 --- [          main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@a39e3dd: startup date [Fri Jan 23 05:47:49 PST 2015]; root of context hierarchy
2015-01-23 05:47:50.014  INFO 56013 --- [          main] o.s.b.f.xml.XmlBeanDefinitionReader      : Loading XML bean definitions from class path resource [beans.xml]
2015-01-23 05:47:50.377  INFO 56013 --- [          main] .b.l.ClasspathLoggingApplicationListener : Application failed to start with classpath: [file:/Users/gary.fong/development/spring/experiments/my-workspace/demoGroovyTask/target/classes/, file:/Users/gary.fong/.m2/repository/org/springframework/boot/spring-boot-starter/1.2.1.RELEASE/spring-boot-starter-1.2.1.RELEASE.jar, file:/Users/gary.fong/.m2/repository/org/springframework/boot/spring-boot/1.2.1.RELEASE/spring-boot-1.2.1.RELEASE.jar, file:/Users/gary.fong/.m2/repository/org/springframework/spring-context/4.1.4.RELEASE/spring-context-4.1.4.RELEASE.jar, file:/Users/gary.fong/.m2/repository/org/springframework/spring-aop/4.1.4.RELEASE/spring-aop-4.1.4.RELEASE.jar, file:/Users/gary.fong/.m2/repository/aopalliance/aopalliance/1.0/aopalliance-1.0.jar, file:/Users/gary.fong/.m2/repository/org/springframework/spring-beans/4.1.4.RELEASE/spring-beans-4.1.4.RELEASE.jar, file:/Users/gary.fong/.m2/repository/org/springframework/spring-expression/4.1.4.RELEASE/spring-expression-4.1.4.RELEASE.jar, file:/Users/gary.fong/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/1.2.1.RELEASE/spring-boot-autoconfigure-1.2.1.RELEASE.jar, file:/Users/gary.fong/.m2/repository/org/springframework/boot/spring-boot-starter-logging/1.2.1.RELEASE/spring-boot-starter-logging-1.2.1.RELEASE.jar, file:/Users/gary.fong/.m2/repository/org/slf4j/jcl-over-slf4j/1.7.8/jcl-over-slf4j-1.7.8.jar, file:/Users/gary.fong/.m2/repository/org/slf4j/slf4j-api/1.7.8/slf4j-api-1.7.8.jar, file:/Users/gary.fong/.m2/repository/org/slf4j/jul-to-slf4j/1.7.8/jul-to-slf4j-1.7.8.jar, file:/Users/gary.fong/.m2/repository/org/slf4j/log4j-over-slf4j/1.7.8/log4j-over-slf4j-1.7.8.jar, file:/Users/gary.fong/.m2/repository/ch/qos/logback/logback-classic/1.1.2/logback-classic-1.1.2.jar, file:/Users/gary.fong/.m2/repository/ch/qos/logback/logback-core/1.1.2/logback-core-1.1.2.jar, file:/Users/gary.fong/.m2/repository/org/springframework/spring-core/4.1.4.RELEASE/spring-core-4.1.4.RELEASE.jar, file:/Users/gary.fong/.m2/repository/org/yaml/snakeyaml/1.14/snakeyaml-1.14.jar]
2015-01-23 05:47:50.378 DEBUG 56013 --- [          main] utoConfigurationReportLoggingInitializer : 
=========================
AUTO-CONFIGURATION REPORT
=========================
Positive matches:
-----------------
   JmxAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.jmx.export.MBeanExporter (OnClassCondition)
      - matched (OnPropertyCondition)
   JmxAutoConfiguration#mbeanExporter
      - @ConditionalOnMissingBean (types: org.springframework.jmx.export.MBeanExporter; SearchStrategy: current) found no beans (OnBeanCondition)
   JmxAutoConfiguration#mbeanServer
      - @ConditionalOnMissingBean (types: javax.management.MBeanServer; SearchStrategy: all) found no beans (OnBeanCondition)
   JmxAutoConfiguration#objectNamingStrategy
      - @ConditionalOnMissingBean (types: org.springframework.jmx.export.naming.ObjectNamingStrategy; SearchStrategy: current) found no beans (OnBeanCondition)
   PropertyPlaceholderAutoConfiguration#propertySourcesPlaceholderConfigurer
      - @ConditionalOnMissingBean (types: org.springframework.context.support.PropertySourcesPlaceholderConfigurer; SearchStrategy: current) found no beans (OnBeanCondition)
2015-01-23 05:47:50.384 ERROR 56013 --- [          main] o.s.boot.SpringApplication            : Application startup failed
java.lang.NoClassDefFoundError: org/codehaus/groovy/control/CompilationFailedException
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2615)
    at java.lang.Class.getDeclaredMethods(Class.java:1860)
    at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:571)
    at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:490)
    at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:474)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors(AutowiredAnnotationBeanPostProcessor.java:241)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineConstructorsFromBeanPostProcessors(AbstractAutowireCapableBeanFactory.java:1057)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1030)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.scripting.support.ScriptFactoryPostProcessor.prepareScriptBeans(ScriptFactoryPostProcessor.java:357)
    at org.springframework.scripting.support.ScriptFactoryPostProcessor.predictBeanType(ScriptFactoryPostProcessor.java:251)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:599)
    at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1397)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:434)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:404)
    at org.springframework.context.support.AbstractApplicationContext.getBeanNamesForType(AbstractApplicationContext.java:1046)
    at org.springframework.context.support.AbstractApplicationContext.registerListeners(AbstractApplicationContext.java:726)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:477)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:961)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:950)
    at demo.DemoGroovyTaskApplication.main(DemoGroovyTaskApplication.java:11)
Caused by: java.lang.ClassNotFoundException: org.codehaus.groovy.control.CompilationFailedException
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 29 common frames omitted
2015-01-23 05:47:50.384  INFO 56013 --- [          main] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@a39e3dd: startup date [Fri Jan 23 05:47:49 PST 2015]; root of context hierarchy
2015-01-23 05:47:50.386  WARN 56013 --- [          main] s.c.a.AnnotationConfigApplicationContext : Exception thrown from LifecycleProcessor on context close
java.lang.IllegalStateException: LifecycleProcessor not initialized - call 'refresh' before invoking lifecycle methods via the context: org.springframework.context.annotation.AnnotationConfigApplicationContext@a39e3dd: startup date [Fri Jan 23 05:47:49 PST 2015]; root of context hierarchy
    at org.springframework.context.support.AbstractApplicationContext.getLifecycleProcessor(AbstractApplicationContext.java:357)
    at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:877)
    at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:836)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:343)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:961)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:950)
    at demo.DemoGroovyTaskApplication.main(DemoGroovyTaskApplication.java:11)
Exception in thread "main" java.lang.NoClassDefFoundError: org/codehaus/groovy/control/CompilationFailedException
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2615)
    at java.lang.Class.getDeclaredMethods(Class.java:1860)
    at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:571)
    at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:490)
    at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:474)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors(AutowiredAnnotationBeanPostProcessor.java:241)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineConstructorsFromBeanPostProcessors(AbstractAutowireCapableBeanFactory.java:1057)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1030)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.scripting.support.ScriptFactoryPostProcessor.prepareScriptBeans(ScriptFactoryPostProcessor.java:357)
    at org.springframework.scripting.support.ScriptFactoryPostProcessor.predictBeanType(ScriptFactoryPostProcessor.java:251)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:599)
    at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1397)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:434)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:404)
    at org.springframework.context.support.AbstractApplicationContext.getBeanNamesForType(AbstractApplicationContext.java:1046)
    at org.springframework.context.support.AbstractApplicationContext.registerListeners(AbstractApplicationContext.java:726)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:477)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:961)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:950)
    at demo.DemoGroovyTaskApplication.main(DemoGroovyTaskApplication.java:11)
Caused by: java.lang.ClassNotFoundException: org.codehaus.groovy.control.CompilationFailedException
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 29 more

1 个答案:

答案 0 :(得分:3)

我能够解决我的问题。

我必须1)安装Groovy-Eclipse,2)将Groovy库添加到构建路径。为了更好地衡量,我还启用了[启用脚本文件夹支持],以便我的脚本不会在构建时编译。

一旦我完成了所有这些,Eclipse报告了我的&#34; import&#34; Groovy脚本中的语句。一旦我删除了它,一切都奏效了。很酷。

全部谢谢