-1

我在尝试扩展 groovy 类时遇到问题。我通过构造文件路径、使用 Spring 的 BeanDefinitionRegistry 注册 bean,然后从应用程序上下文中检索它来扩展从 spring 应用程序上下文文件加载的 groovy 类。

private BeanDefinitionRegistry registry;

...

    GenericBeanDefinition bd = new GenericBeanDefinition();
    bd.setBeanClass(GroovyScriptFactory.class);
    bd.setAttribute(
            ScriptFactoryPostProcessor.REFRESH_CHECK_DELAY_ATTRIBUTE,
            refreshDelay);

    ConstructorArgumentValues cav = bd.getConstructorArgumentValues();
    cav.addGenericArgumentValue(groovyLocation + WordUtils.capitalize(name)
            + ".groovy");

    registry.registerBeanDefinition(name, bd);

...

        // retrieve it
        ExternalObject engine = (ExternalObject) this.applicationContext
                .getBean(engineName);

这似乎可以正常工作,除非我像这样扩展一个 groovy 类:

Cat.groovy:

package com.mycomp.external.engine;

import com.mycomp.external.ExternalObject;

    public class Cat extends ExternalObject {

    }

Lion.groovy

package com.mycomp.external.engine;

    public class Lion extends Cat {

    }

然后我得到了一个非常糟糕的错误:

Lion: 4: unable to resolve class Cat 
 @ line 4, column 1.
   public class Lion extends Cat {
   ^

1 error

    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:452) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1075) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at com.mycomp.external.ExternalAdFactoryImpl.getEngineByName(ExternalAdFactoryImpl.java:119) [adverter-1.9.0-SNAPSHOT.jar:na]
    at com.mycomp.external.BasicEngineTest.getEngine(BasicEngineTest.java:62) [test-classes/:na]
    at com.mycomp.external.BasicEngineTest.realModeGet(BasicEngineTest.java:108) [test-classes/:na]
    at com.mycomp.external.BasicEngineTest.testMany(BasicEngineTest.java:123) [test-classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [na:1.6.0_37]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [na:1.6.0_37]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [na:1.6.0_37]
    at java.lang.reflect.Method.invoke(Method.java:597) [na:1.6.0_37]
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:76) [testng-6.0.1.jar:na]
    at org.testng.internal.MethodInvocationHelper$1.runTestMethod(MethodInvocationHelper.java:178) [testng-6.0.1.jar:na]
    at org.springframework.test.context.testng.AbstractTestNGSpringContextTests.run(AbstractTestNGSpringContextTests.java:158) [spring-test-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [na:1.6.0_37]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [na:1.6.0_37]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [na:1.6.0_37]
    at java.lang.reflect.Method.invoke(Method.java:597) [na:1.6.0_37]
    at org.testng.internal.MethodInvocationHelper.invokeHookable(MethodInvocationHelper.java:191) [testng-6.0.1.jar:na]
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:666) [testng-6.0.1.jar:na]
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:846) [testng-6.0.1.jar:na]
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1170) [testng-6.0.1.jar:na]
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125) [testng-6.0.1.jar:na]
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109) [testng-6.0.1.jar:na]
    at org.testng.TestRunner.runWorkers(TestRunner.java:1147) [testng-6.0.1.jar:na]
    at org.testng.TestRunner.privateRun(TestRunner.java:749) [testng-6.0.1.jar:na]
    at org.testng.TestRunner.run(TestRunner.java:600) [testng-6.0.1.jar:na]
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:317) [testng-6.0.1.jar:na]
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:312) [testng-6.0.1.jar:na]
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:274) [testng-6.0.1.jar:na]
    at org.testng.SuiteRunner.run(SuiteRunner.java:223) [testng-6.0.1.jar:na]
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) [testng-6.0.1.jar:na]
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86) [testng-6.0.1.jar:na]
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1039) [testng-6.0.1.jar:na]
    at org.testng.TestNG.runSuitesLocally(TestNG.java:964) [testng-6.0.1.jar:na]
    at org.testng.TestNG.run(TestNG.java:900) [testng-6.0.1.jar:na]
    at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:70) [surefire-testng-2.8.1.jar:2.8.1]
    at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:102) [surefire-testng-2.8.1.jar:2.8.1]
    at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:114) [surefire-testng-2.8.1.jar:2.8.1]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [na:1.6.0_37]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [na:1.6.0_37]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [na:1.6.0_37]
    at java.lang.reflect.Method.invoke(Method.java:597) [na:1.6.0_37]
    at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103) [surefire-booter-2.8.1.jar:2.8.1]
    at $Proxy0.invoke(Unknown Source) [na:na]
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150) [surefire-booter-2.8.1.jar:2.8.1]
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91) [surefire-booter-2.8.1.jar:2.8.1]
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69) [surefire-booter-2.8.1.jar:2.8.1]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'Lion': Could not determine scripted object type for GroovyScriptFactory: script source locator [file:///Users/jkramer/source/backend/backend/config/../feeds/src/main/groovy/com/mycomp/external/engine/Lion.groovy]; nested exception is org.springframework.scripting.ScriptCompilationException: Could not compile script; nested exception is org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Lion: 4: unable to resolve class Cat 
 @ line 4, column 1.
   public class Lion extends Cat {
   ^

1 error

    at org.springframework.scripting.support.ScriptFactoryPostProcessor.postProcessBeforeInstantiation(ScriptFactoryPostProcessor.java:297) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:848) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:820) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:446) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    ... 50 common frames omitted
