Hi all,
I’m trying to update a JIRA 6 plugin to JIRA 7 using atlassian-spring-scanner, but I’m getting an unsatisfied dependency when I try to add the condition using UserIsProjectAdminCondition:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.atlassian.jira.plugin.webfragment.conditions.UserIsProjectAdminCondition': Unsatisfied dependency expressed through constructor argument with index 0 of type [com.atlassian.jira.security.PermissionManager]: No qualifying bean of type [com.atlassian.jira.security.PermissionManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.atlassian.jira.security.PermissionManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143)
In the atlassian-plugin.xml I added:
<condition class="com.atlassian.jira.plugin.webfragment.conditions.UserIsProjectAdminCondition"/>
In the pom.xml I used this import snippet (and other variants), but didn’t find a solution yet:
<Import-Package>
javax.ws.rs*;version="[1,2)",
javax.servlet*;version="2.5",
javax.xml.bind*;version="[2.1,3)",
*;version="0";resolution:=optional
</Import-Package>
What I want is to see the action only if the user is the admin of the current project.
I haven’t ever gotten any of the webfragment package conditions to work in Jira 7 so I usually implement my own.
Not the answer that I was looking for, but thanks for it.
I will do as you suggest until I will find a better solution and let you know.
If you need a particular condition for two webfragments in two different plugins, do you rewrite it in both of them? Or there is a way to share it?
Hi @luca.andreatta,
Could you try to explicitly require the PermissionManager
via @ComponentImport
?
import com.atlassian.jira.security.PermissionManager;
// ...
@Component("myComponentImportClass")
// This class contains all of our '@ComponentImport's
public class MyComponentImportClass {
// Constructor:
@Autowired
public MyComponentImportClass(@ComponentImport PermissionManager permissionManager) {
// no need to actually do anything with it...
}
}
Just having the component imported in any constructor of any class you define should make the Spring scanner pick it up and import it.
Tried your solution, but I didn’t find a way to make it work.
I tried to create a class as you suggested like that:
@Component("myComponentImporter")
public class ComponentImporter {
@ComponentImport private PermissionManager permissionMgr;
@Autowired
public ComponentImporter(@ComponentImport PermissionManager permissionManager) {
// no need to actually do anything with it...
}
}
But the stacktrace is always the same:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.atlassian.jira.plugin.webfragment.conditions.UserIsProjectAdminCondition': Unsatisfied dependency expressed through constructor argument with index 0 of type [com.atlassian.jira.security.PermissionManager]: No qualifying bean of type [com.atlassian.jira.security.PermissionManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.atlassian.jira.security.PermissionManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143)
I also tried to put this import in the plugin class, as suggested in another thread here, but the output was the same.
@Component
public class ComponentImporter {
private PermissionManager permissionMgr;
@Autowired
public ComponentImporter (@ComponentImport PermissionManager permissionManager) {
this.permissionMgr = permissionManager;
}
}
Hey, can you try this and if you have other class files which are injecting something, please check them also.
1 Like
I tried to build a webfragment plugin from scratch, you can find it here:
Can you take a look at it and try if it runs on your machine?
I’m getting a ClassNotFoundException now:
Caused by: java.lang.ClassNotFoundException: com.atlassian.jira.plugin.webfragment.conditions.JiraGlobalPermissionCondition not found by it.eng.jira.webfragment-test [249]
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
Ok, I found that in the original plugin I was missing this important file:
src/main/resources/META-INF/spring/plugin-context.xml
.
The ComponentImporter class should be annotated with org.springframework.stereotype.Component
and contains the missing classes, so something like that should work:
@Component("myComponentImporter")
public class ComponentImporter {
private PermissionManager permissionMgr;
@Autowired
public ComponentImporter(@ComponentImport PermissionManager permissionManager) {
// no need to actually do anything with it...
}
}
And there you were 10 minutes faster than me
1 Like
By the way, I have many plugins to migrate and for every one I will have to add this importer class so I have removed the component name and the unecessary class variable and I have come to the end to something like this:
@Component
public class ComponentImporter {
@Autowired
public ComponentImporter(@ComponentImport GlobalPermissionManager globalPermissionManager,
@ComponentImport PermissionManager permissionMgr, @ComponentImport ProjectManager projectMgr,
@ComponentImport LabelManager labelMgr, @ComponentImport DoubleConverter doubleConverter) {
// no need to actually do anything with it...
}
}
I’m not happy at all, if someone has a better solution let me know, please.