如何解决添加了Apache Kafka依赖关系后,Jira插件失败
我正在尝试创建JIRA插件,以便每当创建问题时,便将其发布到Kafka集群中。 sample listener code可以正常工作。但是,当我为Kafka添加Maven依赖项时,该插件无法加载,并出现以下错误。
org.springframework.beans.factory.BeanDeFinitionStoreException: Unexpected exception parsing XML document from URL [bundle://219.0:0/meta-inf/spring/plugin-context.xml]; nested exception is org.springframework.beans.FatalBeanException: Class [com.atlassian.plugin.spring.scanner.extension.AtlassianScannerNamespaceHandler] for namespace [http://www.atlassian.com/schema/atlassian-scanner] does not implement the [org.springframework.beans.factory.xml.NamespaceHandler] interface
at org.springframework.beans.factory.xml.XmlBeanDeFinitionReader.doLoadBeanDeFinitions(XmlBeanDeFinitionReader.java:414)
at org.springframework.beans.factory.xml.XmlBeanDeFinitionReader.loadBeanDeFinitions(XmlBeanDeFinitionReader.java:336)
at org.springframework.beans.factory.xml.XmlBeanDeFinitionReader.loadBeanDeFinitions(XmlBeanDeFinitionReader.java:304)
at org.springframework.beans.factory.support.AbstractBeanDeFinitionReader.loadBeanDeFinitions(AbstractBeanDeFinitionReader.java:187)
at org.springframework.beans.factory.support.AbstractBeanDeFinitionReader.loadBeanDeFinitions(AbstractBeanDeFinitionReader.java:223)
at org.springframework.beans.factory.support.AbstractBeanDeFinitionReader.loadBeanDeFinitions(AbstractBeanDeFinitionReader.java:194)
at org.eclipse.gemini.blueprint.context.support.OsgiBundleXmlApplicationContext.loadBeanDeFinitions(OsgiBundleXmlApplicationContext.java:171)
at org.eclipse.gemini.blueprint.context.support.OsgiBundleXmlApplicationContext.loadBeanDeFinitions(OsgiBundleXmlApplicationContext.java:141)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshbeanfactory(AbstractRefreshableApplicationContext.java:133)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshbeanfactory(AbstractApplicationContext.java:619)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.access$800(AbstractDelegatedExecutionApplicationContext.java:57)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext$3.run(AbstractDelegatedExecutionApplicationContext.java:239)
at org.eclipse.gemini.blueprint.util.internal.PrivilegedUtils.executeWithCustomTccl(PrivilegedUtils.java:85)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.startRefresh(AbstractDelegatedExecutionApplicationContext.java:217)
at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterapplicationContextExecutor.stageOne(DependencyWaiterapplicationContextExecutor.java:224)
at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterapplicationContextExecutor.refresh(DependencyWaiterapplicationContextExecutor.java:177)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.refresh(AbstractDelegatedExecutionApplicationContext.java:154)
at org.eclipse.gemini.blueprint.extender.internal.activator.LifecycleManager$1.run(LifecycleManager.java:213)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.beans.FatalBeanException: Class [com.atlassian.plugin.spring.scanner.extension.AtlassianScannerNamespaceHandler] for namespace [http://www.atlassian.com/schema/atlassian-scanner] does not implement the [org.springframework.beans.factory.xml.NamespaceHandler] interface
at org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.resolve(DefaultNamespaceHandlerResolver.java:132)
at org.eclipse.gemini.blueprint.context.support.DelegatednamespaceHandlerResolver.resolve(DelegatednamespaceHandlerResolver.java:55)
at org.springframework.beans.factory.xml.BeanDeFinitionParserDelegate.parseCustomElement(BeanDeFinitionParserDelegate.java:1361)
at org.springframework.beans.factory.xml.BeanDeFinitionParserDelegate.parseCustomElement(BeanDeFinitionParserDelegate.java:1352)
at org.springframework.beans.factory.xml.DefaultBeanDeFinitionDocumentReader.parseBeanDeFinitions(DefaultBeanDeFinitionDocumentReader.java:178)
at org.springframework.beans.factory.xml.DefaultBeanDeFinitionDocumentReader.registerBeanDeFinitions(DefaultBeanDeFinitionDocumentReader.java:98)
at org.springframework.beans.factory.xml.XmlBeanDeFinitionReader.registerBeanDeFinitions(XmlBeanDeFinitionReader.java:508)
at org.springframework.beans.factory.xml.XmlBeanDeFinitionReader.doLoadBeanDeFinitions(XmlBeanDeFinitionReader.java:392)
... 20 more
2020-09-04 18:06:54,517+0530 ThreadPoolAsyncTaskExecutor::Thread 26 ERROR yogeshpitale 1031x426x4 3reejl 127.0.0.1 /rest/plugins/1.0/installed-marketplace [o.e.g.b.e.internal.support.ExtenderConfiguration] Application context refresh Failed (NonValidatingOsgiBundleXmlApplicationContext(bundle=com.vz.jira.defects-plugin,config=osgibundle:/meta-inf/spring/*.xml))
org.springframework.beans.factory.BeanDeFinitionStoreException: Unexpected exception parsing XML document from URL [bundle://219.0:0/meta-inf/spring/plugin-context.xml]; nested exception is org.springframework.beans.FatalBeanException: Class [com.atlassian.plugin.spring.scanner.extension.AtlassianScannerNamespaceHandler] for namespace [http://www.atlassian.com/schema/atlassian-scanner] does not implement the [org.springframework.beans.factory.xml.NamespaceHandler] interface
at org.springframework.beans.factory.xml.XmlBeanDeFinitionReader.doLoadBeanDeFinitions(XmlBeanDeFinitionReader.java:414)
at org.springframework.beans.factory.xml.XmlBeanDeFinitionReader.loadBeanDeFinitions(XmlBeanDeFinitionReader.java:336)
at org.springframework.beans.factory.xml.XmlBeanDeFinitionReader.loadBeanDeFinitions(XmlBeanDeFinitionReader.java:304)
at org.springframework.beans.factory.support.AbstractBeanDeFinitionReader.loadBeanDeFinitions(AbstractBeanDeFinitionReader.java:187)
at org.springframework.beans.factory.support.AbstractBeanDeFinitionReader.loadBeanDeFinitions(AbstractBeanDeFinitionReader.java:223)
at org.springframework.beans.factory.support.AbstractBeanDeFinitionReader.loadBeanDeFinitions(AbstractBeanDeFinitionReader.java:194)
at org.eclipse.gemini.blueprint.context.support.OsgiBundleXmlApplicationContext.loadBeanDeFinitions(OsgiBundleXmlApplicationContext.java:171)
at org.eclipse.gemini.blueprint.context.support.OsgiBundleXmlApplicationContext.loadBeanDeFinitions(OsgiBundleXmlApplicationContext.java:141)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshbeanfactory(AbstractRefreshableApplicationContext.java:133)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshbeanfactory(AbstractApplicationContext.java:619)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.access$800(AbstractDelegatedExecutionApplicationContext.java:57)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext$3.run(AbstractDelegatedExecutionApplicationContext.java:239)
at org.eclipse.gemini.blueprint.util.internal.PrivilegedUtils.executeWithCustomTccl(PrivilegedUtils.java:85)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.startRefresh(AbstractDelegatedExecutionApplicationContext.java:217)
at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterapplicationContextExecutor.stageOne(DependencyWaiterapplicationContextExecutor.java:224)
at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterapplicationContextExecutor.refresh(DependencyWaiterapplicationContextExecutor.java:177)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.refresh(AbstractDelegatedExecutionApplicationContext.java:154)
at org.eclipse.gemini.blueprint.extender.internal.activator.LifecycleManager$1.run(LifecycleManager.java:213)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.beans.FatalBeanException: Class [com.atlassian.plugin.spring.scanner.extension.AtlassianScannerNamespaceHandler] for namespace [http://www.atlassian.com/schema/atlassian-scanner] does not implement the [org.springframework.beans.factory.xml.NamespaceHandler] interface
at org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.resolve(DefaultNamespaceHandlerResolver.java:132)
at org.eclipse.gemini.blueprint.context.support.DelegatednamespaceHandlerResolver.resolve(DelegatednamespaceHandlerResolver.java:55)
at org.springframework.beans.factory.xml.BeanDeFinitionParserDelegate.parseCustomElement(BeanDeFinitionParserDelegate.java:1361)
at org.springframework.beans.factory.xml.BeanDeFinitionParserDelegate.parseCustomElement(BeanDeFinitionParserDelegate.java:1352)
at org.springframework.beans.factory.xml.DefaultBeanDeFinitionDocumentReader.parseBeanDeFinitions(DefaultBeanDeFinitionDocumentReader.java:178)
at org.springframework.beans.factory.xml.DefaultBeanDeFinitionDocumentReader.registerBeanDeFinitions(DefaultBeanDeFinitionDocumentReader.java:98)
at org.springframework.beans.factory.xml.XmlBeanDeFinitionReader.registerBeanDeFinitions(XmlBeanDeFinitionReader.java:508)
at org.springframework.beans.factory.xml.XmlBeanDeFinitionReader.doLoadBeanDeFinitions(XmlBeanDeFinitionReader.java:392)
... 20 more
2020-09-04 18:06:54,517+0530 ThreadPoolAsyncTaskExecutor::Thread 26 ERROR yogeshpitale 1031x426x4 3reejl 127.0.0.1 /rest/plugins/1.0/installed-marketplace [o.e.g.b.e.i.dependencies.startup.DependencyWaiterapplicationContextExecutor] Unable to create application context for [com.vz.jira.defects-plugin],unsatisfied dependencies: none
org.springframework.beans.factory.BeanDeFinitionStoreException: Unexpected exception parsing XML document from URL [bundle://219.0:0/meta-inf/spring/plugin-context.xml]; nested exception is org.springframework.beans.FatalBeanException: Class [com.atlassian.plugin.spring.scanner.extension.AtlassianScannerNamespaceHandler] for namespace [http://www.atlassian.com/schema/atlassian-scanner] does not implement the [org.springframework.beans.factory.xml.NamespaceHandler] interface
at org.springframework.beans.factory.xml.XmlBeanDeFinitionReader.doLoadBeanDeFinitions(XmlBeanDeFinitionReader.java:414)
at org.springframework.beans.factory.xml.XmlBeanDeFinitionReader.loadBeanDeFinitions(XmlBeanDeFinitionReader.java:336)
at org.springframework.beans.factory.xml.XmlBeanDeFinitionReader.loadBeanDeFinitions(XmlBeanDeFinitionReader.java:304)
at org.springframework.beans.factory.support.AbstractBeanDeFinitionReader.loadBeanDeFinitions(AbstractBeanDeFinitionReader.java:187)
at org.springframework.beans.factory.support.AbstractBeanDeFinitionReader.loadBeanDeFinitions(AbstractBeanDeFinitionReader.java:223)
at org.springframework.beans.factory.support.AbstractBeanDeFinitionReader.loadBeanDeFinitions(AbstractBeanDeFinitionReader.java:194)
at org.eclipse.gemini.blueprint.context.support.OsgiBundleXmlApplicationContext.loadBeanDeFinitions(OsgiBundleXmlApplicationContext.java:171)
at org.eclipse.gemini.blueprint.context.support.OsgiBundleXmlApplicationContext.loadBeanDeFinitions(OsgiBundleXmlApplicationContext.java:141)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshbeanfactory(AbstractRefreshableApplicationContext.java:133)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshbeanfactory(AbstractApplicationContext.java:619)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.access$800(AbstractDelegatedExecutionApplicationContext.java:57)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext$3.run(AbstractDelegatedExecutionApplicationContext.java:239)
at org.eclipse.gemini.blueprint.util.internal.PrivilegedUtils.executeWithCustomTccl(PrivilegedUtils.java:85)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.startRefresh(AbstractDelegatedExecutionApplicationContext.java:217)
at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterapplicationContextExecutor.stageOne(DependencyWaiterapplicationContextExecutor.java:224)
at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterapplicationContextExecutor.refresh(DependencyWaiterapplicationContextExecutor.java:177)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.refresh(AbstractDelegatedExecutionApplicationContext.java:154)
at org.eclipse.gemini.blueprint.extender.internal.activator.LifecycleManager$1.run(LifecycleManager.java:213)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.beans.FatalBeanException: Class [com.atlassian.plugin.spring.scanner.extension.AtlassianScannerNamespaceHandler] for namespace [http://www.atlassian.com/schema/atlassian-scanner] does not implement the [org.springframework.beans.factory.xml.NamespaceHandler] interface
at org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.resolve(DefaultNamespaceHandlerResolver.java:132)
at org.eclipse.gemini.blueprint.context.support.DelegatednamespaceHandlerResolver.resolve(DelegatednamespaceHandlerResolver.java:55)
at org.springframework.beans.factory.xml.BeanDeFinitionParserDelegate.parseCustomElement(BeanDeFinitionParserDelegate.java:1361)
at org.springframework.beans.factory.xml.BeanDeFinitionParserDelegate.parseCustomElement(BeanDeFinitionParserDelegate.java:1352)
at org.springframework.beans.factory.xml.DefaultBeanDeFinitionDocumentReader.parseBeanDeFinitions(DefaultBeanDeFinitionDocumentReader.java:178)
at org.springframework.beans.factory.xml.DefaultBeanDeFinitionDocumentReader.registerBeanDeFinitions(DefaultBeanDeFinitionDocumentReader.java:98)
at org.springframework.beans.factory.xml.XmlBeanDeFinitionReader.registerBeanDeFinitions(XmlBeanDeFinitionReader.java:508)
at org.springframework.beans.factory.xml.XmlBeanDeFinitionReader.doLoadBeanDeFinitions(XmlBeanDeFinitionReader.java:392)
... 20 more
下面是我的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.vz.jira</groupId>
<artifactId>jira-defects-plugin</artifactId>
<version>1.0.0-SNAPSHOT</version>
<organization>
<name>Example Company</name>
<url>http://www.example.com/</url>
</organization>
<name>jira-defects-plugin</name>
<description>This is the com.vz.jira:jira-defects-plugin plugin for Atlassian JIRA.</description>
<packaging>atlassian-plugin</packaging>
<dependencies>
<dependency>
<groupId>com.atlassian.jira</groupId>
<artifactId>jira-api</artifactId>
<version>${jira.version}</version>
<scope>provided</scope>
</dependency>
<!-- Add dependency on jira-core if you want access to JIRA implementation
classes as well as the sanctioned API. -->
<!-- This is not normally recommended,but may be required eg when migrating
a plugin originally developed against JIRA 4.x -->
<!-- <dependency> <groupId>com.atlassian.jira</groupId> <artifactId>jira-core</artifactId>
<version>${jira.version}</version> <scope>provided</scope> </dependency> -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-annotation</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-runtime</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
<scope>provided</scope>
</dependency>
<!-- WIRED TEST RUNNER DEPENDENCIES -->
<dependency>
<groupId>com.atlassian.plugins</groupId>
<artifactId>atlassian-plugins-osgi-testrunner</artifactId>
<version>${plugin.testrunner.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.10.RELEASE</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka-streams -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-streams</artifactId>
<version>2.0.1</version>
<!-- <scope>provided</scope> -->
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.kafka/spring-kafka -->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<!-- <version>2.5.4.RELEASE</version> -->
<!-- <scope>provided</scope> -->
<version>2.0.1.RELEASE</version>
</dependency>
<!-- Uncomment to use TestKit in your project. Details at https://bitbucket.org/atlassian/jira-testkit -->
<!-- You can read more about TestKit at https://developer.atlassian.com/display/JIRADEV/Plugin+Tutorial+-+Smarter+integration+testing+with+TestKit -->
<!-- <dependency> <groupId>com.atlassian.jira.tests</groupId> <artifactId>jira-testkit-client</artifactId>
<version>${testkit.version}</version> <scope>test</scope> </dependency> -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>jira-maven-plugin</artifactId>
<version>${amps.version}</version>
<extensions>true</extensions>
<configuration>
<extractDependencies>true</extractDependencies>
<productVersion>${jira.version}</productVersion>
<productDataVersion>${jira.version}</productDataVersion>
<log4jProperties>src/aps/log4j.properties</log4jProperties>
<!-- Uncomment to install TestKit backdoor in JIRA. -->
<!-- <pluginArtifacts> <pluginArtifact> <groupId>com.atlassian.jira.tests</groupId>
<artifactId>jira-testkit-plugin</artifactId> <version>${testkit.version}</version>
</pluginArtifact> </pluginArtifacts> -->
<enableQuickReload>true</enableQuickReload>
<!-- See here for an explanation of default instructions: -->
<!-- https://developer.atlassian.com/docs/advanced-topics/configuration-of-instructions-in-atlassian-plugins -->
<instructions>
<Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>
<!-- Add package to export here -->
<Export-Package>
com.vz.jira.api,</Export-Package>
<!-- Add package import here -->
<Import-Package>
org.springframework.osgi.*;resolution:="optional",org.eclipse.gemini.blueprint.*;resolution:="optional",org.springframework.kafka.*;resolution:="optional",org.apache.kafka.*;resolution:="optional",org.apache.kafka.clients.*;resolution:="optional",org.apache.kafka.common.*;resolution:="optional",*;version="0";resolution:=optional
</Import-Package>
<!-- Ensure plugin is spring powered -->
<Spring-Context>*</Spring-Context>
</instructions>
</configuration>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependency</id>
<phase>process-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.outputDirectory}/meta-inf/lib</outputDirectory>
<includeArtifactIds>spring-jdbc,spring-tx</includeArtifactIds>
<stripVersion>false</stripVersion>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-maven-plugin</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<executions>
<execution>
<goals>
<goal>atlassian-spring-scanner</goal>
</goals>
<phase>process-classes</phase>
</execution>
</executions>
<configuration>
<scannedDependencies>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-external-jar</artifactId>
</dependency>
</scannedDependencies>
<verbose>false</verbose>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<jira.version>7.13.0</jira.version>
<amps.version>8.0.2</amps.version>
<plugin.testrunner.version>2.0.1</plugin.testrunner.version>
<atlassian.spring.scanner.version>1.2.13</atlassian.spring.scanner.version>
<!-- This property ensures consistency between the key in atlassian-plugin.xml
and the Osgi bundle's key. -->
<atlassian.plugin.key>${project.groupId}.${project.artifactId}</atlassian.plugin.key>
<!-- TestKit version 6.x for JIRA 6.x -->
<testkit.version>6.3.11</testkit.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>
下面是我的java类。
package com.vz.jira.listeners;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.disposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Component;
import com.atlassian.event.api.EventListener;
import com.atlassian.event.api.EventPublisher;
import com.atlassian.jira.event.issue.IssueEvent;
import com.atlassian.jira.event.type.EventType;
import com.atlassian.jira.issue.Issue;
import com.atlassian.plugin.spring.scanner.annotation.imports.Jiraimport;
@Component
public class IssueCreatedResolvedListener implements InitializingBean,disposableBean {
private static final Logger log = LoggerFactory.getLogger(IssueCreatedResolvedListener.class);
@Jiraimport
private final EventPublisher eventPublisher;
@Autowired
private KafkaTemplate<Long,String> template;
@Autowired
public IssueCreatedResolvedListener(@Jiraimport EventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
@EventListener
public void onIssueEvent(IssueEvent issueEvent) {
Long eventTypeId = issueEvent.getEventTypeId();
Issue issue = issueEvent.getIssue();
System.out.println("Got Issue with ID:"+issue.getId());
try{
System.out.println("Sending message to queue");
this.template.send("issue",issue.getId(),issue.toString());
System.out.println("Message sent to queue");
}catch(Exception e){
e.printstacktrace();
}
if (eventTypeId.equals(EventType.ISSUE_CREATED_ID)) {
log.info("Issue {} has been created at {}.",issue.getKey(),issue.getCreated());
} else if (eventTypeId.equals(EventType.ISSUE_RESOLVED_ID)) {
log.info("Issue {} has been resolved at {}.",issue.getResolutionDate());
} else if (eventTypeId.equals(EventType.ISSUE_CLOSED_ID)) {
log.info("Issue {} has been closed at {}.",issue.getUpdated());
}
}
@Override
public void destroy() throws Exception {
log.info("disabling plugin");
eventPublisher.unregister(this);
}
@Override
public void afterPropertiesSet() throws Exception {
log.info("Enabling plugin");
eventPublisher.register(this);
}
}
我尝试通过Osgi浏览器进行调试(请参阅所附图像)。 对于某些导入的软件包,缺少“提供者”。我不知道这是否会导致插件失败,但无法理解如何解决。
解决方法
最后,我能够解决这个问题。这就是我所做的。
- 删除了不需要的kafka-streams依赖项。
- 保留所有依赖项
<scope>provided</scope>
- 由于JAR必须在运行时可用。我将它们添加到plugin> execution> configuration> includeArtifactIds中,以便将JAR导出到运行时环境
- 这很重要。。我尝试了不同版本的Kafka。由于我使用的JIRA版本是8.5.4(几年前发布),因此我发现了在同一时期内/之前发布的其他JAR版本,并使用了这些版本。
- 我遇到了一些缺少类的运行时问题。我在plugin> execution> configuration> includeArtifactIds 中添加了这些工件ID
现在我的最终POM如下图所示。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.vz.jira</groupId>
<artifactId>jira-defects-plugin</artifactId>
<version>1.0.0-SNAPSHOT</version>
<organization>
<name>Example Company</name>
<url>http://www.example.com/</url>
</organization>
<name>jira-defects-plugin</name>
<description>This is the com.vz.jira:jira-defects-plugin plugin for Atlassian JIRA.</description>
<packaging>atlassian-plugin</packaging>
<dependencies>
<dependency>
<groupId>com.atlassian.jira</groupId>
<artifactId>jira-api</artifactId>
<version>${jira.version}</version>
<scope>provided</scope>
</dependency>
<!-- Add dependency on jira-core if you want access to JIRA implementation
classes as well as the sanctioned API. -->
<!-- This is not normally recommended,but may be required eg when migrating
a plugin originally developed against JIRA 4.x -->
<!-- <dependency> <groupId>com.atlassian.jira</groupId> <artifactId>jira-core</artifactId>
<version>${jira.version}</version> <scope>provided</scope> </dependency> -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-annotation</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-runtime</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
<scope>provided</scope>
</dependency>
<!-- WIRED TEST RUNNER DEPENDENCIES -->
<dependency>
<groupId>com.atlassian.plugins</groupId>
<artifactId>atlassian-plugins-osgi-testrunner</artifactId>
<version>${plugin.testrunner.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.7.RELEASE</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<version>2.2.8.RELEASE</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka-clients -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.2.1</version>
<scope>provided</scope>
</dependency>
<!-- Uncomment to use TestKit in your project. Details at https://bitbucket.org/atlassian/jira-testkit -->
<!-- You can read more about TestKit at https://developer.atlassian.com/display/JIRADEV/Plugin+Tutorial+-+Smarter+integration+testing+with+TestKit -->
<!-- <dependency> <groupId>com.atlassian.jira.tests</groupId> <artifactId>jira-testkit-client</artifactId>
<version>${testkit.version}</version> <scope>test</scope> </dependency> -->
<!-- <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId>
<version>2.10.0</version> <scope>provided</scope> </dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId>
<version>2.10.0</version> <scope>provided</scope> </dependency> <dependency>
<groupId>org.springframework</groupId> <artifactId>spring-core</artifactId>
<version>5.2.0.RELEASE</version> <scope>provided</scope> </dependency> -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>jira-maven-plugin</artifactId>
<version>${amps.version}</version>
<extensions>true</extensions>
<configuration>
<extractDependencies>true</extractDependencies>
<productVersion>${jira.version}</productVersion>
<productDataVersion>${jira.version}</productDataVersion>
<log4jProperties>src/aps/log4j.properties</log4jProperties>
<!-- Uncomment to install TestKit backdoor in JIRA. -->
<!-- <pluginArtifacts> <pluginArtifact> <groupId>com.atlassian.jira.tests</groupId>
<artifactId>jira-testkit-plugin</artifactId> <version>${testkit.version}</version>
</pluginArtifact> </pluginArtifacts> -->
<enableQuickReload>true</enableQuickReload>
<!-- See here for an explanation of default instructions: -->
<!-- https://developer.atlassian.com/docs/advanced-topics/configuration-of-instructions-in-atlassian-plugins -->
<instructions>
<Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>
<!-- Add package to export here -->
<Export-Package>
com.vz.jira.api,</Export-Package>
<!-- Add package import here -->
<Import-Package>
<!-- org.springframework.osgi.*;resolution:="optional",org.eclipse.gemini.blueprint.*;resolution:="optional",org.springframework.kafka.*;resolution:="optional",org.apache.kafka.*;resolution:="optional",org.apache.kafka.clients.*;resolution:="optional",org.apache.kafka.common.*;resolution:="optional",-->
*;version="0";resolution:=optional
</Import-Package>
<DynamicImport-Package>*</DynamicImport-Package>
<!-- Ensure plugin is spring powered -->
<Spring-Context>*</Spring-Context>
</instructions>
</configuration>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependency</id>
<phase>process-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.outputDirectory}/META-INF/lib</outputDirectory>
<includeArtifactIds>spring-kafka,kafka-clients,spring-context,spring-messaging</includeArtifactIds>
<stripVersion>false</stripVersion>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-maven-plugin</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<executions>
<execution>
<goals>
<goal>atlassian-spring-scanner</goal>
</goals>
<phase>process-classes</phase>
</execution>
</executions>
<configuration>
<scannedDependencies>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-external-jar</artifactId>
</dependency>
</scannedDependencies>
<verbose>false</verbose>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<jira.version>7.13.0</jira.version>
<amps.version>8.0.2</amps.version>
<plugin.testrunner.version>2.0.1</plugin.testrunner.version>
<atlassian.spring.scanner.version>1.2.13</atlassian.spring.scanner.version>
<!-- This property ensures consistency between the key in atlassian-plugin.xml
and the OSGi bundle's key. -->
<atlassian.plugin.key>${project.groupId}.${project.artifactId}</atlassian.plugin.key>
<!-- TestKit version 6.x for JIRA 6.x -->
<testkit.version>6.3.11</testkit.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
与Kafka模板相关的设置在另一个类文件中完成,如下所示。
@Scanned
public class KafkaConfig {
@Bean
public ProducerFactory<Long,String> producerFactory() {
return new DefaultKafkaProducerFactory<>(producerConfigs());
}
@Bean
public Map<String,Object> producerConfigs() {
System.out.println("Intiailizing the config");
Map<String,Object> props = new HashMap<>();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"localhost:9092,localhost:9093");
props.put(ProducerConfig.RETRIES_CONFIG,1);
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,LongSerializer.class);
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,StringSerializer.class);
props.put(ProducerConfig.BATCH_SIZE_CONFIG,16384);
props.put(ProducerConfig.LINGER_MS_CONFIG,1);
props.put(ProducerConfig.BUFFER_MEMORY_CONFIG,33554432);
/*props.put(ProducerConfig.ACKS_CONFIG,"all");
props.put(ProducerConfig.RETRIES_CONFIG,10);*/
return props;
}
@Bean
public KafkaTemplate<Long,String> kafkaTemplate() {
return new KafkaTemplate<Long,String>(producerFactory());
}
}
即使添加了@Configuration注释,我还是无法通过Spring配置和自动装配KafkaTemplate。因此,使用下面的代码手动实例化它(虽然这不是一个好方法!)
private KafkaTemplate<Long,String> template= new KafkaConfig().kafkaTemplate();
,并使用下面的代码将主题发送给Kafka。
package com.vz.jira.listeners;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.stereotype.Component;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;
import com.atlassian.event.api.EventListener;
import com.atlassian.event.api.EventPublisher;
import com.atlassian.jira.event.issue.IssueEvent;
import com.atlassian.jira.issue.Issue;
import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.JiraImport;
import com.vz.jira.config.KafkaConfig;
import com.vz.jira.domain.Defects;
import com.vz.jira.util.DefectUtil;
@Scanned
@Component
public class IssueCreatedResolvedListener implements InitializingBean,DisposableBean {
private static final Logger log = LoggerFactory.getLogger(IssueCreatedResolvedListener.class);
@JiraImport
private final EventPublisher eventPublisher;
private ObjectMapper mapper = new ObjectMapper();
private KafkaTemplate<Long,String> template= new KafkaConfig().kafkaTemplate();
@Autowired
public IssueCreatedResolvedListener(@JiraImport EventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
@EventListener
public void onIssueEvent(IssueEvent issueEvent) {
try{
Long eventTypeId = issueEvent.getEventTypeId();
Issue issue = issueEvent.getIssue();
if(issue!=null){
Defects defect = DefectUtil.getDesiredIssueDetails(issue); //extract necessary details to be sent to Kafka
ListenableFuture<SendResult<Long,String>> future=template.send("issue",issue.getId(),mapper.writeValueAsString(defect));
future.addCallback(new ListenableFutureCallback<SendResult<Long,String>>() {
@Override
public void onSuccess(SendResult<Long,String> result) {
handleSuccess(eventTypeId,issue.getDescription(),result);
}
@Override
public void onFailure(Throwable ex) {
try {
handleFailure(eventTypeId,ex);
} catch (Throwable e) {
e.printStackTrace();
}
}
});
}
}catch (Exception e){
e.printStackTrace();
}
}
protected void handleFailure(Long key,String value,Throwable ex) throws Throwable {
System.out.println("Error sending message & the exception is: {} "+ ex.getMessage());
throw ex;
}
protected void handleSuccess(Long key,SendResult<Long,String> result) {
System.out.println("Message Sent Successfully for key: "+key+" value "+value+" partiotion is: "+ result.getRecordMetadata().partition() );
}
@Override
public void destroy() throws Exception {
System.out.println("Disabling plugin");
eventPublisher.unregister(this);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Enabling plugin");
eventPublisher.register(this);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。