Jira plugin fails after adding apache kafka dependancy - jira-plugin

I am trying to create a JIRA plugin so that whenever an Issue is created, its posted to Kafka cluster. A sample listener code works fine. However when I add Maven dependency for Kafka, the plugin fails to load with below error.
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
Below is my 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>
And below is my Java class.
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.getKey(), issue.getResolutionDate());
} else if (eventTypeId.equals(EventType.ISSUE_CLOSED_ID)) {
log.info("Issue {} has been closed at {}.", issue.getKey(), 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);
}
}
I tried debuugin via OSGI browser (refer to the attached image).
For some of the imported packeges, "provided by" is missing. I wonder if that is causing failure of the plugin but unable to understand how to resolve it.

Finally, I was able crack down the problem. Here's what I did.
Removed kafka-streams dependency which wasn't really required.
Kept <scope>provided</scope> for all the dependencies
Since JARs need to be available at runtime. I added them to plugin>execution> configuration>includeArtifactIds so that JARs are exported to the runtime environment
This is important. I Experimented with different versions of Kafka. Since the JIRA version I was using, was 8.5.4 (released couple of years back), I found versions of other JARs released during/just before the same time period & used those.
I faced runtime issues for some missing classes. I added those artifact Ids in plugin>execution>configuration>includeArtifactIds
Now my final POM looks like below.
<?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>
The Kafka Template related settings were done in another class file as below.
#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());
}
}
I somehow wasn't able to get KafkaTemplate configured & autowired via Spring even after adding #Configuration annotation. Hence instantiated it manually using code below (which isnt a good way though!)
private KafkaTemplate<Long, String> template= new KafkaConfig().kafkaTemplate();
and used below code to send topic to 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,issue.getDescription(),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, String value, 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);
}
}

Related

spring boot test junit null pointer exception

