【问题标题】:Can't get Active Objects to work in Jira无法让活动对象在 Jira 中工作
【发布时间】:2017-12-11 08:35:42
【问题描述】:

我目前正在实习,其中涉及创建 Jira 插件以解决公司用户在使用 Jira 时遇到的一些问题。对于第一个扩展,我需要在查看问题页面上创建一个新部分,用户可以在其中输入和编辑输入。为了做到这一点,我创建了一个包含输入的网络面板。但无论我尝试什么(过去 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 is not an instance of declaring class", _ "状态码": 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);
            }
        })
    });
});

密码Dto

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;}
}

密码模型

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);
}

密码道

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);
    }
}

密码资源

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);
    }
}

密码服务

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;
        }
    }
}

密码上下文提供者

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;
    }
}

【问题讨论】:

  • 这个答案对您有帮助吗?

标签: java jira jira-rest-api jira-plugin


【解决方案1】:

快速浏览后我能发现的唯一问题是 PasswordDao 类。如果我用它的值替换变量查询,那么它将如下所示。

activeObjects.find(PasswordModel.class, Query.select().where("ISSUE_KEY = ?", issueKey));

而您的实体类PasswordModel.java 没有任何此类方法String xxxIssueKey()。使用 ActiveObjects 创建的表的列名参考Offical document

Best practice 文档可能是您使用活动对象时的良好开端。

如下所示更新方法(将 ISSUE_KEY 更改为 ISSUE)。

private Query buildIssueQuery(String issueKey){

    return Query.select().where(" ISSUE = ? ", issueKey);
}

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多