Grails: importing plugin classes to _Events.groovy

最后都变了- 提交于 2019-12-12 18:33:24

问题


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.


回答1:


Have you tried simply loading the class in question via the ClassLoader that is accessible via the classLoader variable in _Events.groovy?

Class customTestTypeClass = classLoader.loadClass('custom.test.CustomTestType')
// use nice groovy overloading of Class.newInstance
return customTestTypeClass.newInstance(name, relativeSourcePath)

You should be late enough in the process at eventAllTestsStart for this to be valid.




回答2:


@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.



来源:https://stackoverflow.com/questions/13328510/grails-importing-plugin-classes-to-events-groovy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!