Grails:将插件类导入_Events.groovy [英] Grails: importing plugin classes to _Events.groovy

查看:99
本文介绍了Grails:将插件类导入_Events.groovy的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个Grails插件,它添加了一个自定义测试类型类(扩展 GrailsTestTypeSupport )和自定义测试结果类(扩展 GrailsTestTypeResult )来支持我在 test-app other 阶段运行的自定义测试类型。脚本。在我的本地机器上测试这个功能已经非常流行,但是......当我将该插件打包到我的应用程序中使用时,测试在我们的CI服务器上爆炸了(Jenkins )。这是Jenkins正在吐出的错误:

 无法解析类CustomTestResult @ line 58,column 9. 
new CustomTestResult(tests.size() - 失败,失败)

看来我不能简单地 import 这些类放入 _Events.groovy 中,并且这些类不在类路径中。但是如果我能弄清楚如何将它们放到类路径中,我会被诅咒的。这是我到目前为止( _Events.groovy ):

  import java.lang.reflect.Constructor 

eventAllTestsStart = {
if(!otherTests)otherTests = []

loadCustomTestResult()
otherTests< < createCustomTestType()
}

private def createCustomTestType(String name ='js',String relativeSourcePath ='js'){
ClassLoader parent = getClass()。getClassLoader()
GroovyClassLoader loader = new GroovyClassLoader(parent)
class customTestTypeClass = loader.parseClass(new File($ {customTestPluginDir} /src/groovy/custom/test/CustomTestType.groovy))
构造函数customTestTypeConstructor = customTestTypeClass.getConstructor(String,String)
def customTestType = customTestTypeConstructor.newInstance(name,relativeSourcePath)
$ b customTestType
}

private def loadCustomTestResult (){
ClassLoader parent = getClass()。getClassLoader()
GroovyClassLoader loader = new GroovyClassLoader(parent)$ b $ Class class customTestResultClass = loader.parseClass(new File($ {customTestPluginDir} / src /groovy/custom/test/CustomTestResult.groovy))
}

目前: CustomTestResult 仅在 CustomTestType 中引用。据我所知, _Events.groovy 正在加载 CustomTestType ,但它失败了,因为它坚持认为 CustomTestResult 不在类路径中。



抛开一段时间,看起来很疯狂, - 为测试循环开始的类路径上的家庭课程开始......我不太确定自己被绊倒的地方。任何帮助或指针将不胜感激。

解决方案

@ Ian Roberts' 答案让我大致指出了正确的方向,并与来自 _Events.groovy 脚本结合/grails-cucumber/blob/master/scripts/_Events.groovyrel =nofollow noreferrer>这个 grails-cucumber 插件,我设法通过有了这个解决方案:



首先, _Events.groovy 变成了这样:

  eventAllTestsStart = {if(!otherTests)otherTests = []} 

eventTestPhasesStart = {phases - >
if(!phases.contains('other')){return}

// classLoader.loadClass business per Ian Roberts:
otherTests<< classLoader.loadClass('custom.test.CustomTestType')。newInstance('js','js')
}

这比我在本主题开始时的可读性要好得多。但是:我处于大致相同的位置:我的 ClassNotFoundException 被从 _Events.groovy 中抛出在 CustomTestType 中,当它试图创建一个 custom.test的实例时。 CustomTestResult 。因此,在 CustomTestType 中,我添加了以下方法:

prerivate私人GrailsTestTypeResult createResult (通过,失败){
尝试{
返回新的customTestResult(传递失败)
} catch(ClassNotFoundException cnf){
class customTestResult = buildBinding.classLoader.loadClass('custom .test.CustomTestResult')
return customTestResult.newInstance(passed,failed)
}
}

所以Ian是对的,因为 classLoader 来救援 - 我只是在两个地方需要它的魔力。


I've created a Grails plugin which adds a custom test type class (extending GrailsTestTypeSupport) and custom test result class (extending GrailsTestTypeResult) to support a custom test type that I run during the other phase of the test-app script. Testing this on my local machine has gone swimmingly but...

When I packaged the plugin to use in my app, the tests are blowing up on our CI server (Jenkins). Here's the error that Jenkins is spitting out:

unable to resolve class CustomTestResult  @ line 58, column 9.
       new CustomTestResult(tests.size() - failed, failed)

It appears that I cannot simply import these classes into _Events.groovy, and the classes are not otherwise on the classpath. But I'll be damned if I can figure out how to get them onto the classpath. Here's what I have so far (in _Events.groovy):

import java.lang.reflect.Constructor

eventAllTestsStart = {
  if (!otherTests) otherTests = []

  loadCustomTestResult()
  otherTests << createCustomTestType()
}

private def createCustomTestType(String name = 'js', String relativeSourcePath = 'js') {
  ClassLoader parent = getClass().getClassLoader()
  GroovyClassLoader loader = new GroovyClassLoader(parent)
  Class customTestTypeClass = loader.parseClass(new File("${customTestPluginDir}/src/groovy/custom/test/CustomTestType.groovy"))
  Constructor customTestTypeConstructor = customTestTypeClass.getConstructor(String, String)
  def customTestType = customTestTypeConstructor.newInstance(name, relativeSourcePath)

  customTestType
}

private def loadCustomTestResult() {
  ClassLoader parent = getClass().getClassLoader()
  GroovyClassLoader loader = new GroovyClassLoader(parent)
  Class customTestResultClass = loader.parseClass(new File("${customTestPluginDir}/src/groovy/custom/test/CustomTestResult.groovy"))
}

Currently: CustomTestResult is only referenced from within CustomTestType. As far as I can tell, _Events.groovy is loading CustomTestType but it is failing because it then insists that CustomTestResult is not on the classpath.

Putting aside for a moment that it seems crazy that there's this much overhead to get plugin-furnished classes onto the classpath for the test cycle to begin with... I'm not quite sure where I've gotten tripped up. Any help or pointers would be greatly appreciated.

解决方案

@Ian Roberts' answer got me pointed in roughly the right direction, and combined with the _Events.groovy script from this grails-cucumber plugin, I managed to come through with this solution:

First, _Events.groovy became this:

eventAllTestsStart = { if (!otherTests) otherTests = [] }

eventTestPhasesStart = { phases ->
  if (!phases.contains('other')) { return }

  // classLoader.loadClass business per Ian Roberts:
  otherTests << classLoader.loadClass('custom.test.CustomTestType').newInstance('js', 'js')
}

Which is far more readable than where I was at the start of this thread. But: I was in roughly the same position: my ClassNotFoundException moved from being thrown in _Events.groovy to being thrown from within CustomTestType when it tried to create an instance of custom.test. CustomTestResult. So within CustomTestType, I added the following method:

private GrailsTestTypeResult createResult(passed, failed) {
  try {
    return new customTestResult(passed, failed)
  } catch(ClassNotFoundException cnf) {
    Class customTestResult = buildBinding.classLoader.loadClass('custom.test.CustomTestResult')
    return customTestResult.newInstance(passed, failed)
  }
}

So Ian was right, inasmuch as classLoader came to the rescue -- I just wound up needing its magic in two places.

这篇关于Grails:将插件类导入_Events.groovy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