log4j2 - JVM input arguments lookup (jvmrunargs) does not work - jvm

I have just started trying out log4j2 (I've been using log4j 1.2.X previously). Aside from the frustration of trying to figure out what is needed/valid for the configuration file (log4j2.xml), I have been unable to use the Java VM "lookup" capability supposedly supported by log4j2. As far as I can tell, I'm doing the right stuff - based on the information available from the log4j web site. Has anyone ever had any success with this?
Here are the basics of what I'm doing:
java class:
[which is using SLF4J to "bridge" to log4j]
package logger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Main {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
logger.info("In main()");
}
}
log4j2.xml:
[I'm trying to pass a log directory, configured elsewhere]
<?xml version="1.0" encoding="UTF-8" ?>
<configuration status="INFO" strict="true">
<Properties>
<Property name="filename">${jvmrunargs:log_dir}/log.txt</Property>
</Properties>
<!-- APPENDERS -->
<Appenders>
<Appender type="File" name="File" fileName="${filename}">
<Layout type="PatternLayout">
<Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
</Layout>
</Appender>
</Appenders>
<!-- LOGGERS -->
<Loggers>
<Root level="INFO">
<AppenderRef ref="File" />
</Root>
</Loggers>
</configuration>
This fails with multiple exceptions thrown by log4j:
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/jo24447/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.7/log4j-slf4j-impl-2.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/jo24447/.m2/repository/org/slf4j/slf4j-log4j12/1.7.21/slf4j-log4j12-1.7.21.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
2016-12-07 10:44:52,566 main ERROR FileManager (${jvmrunargs:log_dir}/log.txt) java.io.FileNotFoundException: ${jvmrunargs:log_dir}\log.txt (The filename, directory name, or volume label syntax is incorrect) java.io.FileNotFoundException: ${jvmrunargs:log_dir}\log.txt (The filename, directory name, or volume label syntax is incorrect)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
at org.apache.logging.log4j.core.appender.FileManager$FileManagerFactory.createManager(FileManager.java:258)
at org.apache.logging.log4j.core.appender.FileManager$FileManagerFactory.createManager(FileManager.java:238)
at org.apache.logging.log4j.core.appender.AbstractManager.getManager(AbstractManager.java:112)
at org.apache.logging.log4j.core.appender.OutputStreamManager.getManager(OutputStreamManager.java:114)
at org.apache.logging.log4j.core.appender.FileManager.getFileManager(FileManager.java:110)
at org.apache.logging.log4j.core.appender.FileAppender$Builder.build(FileAppender.java:89)
at org.apache.logging.log4j.core.appender.FileAppender$Builder.build(FileAppender.java:51)
at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:122)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:942)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:882)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:874)
at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:498)
at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:227)
at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:239)
at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:530)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:603)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:620)
at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:226)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:152)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:103)
at org.apache.logging.slf4j.Log4jLoggerFactory.getContext(Log4jLoggerFactory.java:43)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:42)
at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:29)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:358)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)
at logger.Main.<clinit>(Main.java:8)
2016-12-07 10:44:52,572 main ERROR Unable to inject fields into builder class for plugin type class org.apache.logging.log4j.core.appender.FileAppender, element File. java.lang.IllegalStateException: ManagerFactory [org.apache.logging.log4j.core.appender.FileManager$FileManagerFactory#1decca33] unable to create manager for [${jvmrunargs:log_dir}/log.txt] with data [org.apache.logging.log4j.core.appender.FileManager$FactoryData#24cee99e]
at org.apache.logging.log4j.core.appender.AbstractManager.getManager(AbstractManager.java:114)
at org.apache.logging.log4j.core.appender.OutputStreamManager.getManager(OutputStreamManager.java:114)
at org.apache.logging.log4j.core.appender.FileManager.getFileManager(FileManager.java:110)
at org.apache.logging.log4j.core.appender.FileAppender$Builder.build(FileAppender.java:89)
at org.apache.logging.log4j.core.appender.FileAppender$Builder.build(FileAppender.java:51)
at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:122)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:942)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:882)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:874)
at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:498)
at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:227)
at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:239)
at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:530)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:603)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:620)
at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:226)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:152)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:103)
at org.apache.logging.slf4j.Log4jLoggerFactory.getContext(Log4jLoggerFactory.java:43)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:42)
at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:29)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:358)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)
at logger.Main.<clinit>(Main.java:8)
2016-12-07 10:44:52,575 main ERROR Unable to invoke factory method in class class org.apache.logging.log4j.core.appender.FileAppender for element File. java.lang.IllegalStateException: No factory method found for class org.apache.logging.log4j.core.appender.FileAppender
at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.findFactoryMethod(PluginBuilder.java:224)
at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:130)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:942)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:882)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:874)
at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:498)
at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:227)
at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:239)
at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:530)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:603)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:620)
at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:226)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:152)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:103)
at org.apache.logging.slf4j.Log4jLoggerFactory.getContext(Log4jLoggerFactory.java:43)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:42)
at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:29)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:358)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)
at logger.Main.<clinit>(Main.java:8)
2016-12-07 10:44:52,576 main ERROR Null object returned for File in Appenders.
2016-12-07 10:44:52,581 main ERROR Unable to locate appender "File" for logger config "root"
Here is the simple 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>logger</groupId>
<artifactId>logger</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<compileSource>1.7</compileSource>
<maven-compiler-plugin.version>2.3.2</maven-compiler-plugin.version>
<maven-jar-plugin.version>2.5</maven-jar-plugin.version>
<maven-dependency-plugin.version>2.10</maven-dependency-plugin.version>
<log4j.version>2.7</log4j.version>
<slf4j.version>1.7.21</slf4j.version>
</properties>
<dependencies>
<!-- Apache Log4J 2 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- Log4J 2 to SLF4J bridge -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- SLF4J -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${compileSource}</source>
<target>${compileSource}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

