首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不能使用GroovyClassLoader动态更改或添加类中的方法

不能使用GroovyClassLoader动态更改或添加类中的方法
EN

Stack Overflow用户
提问于 2010-11-27 04:10:39
回答 1查看 1.3K关注 0票数 0

我尝试从另一个groovy脚本中动态地更改和添加在groovy脚本中定义的类的方法,但是如果我直接在.metaClass中使用类名,我就不明白为什么会这样。但是如果我使用GroovyClassLoader加载这个类就不会了(我需要这样做!)。

在一个文件'MyTest.groovy‘中,我有

代码语言:javascript
复制
class MyTest {

   public void setUp() {
      println "SET UP"
   }
   public void tearDown() {
      println "TEAR DOWN"
   }
   public void testA() {
      println "testA"
   }
}

另一个文件'suite.groovy‘包含

代码语言:javascript
复制
#!/usr/bin/env groovy

public class MyTestSuite {
   // For debug
   public static printClassLoader(Class cls) {
      ClassLoader loader = cls.classLoader
      while (loader) {
         println loader.class
         println loader.URLs.join("\n")
         println "\n\n"
         loader = loader.parent
      }
   }

   public static void suite()  {
      // First method to define my class (change/addition of methods works)
      //Class testClass = MyTest

      // Second way to define my class (change/addition of methods doesn't work)
      ClassLoader parent = MyTestSuite.class.getClassLoader();
      GroovyClassLoader gcl = new GroovyClassLoader(parent);
      Class testClass = gcl.parseClass(new File("MyTest.groovy"));

      printClassLoader(testClass)

      testClass.metaClass.setUp = {-> println "I'm your new setUp()" ;}
      testClass.metaClass.newTest = {-> println "I'm your new newTest()" ; }
   }
}

MyTestSuite.suite()
MyTest aTest = new MyTest()
aTest.setUp()
aTest.newTest()

使用第一种方法,我得到了预期的结果:

代码语言:javascript
复制
I'm your new setUp()
I'm your new newTest()

但用第二个我得到的

代码语言:javascript
复制
SET UP
Caught: groovy.lang.MissingMethodException: No signature of method: MyTest.newTest() is applicable for argument types: () values: []
Possible solutions: testA(), getAt(java.lang.String), wait(), inspect(), every()
    at suite.run(suite.groovy:34)

有趣的是,修改现有方法不起作用,但也没有例外,但尝试添加新方法会抛出一个异常。我估计它一定是对使用的类加载器做了些什么,但是不知道到底要改变什么!对于第一个版本,这里是类加载器,称为:

代码语言:javascript
复制
class groovy.lang.GroovyClassLoader$InnerLoader
class groovy.lang.GroovyClassLoader
class org.codehaus.groovy.tools.RootLoader
class sun.misc.Launcher$AppClassLoader
class sun.misc.Launcher$ExtClassLoader

对于第二个版本:

代码语言:javascript
复制
class groovy.lang.GroovyClassLoader$InnerLoader
class groovy.lang.GroovyClassLoader
class groovy.lang.GroovyClassLoader$InnerLoader
class groovy.lang.GroovyClassLoader
class org.codehaus.groovy.tools.RootLoader
class sun.misc.Launcher$AppClassLoader
class sun.misc.Launcher$ExtClassLoader

欢迎有任何想法!

弗兰克

EN

回答 1

Stack Overflow用户

发布于 2010-11-27 23:40:03

new GroovyClassLoader不是当前线程的Groovy类加载器。

它将在suite()方法完成后连同它自己的ClassMetaClass关联一起被处理。

但是,这是可行的:

代码语言:javascript
复制
Class testClass = gcl.parseClass(new File("MyTest.groovy"));
testClass = Class.forName(testClass.getName())
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4288288

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档