我目前正在进行实习,包括创建Jira插件以解决公司用户使用Jira时遇到的一些问题。对于第一个扩展,我需要在视图问题页面上创建一个新部分,用户可以在其中输入和编辑输入。为了做到这一点,我创建了一个包含输入的Web面板。但无论我尝试什么(过去3周我一直在尝试不同的事情),我无法让活跃的物体工作。
目前,当插件尝试加载jira时,它会显示错误:“呈现错误'tig.jira.extension.tigPasswordExtension:issue-page-input'。请联系您的JIRA管理员。”当我尝试在restbrowser中测试REST API调用时,它会显示错误:
“”message“:”AOP配置似乎无效:尝试调用方法[public abstract net.java.ao.RawEntity [] com.atlassian.activeobjects.external.ActiveObjects.find(java.lang.Class,net目标上的.java.ao.Query)] [com.atlassian.activeobjects.osgi.TenantAwareActiveObjects@12bfb51b];嵌套异常是java.lang.IllegalArgumentException:object不是声明类的实例“, _“status-code”:500,“_
这里有没有人可以复制我的问题并找出我搞砸了什么?
我目前的文件如下:
Atlassian的-plugin.xml的
<atlassian-plugin key="${atlassian.plugin.key}" name="${project.name}" plugins-version="2">
<plugin-info>
<description>${project.description}</description>
<version>${project.version}</version>
<vendor name="${project.organization.name}" url="${project.organization.url}"/>
<param name="plugin-icon">images/pluginIcon.png</param>
<param name="plugin-logo">images/pluginLogo.png</param>
</plugin-info>
<!-- add our i18n resource -->
<resource type="i18n" name="i18n" location="tigPasswordExtension"/>
<!-- add our web resources -->
<web-resource key="tigPasswordExtension-resources" name="tigPasswordExtension Web Resources">
<dependency>com.atlassian.auiplugin:ajs</dependency>
<resource type="download" name="tigPasswordExtension.css" location="/css/tigPasswordExtension.css"/>
<resource type="download" name="tigPasswordExtension.js" location="/js/tigPasswordExtension.js"/>
<resource type="download" name="images/" location="/images"/>
<context>tigPasswordExtension.resource</context>
</web-resource>
<web-panel name="IssuePageInput" i18n-name-key="issue-page-input.name" key="issue-page-input" location="atl.jira.view.issue.right.context" weight="1">
<description key="issue-page-input.description">Passwords en SSH</description>
<context-provider class="tig.jira.extension.tigPasswordExtension.PasswordContextProvider"/>
<component-import key="appProps" interface="com.atlassian.sal.api.ApplicationProperties"/>
<resource name="view" type="velocity" location="/vm/password-input.vm"/>
<label key="issue-page-input.title"/>
</web-panel>
<!-- Active Objects module -->
<ao key="password-ao">
<description>The configuration of the Active Objects service</description>
<entity>tig.jira.extension.tigPasswordExtension.ao.PasswordModel</entity>
</ao>
<rest name="Password Resource" i18n-name-key="password-resource.name" key="password-resource" path="/passwordresource" version="1.0">
<description key="password-resource.description">The Password Resource Plugin</description>
</rest>
</atlassian-plugin>
tigPasswordExtension.js
AJS.toInit(function($) {
AJS.$('#searchButton2').click(function (){
var test = "lol";
AJS.$.ajax({
url:"jira/rest/passwordresource/1.0/password",
type: "post",
dataType: 'json',
async: false,
data: ({issueKey : document.getElementById("issueKeyInput").value, content: document.getElementById("passwordInput").value}),
success: function(data)
{
test = data;
console.log(test);
}
})
});
});
PasswordDto
package tig.jira.extension.tigPasswordExtension.dto;
public class PasswordDto {
private String issueKey;
private String content;
public PasswordDto(){}
public String getIssueKey(){return this.issueKey;}
public void setIssueKey(String issueKey){this.issueKey = issueKey;}
public String getContent(){return this.content;}
public void setContent(String content){this.content = content;}
}
PasswordModel
package tig.jira.extension.tigPasswordExtension.ao;
import net.java.ao.Entity;
import net.java.ao.Preload;
@Preload
public interface PasswordModel extends Entity {
String getIssue();
void setIssue(String issue);
String getContent();
void setContent(String content);
}
PasswordDao
package tig.jira.extension.tigPasswordExtension.ao;
import com.atlassian.activeobjects.external.ActiveObjects;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.google.common.collect.ImmutableMap.Builder;
import net.java.ao.Query;
import javax.inject.Inject;
import javax.inject.Named;
import java.util.Map;
@Named
public class PasswordDao {
private final ActiveObjects activeObjects;
@Inject
public PasswordDao(@ComponentImport ActiveObjects activeObjects){this.activeObjects = activeObjects;}
public PasswordModel getByIssueKey(String issueKey){
Query query = this.buildIssueQuery(issueKey);
PasswordModel[] passwordModels = this.activeObjects.find(PasswordModel.class, query);
return passwordModels.length > 0 ? passwordModels[0] : null;
}
public void update(String issueKey, String content){
PasswordModel passwordModel = this.getByIssueKey(issueKey);
if (passwordModel == null){
Map<String, Object> params = (new Builder()).put("ISSUE_KEY", issueKey).put("CONTENT", content).build();
this.activeObjects.create(PasswordModel.class, params);
} else {
passwordModel.setContent(content);
passwordModel.save();
}
}
private Query buildIssueQuery(String issueKey){
return Query.select().where("ISSUE_KEY = ?", issueKey);
}
}
PasswordResource
package tig.jira.extension.tigPasswordExtension.rest;
import tig.jira.extension.tigPasswordExtension.service.PasswordService;
import javax.ws.rs.*;
@Path("/password")
public class PasswordResource{
private final PasswordService passwordService;
public PasswordResource(PasswordService passwordService){this.passwordService = passwordService;}
@POST
public void update(@QueryParam("issue") String issueKey, @QueryParam("content") String content) {
this.passwordService.update(issueKey, content);
}
}
PasswordService
package tig.jira.extension.tigPasswordExtension.service;
import tig.jira.extension.tigPasswordExtension.ao.PasswordDao;
import tig.jira.extension.tigPasswordExtension.ao.PasswordModel;
import tig.jira.extension.tigPasswordExtension.dto.PasswordDto;
import javax.inject.Inject;
import javax.inject.Named;
@Named
public class PasswordService {
private final PasswordDao passwordDao;
@Inject
public PasswordService(PasswordDao passwordDao){
this.passwordDao = passwordDao;
}
public void update(String issueKey, String content){
this.passwordDao.update(issueKey, content);
}
public PasswordDto getByIssueKey(String issueKey){
PasswordModel passwordModel = this.passwordDao.getByIssueKey(issueKey);
if (passwordModel == null){
return null;
} else {
PasswordDto dto = new PasswordDto();
dto.setIssueKey(issueKey);
dto.setContent(passwordModel.getContent());
return dto;
}
}
}
PasswordContextProvider
package tig.jira.extension.tigPasswordExtension;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.plugin.webfragment.contextproviders.AbstractJiraContextProvider;
import com.atlassian.jira.plugin.webfragment.model.JiraHelper;
import com.atlassian.jira.user.ApplicationUser;
import tig.jira.extension.tigPasswordExtension.dto.PasswordDto;
import tig.jira.extension.tigPasswordExtension.service.PasswordService;
import java.util.HashMap;
import java.util.Map;
public class PasswordContextProvider extends AbstractJiraContextProvider {
Map contextMap = new HashMap();
private String issueKey;
private final PasswordService passwordService;
public PasswordContextProvider(PasswordService passwordRepository){
this.passwordService = passwordRepository;
}
public Map getContextMap(ApplicationUser user, JiraHelper jiraHelper) {
Issue currentIssue = (Issue) jiraHelper.getContextParams().get("issue");
issueKey = currentIssue.getKey();
//passwordService.update(issueKey, "klote");
PasswordDto passwordDto = this.passwordService.getByIssueKey(issueKey);
if (passwordDto != null){
contextMap.put("AO", "1");
contextMap.put("content", "Staat nog niks in gek");
if (passwordDto.getContent() != null) {
contextMap.put("content", passwordDto.getContent());
}
}
contextMap.put("issueKey", issueKey);
return contextMap;
}
}
答案 0 :(得分:0)
快速查看后我能找到的唯一问题是课程PasswordDao
。如果我用它的值替换变量查询,那么它将如下所示。
activeObjects.find(PasswordModel.class,Query.select()。where(&#34; ISSUE_KEY =?&#34;,issueKey));
而您的实体类PasswordModel.java
没有任何此类方法String xxxIssueKey()
。请参阅Offical document以获取使用ActiveObjects创建的表的列名。
Best practice文档可以为您提供良好的开端。
更新下面给出的方法(将ISSUE_KEY更改为ISSUE)。
private Query buildIssueQuery(String issueKey){
return Query.select().where(" ISSUE = ? ", issueKey);
}
我希望这会对你有所帮助。