Caused by: org.springframework.scripting.ScriptCompilationException: Could not compile script; nested exception is org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Lion: 4: unable to resolve class Cat 
 @ line 4, column 1.
   public class Lion extends Cat {
   ^

1 error

    at org.springframework.scripting.groovy.GroovyScriptFactory.getScriptedObjectType(GroovyScriptFactory.java:217) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.scripting.support.ScriptFactoryPostProcessor.postProcessBeforeInstantiation(ScriptFactoryPostProcessor.java:290) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    ... 53 common frames omitted
Caused by: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Lion: 4: unable to resolve class Cat 
 @ line 4, column 1.
   public class Lion extends Cat {
   ^

1 error

    at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:302) [groovy-all-1.8.0.jar:1.8.0]
    at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:854) [groovy-all-1.8.0.jar:1.8.0]
    at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:544) [groovy-all-1.8.0.jar:1.8.0]
    at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:493) [groovy-all-1.8.0.jar:1.8.0]
    at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:306) [groovy-all-1.8.0.jar:1.8.0]
    at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:287) [groovy-all-1.8.0.jar:1.8.0]
    at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:267) [groovy-all-1.8.0.jar:1.8.0]
    at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:214) [groovy-all-1.8.0.jar:1.8.0]
    at org.springframework.scripting.groovy.GroovyScriptFactory.getScriptedObjectType(GroovyScriptFactory.java:201) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    ... 54 common frames omitted
17:26:54.942 [Hector.me.prettyprint.cassandra.connection.CassandraHostRetryService-1] INFO  m.p.c.c.CassandraHostRetryService - Not checking that 10.10.0.111(10.10.0.111):9160 is a member of the ring since there are no live hosts

任何帮助,将不胜感激!

4

1 回答 1

0

似乎没有直接的方法将两者都包含在源路径中(除非您设置的定位器在cav.addGenericArgumentValue(groovyLocation + WordUtils.capitalize(name) + ".groovy")与样式定位器路径一起使用时允许多个类classpath:,我对此表示怀疑)。我认为目的是让您加载的脚本自给自足。

您可以尝试将两者合并为一个 .groovy 类,但“24.3.3. Groovy beans”的结尾似乎将 kibosh 放在了上面。

如果您可以使用与加载类相同的机制加载超ExternalObject类,我认为这可能会做到(尽管这不太可能是您要寻找的)。

如果你可以避免使用继承,而是在你的Lion类中使用封装,你可能可以在你加载的类中使用 groovy 类加载器来安装一些 hacky 东西来拉入另一个类,但我承认我只是在那里挥手.

于 2012-12-19T05:06:57.117 回答