im new on this of unit tests, so im trying to code the unit test for my service, right now i have this class
package com.praxis.topics.service;
import com.praxis.topics.exception.EntityNotFoundException;
import com.praxis.topics.model.Topic;
import com.praxis.topics.model.enums.Status;
import com.praxis.topics.repository.TopicRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
#Service("topics")
public class TopicServiceImpl implements TopicService {
private final TopicRepository topicRepository;
#Autowired
public TopicServiceImpl(TopicRepository topicRepository) {
this.topicRepository = topicRepository;
}
#Override
public List<Topic> getTopicsByStatus(int status) {
// Check if status exists in enum
if (status < 0 || Status.values().length - 1 < status)
throw new ArrayIndexOutOfBoundsException(status);
return topicRepository.findTopicByStatus(Status.values()[status]);
}
#Override
public Topic addTopic(Topic topic) {
//topic.setCreatedAt(LocalDateTime.now());
return topicRepository.save(topic);
}
#Override
public Topic updateTopic(Topic topic) throws EntityNotFoundException {
if (topicRepository.findTopicById(topic.getId()) == null)
throw new EntityNotFoundException(String.format("Topic with id: %s was not found", topic.getId()));
return topicRepository.save(topic);
}
#Override
public Topic getTopicById(String id) {
return topicRepository.findTopicById(id);
}
#Override
public void deleteTopicById(String id) {
topicRepository.deleteTopicById(id);
}
#Override
public List<Topic> getTopicsByName(String name) {
return topicRepository.findAllByNameContains(name);
}
#Override
public Topic getTopicByName(String name) {
return topicRepository.findTopicByName(name);
}
#Override
public List<Topic>getAllTopics(){
return topicRepository.findAll();
}
}
the model of topics is this
package com.praxis.topics.model;
import com.praxis.topics.model.enums.Status;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
#Document(collection = "Topic")
public class Topic {
#Id
private String id;
#NotEmpty(message = "The name is required")
private String name;
#NotEmpty(message = "The description is required")
private String description;
private Status status;
private String chat;
private int teachers;
private int students;
#DateTimeFormat(pattern = "dd-MM-yyyy hh:mm:ss")
private LocalDateTime createdAt;
#DateTimeFormat(pattern = "dd-MM-yyyy hh:mm:ss")
private LocalDateTime openedAt;
#DateTimeFormat(pattern = "dd-MM-yyyy hh:mm:ss")
private LocalDateTime closedAt;
public Topic() {}
public Topic(String name, String description) {
this.name = name;
this.description = description;
this.createdAt = LocalDateTime.now();
}
and im trying to do this test for but it throws me a null pointer exception, like if the service variable wasnt initialized or something
package com.praxis.topics.service;
import com.praxis.topics.model.Topic;
import com.praxis.topics.repository.TopicRepository;
import org.springframework.beans.factory.annotation.Autowired;
import static org.junit.jupiter.api.Assertions.*;
class TopicServiceImplTest {
#Autowired
TopicServiceImpl service;
#org.junit.jupiter.api.Test
void addTopic() {
Topic topic = new Topic("java", "test");
assertEquals(topic, service.addTopic(topic));
}
}
and this are the exceptions i get
java.lang.NullPointerException at com.praxis.topics.service.TopicServiceImplTest.addTopic(TopicServiceImplTest.java:29)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:436)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:170)
at org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:166)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:113)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:58)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:112)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:120)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:430)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:120)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:120)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:430)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:120)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:55)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:43)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:65)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
any idea? i think that its because some of the variable dont get initialized, but im doing adding the #Autowired on those so i dont know what it is
this is my pom file
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
<groupId>com.praxis</groupId>
<artifactId>topics</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>topics</name>
<description>Project for Integrador 2018</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
For starters, if you're using JUnit Jupiter (the programming model in JUnit 5), you'll have to configure the Jupiter Test Engine in your build.
I recommend you use the official spring-boot-sample-junit-jupiter sample project as a template.
The pom.xml shows how to configure the Jupiter Test Engine with the Maven Surefire Plugin:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>${junit-platform.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
Note that it also shows that you need dependency declarations for
junit-jupiter-api and junit-jupiter-engine.
And SampleJunitJupiterApplicationTests shows how to configure Spring Boot's testing support with the SpringExtension for JUnit Jupiter:
#ExtendWith(SpringExtension.class)
#SpringBootTest
class TopicServiceImplTest {
#Autowired
TopicService service;
// ..
}
We had recently started using Spring 4.3, JUnit5, Maven together as well and got NullPointerException in integration tests where #Autowired was used.
Solution for us was to upgrade maven-related test dependencies:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M4</version> // upgraded from 2.19.1
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version> // upgraded from 2.19
</plugin>
Your TopicServiceImplTest class is not spring component so #Autowired won't work.
Spring Boot test should be annotated with #SpringBootTest and #RunWith(SpringRunner.class). Optionaly you could use other annotations to define your context to suit your specific needs. You can find basic information here: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html

java.lang.ClassCastException: org.glassfish.jersey.jackson.internal.JacksonAutoDiscoverable cannot be cast to spi.AutoDiscoverable

I am new to implementing REST API services. I have tried the simple resources to implement. unfortunately I stuck with this exception. I have googled and tried many options but no luck. I am unsure what am doing wrong. Please help me.
Created a Dynamic Web project "JersyJson"
Created a resouce named - JSONService.java (source is from googling)
Created a Java Bean class - Track.java (source is from googling)
Converted the project into Maven project
Created a Application file - JersyJson.java file for Application Annotation
using the latest Jersy Jars (version: 2.22.2)
Imported & configured jersey-media-json-jackson and jersey-media-moxy jars (2.22.2) in pom.xml
Pom.xml
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>JersyJson</groupId>
<artifactId>JersyJson</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<!-- if your container implements Servlet API older than 3.0, use "jersey-container-servlet-core" -->
<artifactId>jersey-container-servlet</artifactId>
<version>2.22.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.22.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.22.2</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>JersyJson</display-name>
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/json/metallica/*</url-pattern>
</servlet-mapping>
</web-app>
JersyJson.java (ApplicationAnnotation file)
#ApplicationPath("json")
public class JersyJson extends ResourceConfig {
public JersyJson() {
packages("com.sai.jersyjson");
}
}
JSONservice.java:
package com.sai.jersyjson;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
#Path("/json/metallica")
public class JSONService {
#GET
#Path("/get")
#Produces(MediaType.APPLICATION_JSON)
public Track getTrackInJSON() {
Track track = new Track();
track.setTitle("Enter Sandman");
track.setSinger("Metallica");
return track;
}
#POST
#Path("/post")
#Consumes(MediaType.APPLICATION_JSON)
public Response createTrackInJSON(Track track) {
String result = "Track saved : " + track;
return Response.status(201).entity(result).build();
}
}
Track.java (simple bean class)
package com.sai.jersyjson;
public class Track {
String title;
String singer;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSinger() {
return singer;
}
public void setSinger(String singer) {
this.singer = singer;
}
#Override
public String toString() {
return "Track [title=" + title + ", singer=" + singer + "]";
}
}
After I run this project in Eclispe using Tomcat webserver, I get the following
error with 404-Error Status
SEVERE: StandardWrapper.Throwable
java.lang.ClassCastException: org.glassfish.jersey.jackson.internal.JacksonAutoDiscoverable cannot be cast to org.glassfish.jersey.internal.spi.AutoDiscoverable
at org.glassfish.jersey.model.internal.CommonConfig$2.compare(CommonConfig.java:594)
at java.util.TreeMap.put(Unknown Source)
at java.util.TreeSet.add(Unknown Source)
at java.util.AbstractCollection.addAll(Unknown Source)
at java.util.TreeSet.addAll(Unknown Source)
at org.glassfish.jersey.model.internal.CommonConfig.configureAutoDiscoverableProviders(CommonConfig.java:616)
at org.glassfish.jersey.server.ResourceConfig.configureAutoDiscoverableProviders(ResourceConfig.java:811)
at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:447)
at org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.java:184)
at org.glassfish.jersey.server.ApplicationHandler$3.call(ApplicationHandler.java:350)
at org.glassfish.jersey.server.ApplicationHandler$3.call(ApplicationHandler.java:347)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:255)
at org.glassfish.jersey.server.ApplicationHandler.(ApplicationHandler.java:347)
at org.glassfish.jersey.servlet.WebComponent.(WebComponent.java:392)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:177)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:369)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1238)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1041)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4996)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5285)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
I had the exact same problem in Weblogic. It seems to be that the JacksonAutoDiscoverable and AutoDiscoverable came from different class loaders and therefore different versions. AutoDiscoverable exists in jersey-common and JacksonAutoDiscoverable exists in jersey-media-json-jackson.
I got around this by letting Weblogic have all the discoverable classes and instead specifying 'com.fasterxml.jackson.*' as prefer-application-packages/resources to have my own version of jackson.
I had this same problem, but I got a fix. There's an issue with conflicting dependencies. You've included the jersey-media-json-jackson dependency, but the Tomcat web container already provides those classes.
Just add the scope tag to your dependency:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.27</version>
<scope>provided</scope>
</dependency>
Refer to the link for more information: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#
In my case I worked with Glassfish and I had the Glassfish descriptor (glassfish-web.xml) in the project as follow:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
<class-loader delegate="false"/>
<parameter-encoding default-charset="UTF-8"/>
<jsp-config>
<property name="keepgenerated" value="true">
<description>Keep a copy of the generated servlet class' java code.</description>
</property>
</jsp-config>
</glassfish-web-app>
The class-loader property was marked with the attribute
delegate=false
, I think that was my mistake, because as Glassfish Deployment Guide say, this attribute must be true when you are exposing services.
https://javaee.github.io/glassfish/doc/4.0/application-deployment-guide.pdf#G11.1006531
The solution that worked for me was remove that file and keep only the Standard Deployment Descriptor(web.xml).
Hope this help.
I had this same problem with JBOSS6 server. After adding jersey-media-moxy dependency to pom file, it was worked.
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.25.1</version>
</dependency>
I solved the issue by adding both jersey-common and jersey-media-json-jackson. Removed jersey-bean-validation.
<dependency>
<artifactId>jersey-common</artifactId>
<groupId>org.glassfish.jersey.core</groupId>
<version>2.29.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.29.1</version>
</dependency>
<!--<dependency>
<artifactId>jersey-bean-validation</artifactId>
<groupId>org.glassfish.jersey.ext</groupId>
<version>2.29.1</version>
</dependency>-->

Jersey MessageBodyWriter not found for media type=text/html

I am going to display html using "Thymeleaf", but the following errors are given.
The server using is tomcat8.
My code looks like.
pom.xml
<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.abc.def</groupId>
<artifactId>jersey_de</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>jersey_de</name>
<build>
<finalName>jersey_de</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<inherited>true</inherited>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- my setting -->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.21</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.21</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.connectors</groupId>
<artifactId>jersey-apache-connector</artifactId>
<version>2.21</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.21</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-mvc</artifactId>
<version>2.21</version>
</dependency>
<!--
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-mvc-jsp</artifactId>
<version>2.21</version>
</dependency>
-->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
Jersey Web Application
org.glassfish.jersey.servlet.ServletContainer
jersey.config.server.provider.packages
com.abc.def.jersey_de
com.abc.def.jersey_de.ThymeleafViewProcessor
/WEB-INF/view/
1
Jersey Web Application
/webapi/*
javacode
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.glassfish.jersey.server.mvc.Viewable;
import com.abc.def.jersey_de.domain.TestPOJO;
#Path("top")
#Produces(MediaType.TEXT_PLAIN)
public class DemoCtrl {
#GET
#Produces(MediaType.TEXT_HTML)
public Viewable getIt() {
Viewable vb = new Viewable("test",new TestPOJO());
System.out.println("top end");
return vb;
}
}
ThymeleafViewProcessor
#Provider
public class ThymeleafViewProcessor implements TemplateProcessor<String> {
#Context
private HttpServletRequest request;
#Context
private HttpServletResponse response;
#Context
private ServletContext servletContext;
private final TemplateEngine templateEngine;
/**
* コンストラクタ
*/
public ThymeleafViewProcessor() {
TemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/view/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
resolver.setCacheTTLMs(3600000L);
templateEngine = new TemplateEngine();
templateEngine.setTemplateResolver(resolver);
System.out.println("ThymeleafViewProcessor end");
}
/**
* 参照させるファイル名を解決する。
*/
#Override
public String resolve(String name, MediaType mediaType) {
return name;
}
#Override
public void writeTo(String templateReference, Viewable viewable, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream out) throws IOException {
WebContext context = new WebContext(request, response, servletContext);
//HTML内でモデルオブジェクトを使用できるようにしている。
//ここはモデル名をそのまま使用できるようにした方が良い。
context.setVariable("item", viewable.getModel());
Writer writer = new OutputStreamWriter(out);
templateEngine.process(templateReference, context, writer);
writer.flush();
}
}
ApplicationSetting
#ApplicationPath("/service")
public class ApplicationSetting extends ResourceConfig {
public ApplicationSetting() {
packages(this.getClass().getPackage().getName());
register(ThymeleafViewProcessor.class);
register(MvcFeature.class);
register(LoggingFilter.class);
System.out.println("ApplicationSetting ");
}
}
It was settled.
The points that I revised are as follows.
web.xml
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.abc.def.jersey_de.MyApplication</param-value>
</init-param>
pom
<dependencies>
<dependency>
<groupId>javax</groupId><!-- 動きが変わらないので不要? -->
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>8.0.15</version>
</dependency>
<dependency><!-- 不要? -->
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-mvc</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
</dependencies>
<properties>
<jersey.version>2.21</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

