Using the Payara Micro Maven Plugin

Photo of Mike Croft by Mike Croft

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.

 

  1. Bundle the ActiveMQ RAR into an Uber JAR
    The first improvement we can make is to use the payara-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. 

 

Now we have configured both the goals, we need to address a couple of questions: When there are several different ways of configuring Payara Micro (here we are deploying the RAR and the EJB JAR using different configurations), why did we go to the effort of doing it all this way?
  1. Why didn't we just add another artifact to the <deployArtifacts> list of the payara-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.

  2. Why didn't we use the <deployWar> property of the payara-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!

Payara Micro Download

 

 

Comments