Related

Jira plugin fails after adding apache kafka dependancy

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

custom baggage key not showing up in logs with Spring cloud sleuth

Not seeing custom baggage id in the spring boot micro-service logs.
Below are the steps followed.
1. Used spring-cloud-starter-sleuth 2.2.1.release with springboot 2.2.0. Snippet from pom-
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
Both properties in application.propertieswhere set as:
spring.sleuth.baggage-keys=baggage-TraceId
spring.sleuth.log.slf4j.whitelisted-mdc-keys=baggage-TraceId.
logback-spring.xml is set with this baggage-TraceId.
<?xml version="1.0" encoding="UTF-8"?>
<springProperty scope="context" name="springName" source="spring.application.name" defaultValue=""/>
<!-- You can override this to have a custom pattern -->
<property name="CONSOLE_LOG_PATTERN"
value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p [${springName},%X{traceId:-},%X{parentId:-},%X{spanId:-},%X{baggage-TraceId:-}]) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%t]){faint} %clr(%logger{20}:%line){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
<!-- Logging configuration -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</root>
in Filter, set the header value fetched from the service request.
public void doFilter(ServletRequest req, ServletResponse res, FilterChain
filterChain) throws IOException, ServletException {
log.info("In Filter-START");
ExtraFieldPropagation.set("baggage-TraceId","1234");
log.info("In Filter-END"+ExtraFieldPropagation.get("baggage-TraceId"));
}

Error running Spark Main Class - Exception in thread "Thread-0" java.lang.NoClassDefFoundError: org/eclipse/jetty/server/Handler

I am learning Mongodb for Java and I am trying to run the code below which shows jetty handler error. I tried searching for solutions in different threads of this forum but none of the solutions helps me. Please help. What am I missing?
package com.mongo.practice;
import spark.Request;
import spark.Response;
import spark.Route;
import spark.Spark;
public class SparkMain {
public static void main(String[] args){
Spark.get("/", new Route() {
public Object handle(final Request request, final Response response){
return "Hello worldfrom Spark";
}
});
}
}
I get this error when run
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread "Thread-0" java.lang.NoClassDefFoundError: org/eclipse/jetty/server/Handler
at spark.embeddedserver.EmbeddedServers.initialize(EmbeddedServers.java:40)
at spark.Service.lambda$init$2(Service.java:536)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.eclipse.jetty.server.Handler
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
... 3 more
This is my 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>com.mongo</groupId>
<artifactId>M101J</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.7.1</version>
</dependency>
<dependency>
<groupId>com.sparkjava</groupId>
<artifactId>spark-core</artifactId>
<version>2.7.2</version>
</dependency>
</dependencies>
</project>
I tried adding this
<!-- https://mvnrepository.com/artifact/org.eclipse.jetty/jetty-server -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.4.9.v20180320</version>
</dependency>
but it did not solve the issue
You have to add two dependencies. The following:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.22</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.eclipse.jetty/jetty-util -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>9.3.24.v20180605</version>
</dependency>
The version for sl4j can varry. But the version of jetty is not flexible. I have tried with the latest version. It does not work for any other version other than this.

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

Looking for Webstart Maven Plugin sample application [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 8 years ago.
Improve this question
I am looking for source code for a complete application that uses the Webstart Maven Plugin.
Any ideas?
I tried the webstart plugin in a prrof of concept involving an embedded tomcat server. The plugin is bound to the package phase and takes a longtime to execute, I would recommend to invoke it manually from the command line. It generates a zip file in the target directory containing the jnlp file and all dependencies. This file can then be extraced and put on a webserver. The url in the pom should point to this path on the server. When started, the app runs a tomcat server on localhost port 8080 with a simple servlet that just returns the requested path as a string.
Let me know if this works for you.
Here is the pom of the project, the plugin configuration was mostly copied from the documentation here
<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>net.jhorstmann</groupId>
<artifactId>EmbeddedTomcatWebstart</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>EmbeddedTomcatWebstart</name>
<url>http://localhost/jnlp/</url>
<organization>
<name>Organisation</name>
</organization>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<tomcat.version>7.0.6</tomcat.version>
</properties>
<repositories>
<repository>
<id>jboss</id>
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
</repository>
<repository>
<id>sonatype</id>
<url>http://oss.sonatype.org/content/repositories/releases/</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifest>
<mainClass>net.jhorstmann.embeddedtomcat7.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo.webstart</groupId>
<artifactId>webstart-maven-plugin</artifactId>
<executions>
<execution>
<!-- bind to phase, I prefer to call it manualls -->
<phase>package</phase>
<goals>
<goal>jnlp-inline</goal> <!-- use jnlp, jnlp-inline or jnlp-single as appropriate -->
</goals>
</execution>
</executions>
<configuration>
<!--outputDirectory></outputDirectory--> <!-- not required?? -->
<!-- Set to true to exclude all transitive dependencies. Default is false. -->
<excludeTransitive>false</excludeTransitive>
<!-- The path where the libraries are stored within the jnlp structure. not required. by default the libraries are within the working directory -->
<libPath>lib</libPath>
<outputJarVersions>true</outputJarVersions>
<!-- [optional] transitive dependencies filter - if omitted, all transitive dependencies are included -->
<dependencies>
<!-- Note that only groupId and artifactId must be specified here. because of a limitation of the Include/ExcludesArtifactFilter -->
<!--
<includes>
<include>commons-logging:commons-logging</include>
<include>commons-cli:commons-cli</include>
</includes>
-->
<!--
<excludes>
<exclude></exclude>
<excludes>
-->
</dependencies>
<!--
<resourcesDirectory>${project.basedir}/src/main/jnlp/resources</resourcesDirectory>
-->
<!-- default value -->
<!-- JNLP generation -->
<jnlp>
<!-- default values -->
<!--inputTemplateResourcePath>${project.basedir}</inputTemplateResourcePath-->
<!--inputTemplate>src/main/jnlp/template.vm</inputTemplate--> <!-- relative to inputTemplateResourcePath -->
<outputFile>app.jnlp</outputFile> <!-- defaults to launch.jnlp -->
<!-- used to automatically identify the jar containing the main class. -->
<!-- this is perhaps going to change -->
<mainClass>net.jhorstmann.embeddedtomcat7.App</mainClass>
</jnlp>
<!-- SIGNING -->
<!-- defining this will automatically sign the jar and its dependencies, if necessary -->
<sign>
<keystore>${basedir}/keystore</keystore>
<keypass>password</keypass> <!-- we need to override passwords easily from the command line. ${keypass} -->
<storepass>password</storepass> <!-- ${storepass} -->
<!--storetype>fillme</storetype-->
<alias>EmbeddedTomcatWebstart</alias>
<!--validity>fillme</validity-->
<!-- only required for generating the keystore -->
<dnameCn>EmbeddedTomcatWebstart</dnameCn>
<dnameOu>Organisation Unit</dnameOu>
<dnameO>Organisation</dnameO>
<dnameL>Location</dnameL>
<dnameSt>State</dnameSt>
<dnameC>Country</dnameC>
<verify>true</verify> <!-- verify that the signing operation succeeded -->
<!-- KEYSTORE MANAGEMENT -->
<keystoreConfig>
<delete>true</delete> <!-- delete the keystore -->
<gen>true</gen> <!-- optional shortcut to generate the store. -->
</keystoreConfig>
</sign>
<!-- BUILDING PROCESS -->
<pack200>true</pack200>
<gzip>true</gzip> <!-- default force when pack200 false, true when pack200 selected ?? -->
<!-- causes a version attribute to be output in each jar resource element, optional, default is false -->
<outputJarVersions>false</outputJarVersions>
<!--install>false</install--> <!-- not yet supported -->
<verbose>true</verbose>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-coyote</artifactId>
<version>${tomcat.version}</version>
</dependency>
</dependencies>
</project>
Here is a custom template for the jnlp file placed at src/main/jnlp/template.vm, I can't remember why I needed that exactly:
<?xml version="1.0" encoding="utf-8"?>
<jnlp
spec="$jnlpspec"
codebase="$project.Url"
href="$outputFile">
<information>
<title>$project.Name</title>
<vendor>$project.Organization.Name</vendor>
<homepage href="$project.Url"/>
<description>$project.Description</description>
#if($offlineAllowed)
<offline-allowed/>
#end
</information>
#if($allPermissions)
<security>
<all-permissions/>
</security>
#end
<resources>
<j2se version="$j2seVersion"/>
$dependencies
</resources>
<application-desc main-class="$mainClass"/>
</jnlp>
This is the main class at src/main/java/net/jhorstmann/embeddedtomcat7/App.java
package net.jhorstmann.embeddedtomcat7;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Wrapper;
import org.apache.catalina.startup.Tomcat;
public class App {
public static void main(String[] args) throws LifecycleException, ServletException, IOException {
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
File webappDir = new File(tmpDir, "embeddedtomcat7");
webappDir.mkdir();
final Tomcat tomcat = new Tomcat();
tomcat.setPort(8080);
tomcat.setBaseDir(tmpDir.getAbsolutePath());
tomcat.getConnector().setURIEncoding("UTF-8");
String contextPath = "/";
Context context = tomcat.addContext(contextPath, webappDir.getAbsolutePath());
Wrapper wrapper = tomcat.addServlet(contextPath, "Test", new TestServlet());
//Wrapper wrapper = tomcat.addServlet(contextPath, "Async", new AsyncServlet());
//wrapper.setAsyncSupported(true);
wrapper.addMapping("/*");
tomcat.start();
tomcat.getServer().await();
}
}
And finally a servlet at src/main/java/net/jhorstmann/embeddedtomcat7/TestServlet.java
package net.jhorstmann.embeddedtomcat7;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html; charset=utf-8");
PrintWriter writer = resp.getWriter();
writer.println("<h1>" + req.getPathInfo() + "</h1>");
writer.close();
}
}
A few notes on this plugin (it's documentation is horrible):
It won't use the template.vm file unless you specify it, like
<templateFilename>roll-gen-template.vm</templateFilename>
For creating a war:
If you want to use the JnlpDownloadServlet (the standard one java provides) to serve up the files instead of the above code (and have the plugin generate a working version.xml file for it to use, etc.), basically you need to create a new project of type war and target the jnlp-download-servlet goal (it doesn't seem to support creating a war with classes from the current pom project) then, instead of a single <jnlp> section, you'll have the <jnlpFiles> section instead, which can list multiple jar dependencies. You may need to modify your web.xml file as well.
http://www.mojohaus.org/webstart/webstart-maven-plugin/jnlp-mojos-overview.html has an example pom for
If you have additional comments feel free to edit this, it is a community wiki.