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

Wojciech Olearczyk November 16, 2011

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 votes
JamieA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
December 12, 2011

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.

Wojciech Olearczyk January 16, 2012

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 !

JamieA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 16, 2012

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.

Wojciech Olearczyk January 17, 2012

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.

JamieA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 17, 2012

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.

Wojciech Olearczyk January 18, 2012

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

0 votes
JamieA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 16, 2011

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

Wojciech Olearczyk November 17, 2011

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.

JamieA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 17, 2011

Did you try the method in the attached link?

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

Wojciech Olearczyk December 12, 2011

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.

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events