Using the Payara Micro Maven Plugin
Originally published on 03 Aug 2017
Last updated on 31 Mar 2020
Payara Micro provides build tool plugins for Maven and Gradle. The plugins allows to start/stop/reload Payara Micro instance and package uber jar bundle of application. To illustrate the use of Payara Micro Maven Plugin, I'll be revisiting my earlier blog on another feature of Payara Micro - the ability to use Payara Micro as a JMS consumer.
I'll gradually modify the example from that blog post to make full use of the plugin. Full reference documentation for the plugin is available in ourdocumentation GitBook.
-
Bundle the ActiveMQ RAR into an Uber JAR
The first improvement we can make is to use thepayara-micro:bundle
goal to create an Uber JAR containing the ActiveMQ resource adapter. This will let us specify the Maven GAV coordinates of the ActiveMQ RAR so we don't have to bother downloading the artefact ourselves.
<plugin>
<groupId>fish.payara.maven.plugins</groupId>
<artifactId>payara-micro-maven-plugin</artifactId>
<version>1.0.7</version>
<executions>
<execution>
<goals>
<goal>bundle</goal>
</goals>
</execution>
</executions>
<configuration>
<payaraVersion>5.201</payaraVersion>
<deployArtifacts>
<artifactItem>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-rar</artifactId>
<version>5.15.12</version>
<type>rar</type>
</artifactItem>
</deployArtifacts>
</configuration>
</plugin>
I've separated out the configuration properties I've set above.
<payaraVersion>
This property is simply the version of Payara Micro we want to target for this application. We need at least 172 for the JCA support for ActiveMQ.-
<deployArtifacts>
This property allows you to add a list of<artifactItem>
, which are just Maven GAV coordinates of applications to be deployed on the Payara Micro instance.
2. Deploy the built JMS11NotificationConsumer app
Our next step is to deploy the JMS11NotificationConsumer app using the payara-micro:start
goal:
<plugin>
<groupId>fish.payara.maven.plugins</groupId>
<artifactId>payara-micro-maven-plugin</artifactId>
<version>1.0.7</version>
<executions>
<execution>
<goals>
<goal>bundle</goal>
<goal>start</goal>
</goals>
</execution>
</executions>
<configuration>
<payaraVersion>5.201</payaraVersion>
<deployArtifacts>
<artifactItem>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-rar</artifactId>
<version>5.15.12</version>
<type>rar</type>
</artifactItem>
</deployArtifacts>
<useUberJar>true</useUberJar>
<commandLineOptions>
<option>
<key>--deploy</key>
<value>target/jms11-notification-consumer-1.0-SNAPSHOT.jar</value>
</option>
<option>
<value>--autobindhttp</value>
</option>
</commandLineOptions>
</configuration>
</plugin>
Here, I have made a couple of additions to my plugin configuration. I have added the start
goal, and some configuration options for that goal:
-
<useUberJar>true
</useUberJar>
The default behaviour is not to use the bundled Uber JAR. Setting this property to true means that Maven will attempt to start the Uber JAR, rather than look for a path to an executable specified with<payaraMicroAbsolutePath>
. -
<commandLineOptions>
This property allows you to declare all the same command line options as are available when launching a Payara Micro instance from the terminal. Each<option>
must be specified as its own key/value pair. Do be aware that the<value>
property must always have a value.
-
Why didn't we just add another artifact to the
<deployArtifacts>
list of thepayara-micro:bundle
goal?
The<deployArtifacts>
list would have allowed us to bundle both the RAR and our application at once in an Uber JAR; meaning that everything is packaged in a single unit. The problem is that our JMS11NotificationConsumer application depends on the ActiveMQ RAR, so the RAR must be deployed first. When we package everything into the Uber JAR, we lose any concept of deployment order, so the application might try to deploy before the ActiveMQ RAR and fail when the Payara Micro instance is started.
This method does actually have some benefits when using a Docker container. Keeping a skinny WAR or JAR containing business logic separate means that there can be a significant benefit from Docker's layering system. The ActiveMQ RAR version will change far less frequently than our app and is where the majority of the disk space is taken up. Since Docker only builds the layers which change, this is likely to mean rebuilding (and pushing to a registry!) a few KB rather than a few MB. -
Why didn't we use the
<deployWar>
property of thepayara-micro:start
goal?
The reason we didn't use this is for the simple fact that we are creating an EJB JAR, not a WAR file, so this property would not have deployed our app. If the resulting artifact was a WAR, then this property would have worked with our configuration.
3. Refactor the application to avoid using a post-deploy command file
We could have simply reused the existing post-deploy.asadmin file from the previous blog and supplied that with another <option>
but, since that configuration can be done via annotations, it means we can include that configuration in the app and avoid having to maintain multiple files.
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/notifierQueue"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "notifierQueue"),
@ActivationConfigProperty(propertyName = "resourceAdapter", propertyValue = "activemq-rar-5.15.12")
})
@ConnectionFactoryDefinition(name = "java:global/jms/myConnectionPool",
interfaceName = "javax.jms.ConnectionFactory",
resourceAdapter = "activemq-rar-5.15.12",
properties = {"UserName=admin", "Password=admin", "ServerUrl=tcp://127.0.0.1:61616"
})
@AdministeredObjectDefinition(resourceAdapter = "activemq-rar-5.15.12",
interfaceName = "javax.jms.Queue",
className = "org.apache.activemq.command.ActiveMQQueue",
name = "java:global/jms/notifierQueue",
properties = {"PhysicalName=notifierQueue"
})
public class JMS11NotificationConsumer implements MessageListener {
...
Here, I have added the @ConnectionFactoryDefinition
and created the notifierQueue with an @AdministeredObjectDefinition
annotation. The values of these properties are the same as I used in my previous blog.
4. Start Payara Server with the JMS notifier enabled
Finally, we need to start Payara Server with the healthcheck service pushing data through it the JMS notifier. This is covered in steps 5-7 in my previous blog but, to summarise, the asadmin commands to run against Payara Server are as follows:
asadmin deploy activemq-rar-5.15.12.rar
asadmin set resources.connector-connection-pool.jms/__defaultConnectionFactory-Connection-Pool.resource-adapter-name=activemq-rar-5.15.12
asadmin notification-jms-configure --password=admin --connectionFactoryName=jms/__defaultConnectionFactory --queueName=notifierQueue --contextFactoryClass=com.sun.enterprise.naming.SerialInitContextFactory --dynamic=true --enabled=true --url=localhost:61616 --username=admin --target=server-config
asadmin healthcheck-service-configure-checker-with-thresholds --thresholdWarning=50 --unit=MILLISECONDS --thresholdCritical=80 --checkerName=CPUC --dynamic=true --time=5000 --serviceName=healthcheck-cpu --thresholdGood=0 --enabled=true --target=server-config
asadmin healthcheck-configure --historicalTraceEnabled=false --notifierEnabled=true --dynamic=true --enabled=true --historicalTraceStoreSize=20 --target=server-config
We should now see the same results as we saw before but, now we have set up our Payara Micro environment with the plugin configuration, we have less work to do each time we want to see a change.
We can simply run the goals mvn clean install payara-micro:bundle payara-micro:start
and that should be enough!
Wrap-Up
There are lots of other features in the plugin which aren't covered in this blog post - a complete reference is available in our documentation. The biggest advantage to using this plugin is in creating an Uber JAR. Previously, users needed to use the Maven Exec plugin to call the --outputUberJar
option on a previously downloaded Payara Micro JAR. This meant that Payara Micro would need to start to create the Uber JAR, and then start again when actually running the created Uber JAR. Now, the bundle goal takes care of that, and Payara Micro does not need to start, meaning a big chunk of build time is eliminated.
There are lots of different ways you may choose to use this plugin and many ways to achieve the same goal, so there's sure to be something to fit your workflow!
Related Posts
The Payara Monthly Catch - October 2024
Published on 30 Oct 2024
by Chiara Civardi
0 Comments
Can You Futureproof Your Enterprise Java Apps or Are They Doomed to Fall Behind?
Published on 16 Oct 2024
by Chiara Civardi
0 Comments