Hello All,
When I loadClass() from a script executed by a scriptrunner post function, none of the methods are available.
ie:
testMe = this.class.classLoader.loadClass( load_class, true )?.newInstance()
log.debug("testMe: " + testMe.dump())
if (!testMe.metaClass.respondsTo(testMe,"populateTransitionName")) {
log.debug("populateTransitionName is a NOT a valid method!")
}
The dump looks fine, the properties of the class are exposed and accessible ... but the test fails.
When trying to access the methods, I get a methodNotFound exception .. which I would expect since the metaClass test fails
What I really want to do is to not have to "import" a metric ton of packages so I want to accept the post function , interrogate the payload, and dynamically load the appropriate class to execute.
Maybe this is just not possible in the confines of Groovy executed by ScriptRunner?
I tried a bunch of different way to load the class including GroovyClassLoader among others.
Hopefully this is something simple? I have already wasted a couple of hour trying different ways of invoking loadClass() to try to make it work ...
Interesting idea.
I have played with class loader to be able to load custom class in the console. But I'd never tried to load existing classes.
Playing around with your code and what I had before I got this to respond apparently correctly in the console:
def load_class = "com.atlassian.jira.component.ComponentAccessor"
testMe = this.class.classLoader.loadClass( load_class, true )?.newInstance()
log.debug("testMe: " + testMe.dump())
testMethod = "getProjectManager"
if (!testMe.metaClass.respondsTo(testMe,testMethod)) {
log.debug("$testMethod is a NOT a valid method!")
}
testMe.projectManager.projectCount
Where as, that did not work for me when invoking a post function.
But, this is what did work in the end:
def getClass($path_to_file) {
// Take groovy off, just in case it was passed in
def cleaned_path = $path_to_file.replaceAll(".groovy","")
// Combine base path + cleaned path + .groovy
File sourceFile = new File("${base_url}/${cleaned_path}.groovy")
// Delcare the Object
Class groovyClass = new GroovyClassLoader(getClass().getClassLoader()).parseClass(sourceFile)
// Return the object
(GroovyObject) groovyClass.newInstance()
}
This is a method of a classLoader that I created to handle the code. I should have used regex to strip the .groovy, but I was in a hurry.
The main difference here is the "parseClass" method ... and the use of "GroovyClassLoader".
This now works as expected ... I have not tested from the console as this is part of an automation system so console working / not working is a non-issue.
The end goal? to not have a bunch of "post functions" spread out all over the workflow transitions. (multiple transitions with multiple post functions). In the end, there will be one post function call per transition and that call will act as a "router" to call the proper controllers / handlers / repo's.
This will allow us to manage all processes through "code deploy" instead of manually changing workflows.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.