how to test an REST app (built with apache-cxf) with jersey-test-framework

I would like to know how I can test an REST application, which is developed using Apache CXF and Spring, with the Jersey Test Framework (JTF).
The application is made of several Maven modules, of which "app-rest" is the one that integrates them and exposes the REST interface to be tested.
I've made a separate Maven module that contains the tests, which has the "app-rest" as dependency, but I'm receiving an exception like this :
BeanDefinitionStoreException: IOException parsing XML document from class path resource
when running the tests.
I think that's because the app-rest is not properly deployed in the embedded container.
I've tried to put the tests into the "app-rest" module, but I get this instead :
RuntimeException: The scope of the component class org.apache.cxf.jaxrs.provider.AtomFeedProvider must be a singleton
I'm running the test with this command line:
mvn test -Dtest=JerseyRestTest -Djersey.test.containerFactory=com.sun.jersey.test.framework.spi.container.grizzly.web.GrizzlyWebTestContainerFactory
These is my pom.xml file for the tests module:
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>project-group-id</groupId>
<artifactId>projectname</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<groupId>project-group-id</groupId>
<artifactId>integration-tests</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Integration Tests of REST interface</name>
<!-- build -->
<build>
<finalName>${project.artifactId}</finalName>
</build>
<!-- additional repositories -->
<repositories>
<repository>
<id>java.net.m2</id>
<url>http://download.java.net/maven/2/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>project-group-id</groupId>
<artifactId>app-rest</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>war</type>
<scope>test</scope>
</dependency>
<!-- JUnit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
<!-- Jersey stuff -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey.jersey-test-framework</groupId>
<artifactId>jersey-test-framework-grizzly</artifactId>
<version>1.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-spring</artifactId>
<version>1.6</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
The simple test is:
public class JerseyRestTest extends JerseyTest {
public JerseyRestTest() {
super(new WebAppDescriptor.Builder("projectname.resource")
.servletClass(SpringServlet.class)
.contextParam("contextConfigLocation", "classpath:META-INF/spring/context-rest.xml")
.contextListenerClass(org.springframework.web.context.ContextLoaderListener.class)
.contextPath("app-rest")
.build());
}
#Test
public void testSomeResource() {
String response = resource().path("/rest/resources").get(String.class);
Assert.assertNotNull("No text returned!", response);
assertResponseContains(response, "<html>");
assertResponseContains(response, "</html>");
}
protected void assertResponseContains(String response, String text) {
Assert.assertTrue("Response should contain " + text + " but was: " + response, response.contains(text));
}
}
Thank you very much!

