Behaviours plugin + groovy scripts = unable to resolve class com.atlassian.jira.issue.context.ProjectContext

Hi,

We recently were able to update our Behaviours plugin to version 0.4.7

We have:
- JIRA 4.3.4
- groovyrunner 1.7.9 (groovy 1.7.10)

Before updating Behaviours plugin our groovy scripts (for behaviours) were running just fine. Now we're having :

Nov 17, 2011 7:38:15 AM com.sun.jersey.server.impl.application.WebApplicationImpl onException

SEVERE: Internal server error

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:

/atlassian-jira-4.3.4-standalone/jira-home/behaviours/CustomToComponentsSetter.groovy: 8: unable to resolve class com.atlassian.jira.issue.context.ProjectContext

@ line 8, column 1.

import com.atlassian.jira.issue.context.ProjectContext

^

1 error

I checked with JIRA 4.3.4 API and this class is where it should be.

I would be very grateful if anyone has a hint how to fix that and why this occurs.

Cheers.

2 answers

0 vote

I'm assuming you are working in a test instance....

The problem is that because it's a plugins2 plugin it doesn't automatically have access to all the classes in the root classloader like the previous version did.

You could use the class through reflection but that's a pain: https://studio.plugins.atlassian.com/wiki/display/GRV/Script+Runner?focusedCommentId=60686458#comment-60686458

The other way is to modify the Import-Package section in the atlassian-plugin.xml file and rebuild, which is also a pain, but less so.

It is possible for me to use the root classloader for compiling the groovy scripts, however then you don't get access to the classes shipped in the plugin, which is required, even if you don't use them explicitly.

If anyone has a good solution to this I'm all ears...

Could you please provide me with a brief example how to obtain the instance of this class ? I was trying to use class loader but I'm still having

java.lang.ClassNotFoundException: com.atlassian.jira.issue.context.ProjectContext

I was trying to use both

MyScript.class.getClassLoader()
ClassLoader.getSystemClassLoader()

and neither of them can load me this class.

Did you try the method in the attached link?

Or you could try ComponentManager.getInstance().getClassLoader()

I did but it's still not working.

But maybe there is a simpler way to deal with this problem.

We have the script that was automatically setting Component Value based on item from select list of a customfield.

We needed:

import com.atlassian.jira.issue.context.ProjectContext

to do this (field is a customfield):

String fieldValue = field.getOptions("",new ProjectContext(b.pid))?.getOptionById(fieldId)

Maybe there is some other, simpler way to obtain options/selected option of customfield?

Or a way that is not reffering to ProjectContext class.

I know it's not strictly connected with the plugin itself but I really need to get that working before we upgrade to new plugin version.

I will be very grateful for any help.

0 vote

Why does the following not work...?

FormField f = getFieldById(getFieldChanged())

f.getValue()

> String fieldValue = field.getOptions("",new ProjectContext(b.pid))?.getOptionById(fieldId)

I don't understand what that's supposed to do - can you post the whole script.

The basic idea behing the script is that when new issue form is submitted the Component is set to the same value as chosen customfield value (CF is a cascading select).

When I'm trying like that:

FormField formComponent = getFieldById(fieldChanged)
String fieldStringId = formComponent.getFormValue()
if (fieldStringId) {
	FormField field = getFieldById(fieldStringId)
if (field) { Long fieldId = Long.parseLong(fieldStringId) String fieldValue = field.getValue() if (fieldValue) { Collection components = projectComponentManager.findAllForProject(b.pid) ProjectComponent component = components.find { ProjectComponent pc -> pc.getName() == fieldValue } getFieldById(COMPONENTS).setFormValue(component?.id) } } }

It is not working because field.getValue() doesn't provide me with String value that I need to find component and then to set it. There is no good method in CustomField class to get the chosen value without referencing to ProjectContext as values for CFs are project orienented and for this particular CF we have more than one context.

I really appreciate your help on that issue !

getValue returns you an Option object when called on select lists (can't remember when I introduced that, you may need to upgrade the plugin).

You seem to be looking up the options, I don;t see the need. Can you post your whole class/script.

The original script was:

public void set() {
        FormField formComponent = getFieldById(fieldChanged)
        String fieldStringId = formComponent.getFormValue()
        if (fieldStringId) {
	        CustomField field = fieldManager.getCustomFieldObject(formComponent.getFieldId())
		if (field) {
                Long fieldId = Long.parseLong(fieldStringId)
		String fieldValue = field.getOptions("",new ProjectContext(b.pid))?.getOptionById(fieldId)
                if (fieldValue) {
                    Collection components = projectComponentManager.findAllForProject(b.pid)
                    ProjectComponent component = components.find { ProjectComponent pc -> pc.getName() == fieldValue }
                    getFieldById(COMPONENTS).setFormValue(component?.id)
                    }
            }
        }
 }

As you can see it was tring to get the option, then search a component and set it appropriately.

Now I tried:

public void set() {
        FormField formComponent = getFieldById(fieldChanged)
        String fieldStringId = formComponent.getFormValue()
 	if (fieldStringId) {
	String fieldValue1 = formComponent.getValue()
		if (fieldValue1) {
                    Collection components = projectComponentManager.findAllForProject(b.pid)
                    ProjectComponent component = components.find { ProjectComponent pc -> pc.getName() == fieldValue1 }
                    getFieldById(COMPONENTS).setFormValue(component?.id)
                    log.info(">>> CustomToComponentsSetter set in project: ${b.pid}, field: ${fieldStringId}, fieldValue: ${fieldValue1}, value: ${component?.id}")
                }
         }
}

I tried to use Option (Option option = formComponent.getValue()) but I got cast exception because getValue() from FormField returns a String object. I also think that the problem might be that this is Cascading select.

I am definately missing something. Sorry for bringing this back after some time - I am working on fixing this script in my 'spare' time.

Can't remember what's returned for a cascading select. What do these two things look like if you print then:

formComponent.getFormValue()
formComponent.getValue()
A class cast ex sounds about right. getValue(), for select lists, returns the string value that you see in the UI. Whereas getFormValue returns the ID, which is generally not very useful.

I finally gave up and just edited atlassian-plugin.xml (to be honest it works without rebuilding ;) I couldn't set up the atlassian sdk env... our nexus is acting weird lately).

BTW for Cascading Selects both methods you mentiones gives me the id (which is somehow consistent with the way cascading selects are designed).

Thanks for all your help !

Magda//BTO

Suggest an answer

Log in or Sign up to answer
How to earn badges on the Atlassian Community

How to earn badges on the Atlassian Community

Badges are a great way to show off community activity, whether you’re a newbie or a Champion.

Learn more
Community showcase
Published May 30, 2018 in Marketplace Apps

Three tips for boosting your board's efficiency with Story Maps

Trello is one of the most effective tools for driving your sprints. It's customizable for every Agile team and product owners and Scrum masters (SM) love it. However, Agile teams often struggle with:...

860 views 2 9
Read article

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you