maven jdepend fail build with cycles

Is there way to use the jdepend plugin in maven to fail a build when package cycles exist? I know you can do it fairly easily with ant, but I haven't figured out how to do it with maven.
thanks,
Jeff
Based on the accepted answer, I improved the performance and log output and released it on Maven Central:
https://github.com/andrena/no-package-cycles-enforcer-rule
(I'd comment on the accepted answer, but don't have enough rep yet.)
You could write your own rule for the maven-enforcer plugin as described in
http://maven.apache.org/enforcer/enforcer-api/writing-a-custom-rule.html
That's how I did it.
NoPackageCyclesRule.java
package org.apache.maven.enforcer.rule;
import java.io.File;
import java.io.IOException;
import jdepend.framework.JDepend;
import org.apache.maven.enforcer.rule.api.EnforcerRule;
import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
public class NoPackageCyclesRule implements EnforcerRule
{
public void execute(EnforcerRuleHelper helper) throws EnforcerRuleException
{
Log log = helper.getLog();
try
{
MavenProject project = (MavenProject) helper.evaluate("${project}");
File targetDir = new File((String) helper.evaluate("${project.build.directory}"));
File classesDir = new File(targetDir, "classes");
if (project.getPackaging().equalsIgnoreCase("jar") && classesDir.exists())
{
JDepend jdepend = new JDepend();
jdepend.addDirectory(classesDir.getAbsolutePath());
jdepend.analyze();
if (jdepend.containsCycles())
{
throw new EnforcerRuleException("There are package cycles");
}
}
else
{
log.warn("Skipping jdepend analysis as " + classesDir + " does not exist.");
}
}
catch (ExpressionEvaluationException e)
{
throw new EnforcerRuleException("Unable to lookup an expression "
+ e.getLocalizedMessage(), e);
}
catch (IOException e)
{
throw new EnforcerRuleException("Unable to access target directory "
+ e.getLocalizedMessage(), e);
}
}
public String getCacheId()
{
return "";
}
public boolean isCacheable()
{
return false;
}
public boolean isResultValid(EnforcerRule arg0)
{
return false;
}
}
pom.xml for enforcer rule:
<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>custom-rule</groupId>
<artifactId>no-package-cycles-rule</artifactId>
<version>1.0</version>
<properties>
<api.version>1.0</api.version>
<maven.version>2.2.1</maven.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven.enforcer</groupId>
<artifactId>enforcer-api</artifactId>
<version>${api.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>${maven.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>${maven.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
<version>${maven.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>${maven.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-container-default</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>jdepend</groupId>
<artifactId>jdepend</artifactId>
<version>2.9.1</version>
</dependency>
</dependencies>
</project>
Then you can add it to your build:
<plugin>
<artifactId>maven-enforcer-plugin</artifactId>
<dependencies>
<dependency>
<groupId>custom-rule</groupId>
<artifactId>no-package-cycles-rule</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>enforce-no-package-cycles</id>
<goals>
<goal>enforce</goal>
</goals>
<phase>verify</phase> <!-- use a phase after compile! -->
<configuration>
<rules>
<NoPackageCyclesRule
implementation="org.apache.maven.enforcer.rule.NoPackageCyclesRule" />
</rules>
</configuration>
</execution>
</executions>
</plugin>
From what I can see, the JDepend Maven Plugin is supposed to be used to generate a report, it doesn't allow to fail the build on particular rules violations.