Skip navigation

Jive Plugin Developer

6 Posts authored by: Ryan King

A while back, it was reported that Javascript files that were overlaid in the web/src/main/overlay directory were not being properly minified as part of the build process.  I'm happy to say that this issue has been addressed in the latest version of the jive-parent-pom for Jive versions 6.0.3.4 and up.  Getting the fixes into your project is easy.

 

The next time you build your project, you should see a message similar to the following:

 

[INFO] ************************************************************************************************************************************************

[INFO] Checking for newer versions of jive-parent-pom...

[INFO] You are currently using version 6.0.3.4-3 of jive-parent-pom.

[INFO] The latest version of jive-parent-pom is 6.0.3.4-4

[WARNING] You are not using the latest version of jive-parent-pom.  It is strongly recommended you update your project POMs to reflect this, as follows:

[WARNING] <parent>

[WARNING]     <groupId>com.jivesoftware.maven</groupId>

[WARNING]     <artifactId>jive-parent-pom</artifactId>

[WARNING]     <version>6.0.3.4-4</version>

[WARNING] </parent>

[INFO] ************************************************************************************************************************************************

 

Just follow the instructions, and modify your root POM's <parent> element to point to the appropriate version. 

 

Before rebuilding your project, however, you'll need to make one more change.  In your /web/pom.xml file, remove the following dependencies, as they are no longer needed:

        <dependency>

            <groupId>com.jivesoftware</groupId>

            <artifactId>yuicompressor</artifactId>

        </dependency>

 

 

        <dependency>

            <groupId>com.jivesoftware</groupId>

            <artifactId>yuicompressor-anttask</artifactId>

        </dependency>

 

 

Once you have made these changes, you can rebuild your project, and note that your overlaid Javascript is once again being properly minified.

 

Please reply if you have any questions about this change.

 

Thanks!

Hey everyone.

 

I wanted to let everyone know that we have added full support for Jive 7.0.2.0 to the Jive Maven Unified Archetype.  We created the new 7.0.2.0-compatible version of the jive-parent-pom in conjunction with the 7.0.2.0 GA release on Monday, so you technically have been able to create 7.0.2.0 projects since that time, but the archetype was missing some 7.0.2.0-specific search settings, which could have led so your local search server not starting up correctly. (See the end of this post for details)

 

To recap, in order to create your new Jive 7.0.2.0 project, just enter the following on your command line:

 

$ mvn -U jive:create-project

 

Be sure to specify "7.0.2.0" when prompted for a Jive version.

 

If you already have a Jive project, and want to upgrade it, you can easily start the process by entering the following command at the root of your project, entering "7.0.2.0" when prompted:

 

$ mvn -U jive:upgrade

 

If all this jive:whatever-whatsthisnow craziness is new to you, be sure to check out Announcing Jive Maven Archetype Changes and Moar Archetype Changes! Now Simpler Than Evar!

 

Also, if you're upgrading, and want to incorporate any changes in the archetype into your project, check out and follow Maven Unified Archetype Release Notes.

 

 

Ok, so if you got super excited, and created a new 7.0.2.0 project before this blog post was published, you'll need to make a few changes.

 

If you run the start-search script in the run-services directory, you'll see the following error message:

 

/---------------------------------------------------------------------------------

The follwoing properties are missing and need in-order to start the service.

CONTENT_SEARCH_FILTER_CACHE_ENABLED=true

CONFIG_DIRECTORY=./etc

CONTENT_SEARCH_FILTER_CACHE_SIZE=1000

CONTENT_SEARCH_FILTER_CACHE_TIME_MILLIS=600000

 

 

Add the properties to /path/to/my/project/run-services/main-args.properties and restart the system.

\---------------------------------------------------------------------------------

 

But HOLD ON, because if you add those properties exactly as displayed, your search service won't start up properly, and will just hang.  You'll need to modify the CONFIG_DIRECTORY property to be ./var/data/directory.  Add the following lines to the end of your main-args.properties file:

 

CONTENT_SEARCH_FILTER_CACHE_ENABLED=true
CONFIG_DIRECTORY=./var/data/directory
CONTENT_SEARCH_FILTER_CACHE_SIZE=1000
CONTENT_SEARCH_FILTER_CACHE_TIME_MILLIS=600000

 

 

As always, we welcome your feedback.  Thanks!

Upgrades Made Easy(er)

Posted by Ryan King May 10, 2014

Before you read this post, check out:

 

 

Our recent changes to the Maven archetype, including the inception of the jive-parent-pom, are aimed at making it easier to do those mundane, yet error-prone, tasks around project creation, as well as alerting you to new changes to dependencies and build configuration.  As I mentioned in my last post, your build will tell you if there is a newer release of the jive-parent-pom for your version of Jive.  While this is all well and good, it doesn't help you upgrade your custom project or plugin.  For instance, if you want to upgrade from 7.0.0.2 to 7.0.1.0, you would have to change the version of the jive-parent-pom dependency in the <parent> element of your project's pom.xml file, somewhat blindly, from 7.0.0.2-1 to 7.0.1.0-0, build the project, and see if you needed to change the version again to something like 7.0.1.0-1.  While this is still easier than search for the proper jive, EAE, search, Spring and AspectJ versions for the version of Jive you're upgrading to, it's still not ideal.  That is about to change.

 

The jive:upgrade goal is here!

 

Note that the following is only valid with projects and plugins that were created with the new jive:create-project and jive:create-plugin Maven goals.  You'll need to upgrade any projects you have created using the old maven-jive-archetype or maven-jive-plugin-archetype before you can use this.

 

This goal can only be executed from your root project, or your independently-created plugin (not within a Jive project).  Just run the following command:

mvn -U jive:upgrade

 

You will be prompted to type the Jive version to which you want to upgrade.

 

You are current using Jive version 7.0.0.2. Which version of Jive do you want to upgrade to?: 7.0.1.0

 

All you have to do is enter the full Jive version.  The goal will then automatically detect the latest jive-parent-pom release for that version of Jive, and change the version within your project's pom.xml file.

 

[INFO] Applying com.jivesoftware.maven:jive-parent-pom version 7.0.1.0-3 to /Users/ryan.king/code/test/upgrade-me-again/pom.xml

[INFO] Applying com.jivesoftware.maven:jive-parent-pom version 7.0.1.0-3 to /Users/ryan.king/code/test/upgrade-me-again/run-services/pom.xml

[INFO] Be aware that you may need to change the contents of the following files:

[INFO] run-services/serviceconfig/core.json

[INFO] run-services/main-args.properties

 

While this sounds perfect, there is a caveat.  Sometimes, upgrading from one version of Jive to another requires that you change some files.  Once you complete this process, you may need to make those changes.

 

Stay tuned, as more changes are coming!

 

As always, post your comments and feedback here.

A couple of weeks ago, I wrote a post Announcing Jive Maven Archetype Changes.  This was just the first step in a series of changes to make both the use and the management of Jive Maven archetype-generated projects easier.  The first step, described in the aforementioned post, discussed the new unified archetypes, which, going forward, will support Jive 6, 7, and beyond. Next, we abstracted the archetypes altogether with the creation of the Jive Project Plugin for Maven, described in How To: Create a Custom Jive Project, making the generation of a project as easy as typing a simple, easily-rememberable command, which will always pull from the latest version of the unified archetypes, so you get all the latest improvements for your new project.

 

While these first steps make project and plugin creation a cinch, they don't help much with maintaining your project.  You still need to know which version of Jive to point to, and which versions of the EAE and Search server libraries to use for that version. We tried to make that a bit easier with Jive EAE/Search Dependency Map, but it's still ultimately a manual process to upgrade them, and still quite error prone.  Not only that, but the project POM files are kinda huge.  We use lots of plugins and dependencies in our projects, and they are repeated, over and over again, every time you create a project.  As we changed things, such as AspectJ or Spring library dependencies, or Maven plugin configurations, there was really no way to get them to you, the developer.  You were pretty much stuck with generating a new project from the latest archetype version, and performing a diff against your existing project.

 

Well, those days are gone.

 

I'm thrilled to tell you about new changes to the Jive Maven Unified Archetype (and the Jive Maven Unified Plugin Archetype) that simplify version management, decrease the size of your project POMs, and help keep your builds up-to-date with the latest changes.  Best of all, this is already available to you.

 

First things first:  You'll need to upgrade your Maven installation.  Unfortunately, some of the awesome features we wanted to use were only available in Maven 3.2.1.  Go get it here.

 

If you follow the instructions in How To: Create a Custom Jive Project, and execute the command to create a new project..

 

mvn -U jive:create-project

 

...and follow all the prompts, on the surface, your new project will look the same.  If you look a bit closer, however, you'll see the difference.  Check out the project's root pom.xml file.

 

<?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>
    <name>demo-project</name>
    <groupId>com.jivesoftware.demo</groupId>
    <artifactId>demo-project</artifactId>
    <version>1.0-d1-SNAPSHOT</version>
    <description>Jive customization project. This is the parent pom</description>
    <packaging>pom</packaging>

    <parent>
        <groupId>com.jivesoftware.maven</groupId>
        <artifactId>jive-parent-pom</artifactId>
        <version>7.0.1.0-2</version>
    </parent>

    ...
</project>


 

Notice the new <parent> element.  This references the new jive-parent-pom, which enables us to do all those things we mentioned above.  If you click the link, and take a look at the POM itself (after authenticating to our Archiva server, of course), you'll see that we pushed all the dependency and plugin management up into this new parent POM.

 

Now, all those nasty versioning details are completely abstracted.  The versions you need for the Jive, EAE, Search service, AspectJ, Spring libraries, are all defined for you, and you won't need to change them.  But if, for some reason they do need to change, all you'll have to do is change which version of the parent POM your project is pointing to (from 7.0.1.0-2, for example, to 7.0.1.0-3), and you'll get all those changes.  This does not only apply to versions, but also to Maven plugins.  Whereas before all plugins were explicitly defined in the root, web, and plugin POMs, now they are defined in the parent POM, and merely referenced in the individual POM files.  Each plugin's configuration is hidden where possible, and each POM that needs it simply references it.  As you can imagine, this makes the POMs themselves much smaller.

 

Fun Fact:  We reduced the size of the root POM file from 318 lines, to 77 lines.  The web POM is still kinda hefty, due to the cargo configurations, but it, too, shrunk in size a great deal, going from 520 lines, down to 331.

 

At this point you might be asking yourself how a developer might know that new changes are available in a new version of the parent POM, and you'd be right to do so.  After all, the whole point of all these exercises was to simplify things and get our developers out of the business of keeping track of which versions of what to use, so what gives?  My answer to you would be this:

 

Your build will tell you.

 

Tucked away into the <plugins> section of the jive-parent-pom is a little plugin called jive-parent-pom-version-check-plugin, which contains a goal which is run every time you perform a build.  During the validate step of the project lifecycle, it will check Maven to see if another, newer, version of the jive-parent-pom is available, and will display a message if that is the case.  For instance, if my project was using version 7.0.1.0-1 of the parent POM, I would see the following message when building my project:

 

[INFO] Checking for newer versions of jive-parent-pom...

[INFO] You are currently using version 7.0.1.0-1 of jive-parent-pom.

[INFO] The latest version of jive-parent-pom is 7.0.1.0-2

[ERROR] ************************************************************************************************************************************************

[ERROR] You are not using the latest version of jive-parent-pom.  It is strongly recommended you update your project POMs to reflect this, as follows:

[ERROR] <parent>

[ERROR]    <groupId>com.jivesoftware.maven</groupId>

[ERROR]    <artifactId>jive-parent-pom</artifactId>

[ERROR]    <version>7.0.1.0-2</version>

[ERROR] </parent>

[ERROR] You can bypass this error by setting the ignoreNewVersion property to "true"

[ERROR] ************************************************************************************************************************************************

 

At this point, you would have the option of changing the version to the recommended version, and you're golden.  And when it comes time to upgrade, it's just a matter of changing your jive-parent-pom version to the appropriate version, and then dealing with compile errors, etc.

 

Transparency Time:  As I type this, I understand that it's not entirely obvious, when it is time to upgrade, which version to change to.  For now, this will be a trial and error process.  Simply change the version to the next Jive version, and add a -0.  Your build will tell you if:
  • a parent POM for that version of Jive exists
  • whether a new version for the parent POM exists for that version of Jive (like -1 or -2 ) exists

 

Look for another blog post soon that details some new cool ways to know what versions of the jive-parent-pom are available, right from your command line.

 

If you have read this, and are wondering how you can get these changes into your existing project without having to scrap everything and start over, well there's good new and bad news.

 

The good news is, yes, you can definitely do this!  The bad news is, you have to do it the old way, by creating a new project, and then performing a diff on your root, web, run-services, and plugin POMs.  However, you only have to do it this one last time!

 

For plugins that exist within the context of a project, they should still use the root project as their parent, but will still get all the parent POM goodness through inheritance.  Independent plugins, on the other hand, which do not live within a root project, should reference the jive-parent-pom directly, as its parent.

 

Hold On, Right There:  The new jive-parent-pom is only available for Jive 6.0.3.4 and up.  If you're still using Jive 5, or an earlier version of Jive 6, you'll need to wait to get this until you upgrade.  So upgrade, already!

 

As always, we welcome your feedback.

 

Thanks!

Hello all,

 

We have been working hard over the past few weeks on the latest set of changes Jive's Maven archetype, which I am happy to highlight here.

 

Unified Archetype

 

Each time a new major version of Jive has been released (5.0, 6.0, 7.0) we have created a new version of our Jive Maven archetypes.  This has allowed for the easy inclusion of modules or elements specific to that new version.  Additionally, the archetypes have been never really been released, and have been left as SNAPSHOTs.  This has enabled developers, each time they create a new project or plugin, to get the most recent version of of the archetype, along with any fixes or improvements therein.  Honestly, this has always felt a little weird.  While it makes sense from a practical standpoint, we're not really following any best practices by doing so.  We didn't want anyone to miss out on the latest just because they got the version number of the archetype wrong, specifying version 7.0.0.1, for example, when there's a really great fix in 7.0.0.2.

 

That's all changing today, with our new jive-maven-unified-archetype (and jive-maven-unified-plugin-archetype).  The unified archetype will support both 6.x and 7.x Jive projects.  It will also be versioned with each change.  But that's ok because we are also releasing a new Jive Maven Plugin, called jive-project-plugin.  With a few tweaks to your settings.xml file, you'll now be able to create a new custom project without ever dealing with the archetype directly, or knowing the name of its latest version.

 

You'll now be able to create a project simply by running the following on the command line:

mvn -U jive:create-project

 

or a new plugin with:

mvn -U jive:create-plugin

 

You will then be asked questions regarding the kind of project you want to create, including:

  • Jive version (and, yes, EAE and Search versions will be changed accordingly)
  • Project group ID
  • Project artifact ID
  • Instance type (internal or external)

 

It's all detailed in How To: Create a Custom Jive Project.  We definitely welcome your feedback should you experience any problems using it, or have any suggestions for improvement.

 

 

Themery

 

Historically, custom themes have lived in the web module, in the /src/main/themes directory, of our maven-jive-archetype.  This has worked pretty well to this point, but changes we have made to our build environment at Jive dictated that we make a change.  Under the new jive-maven-unified-archetype, themes have been moved out into its own module, as a peer to the web module. 

 

Screen Shot 2014-03-10 at 6.57.03 AM.png

 

We have worked on a number of customer projects lately that have consisted of only Jive plugins and custom themes, with no custom WAR (which is a good thing!).  However, with the themes tied to the web module, that meant that we always had a WAR artifact to deploy to Maven, empty or not.  That's over 100MB per deployment.  Over time, and with all our customers, that amounts to a ton of wasted space.  Now, when you build your project, the themes module will produce its own binary artifact, themes-<version>.zip

 

EAE and Search

 

The run-services module has had an awkward existence since its creation in the 6.0.x version of the maven-jive-archetype.  If you leave it as a module, referenced in the root POM, it gets built and potentially deployed to Maven upon release.  To avoid this, we have made a couple changes to prevent this.

  1. run-services is no longer a module in the root POM
  2. The <parent> reference to the root project has also been removed from the run-services POM.
  3. <eae.version> and <search.version> properties have been moved from the root project to run-services.

 

These changes give the run-services project a sort of transient existence, in that it's still useful when running your Jive instance locally, but will never be built or deployed if you leave things alone.

NOTE: This technique is valid only for Jive 6.0.1 and up.

 

Adding markup to the Jive application can be a challenge within the context of a plugin.  Well, I take that back.  It's easy to do, sure.  But doing it right?  A little harder than you might think.

 

Sure, you could just redefine a core Struts action in your plugin's struts.xml file and point it at your custom Struts action and/or custom Freemarker or Soy template.  But you know that doing so introduces risk.  Another plugin you install into your instance later on could override the same action, rendering one of them useless.  You may need to theme the Freemarker or Soy template that you modified, which would also wipe out the change made in your plugin.  You also are bound to that action and template's implementation for your version, which requires you to have to manually upgrade them each time you upgrade your Jive instance.

 

To get around that, you could always use Javascript, which you can include on every page in the system, that knows when to modify the DOM structure of the page, which is a pretty slick way to do it.  You can have your script detect which page you're currently on, and, when appropriate, invoke a Soy template, and append it to the DOM, thus modifying your view in a pretty upgrade-safe manner.  The problem with this approach becomes evident when you realize your custom page content requires server side data.  This means you need to make an AJAX call to a web service which you may or may not have to code up yourself, which totally works, but may not result in the best user experience, with the custom content being added to the DOM after a slight delay.

 

It would be great if we could somehow augment the data being returned by the Struts action in the first place, and have some sort of hook to add the markup that utilizes that data to the DOM structure.

 

Enter the PluginTemplateDefinition.

 

A PluginTemplateDefinition is a way to do just that.  Utilizing it requires the following:

  • Create PluginTemplateDefinition Java class implementation
  • Add your PluginTemplateDefinition class to Spring, and register it
  • Create a Soy Template

 

The Java Class

public class MyPluginTemplateDefinition implements PluginTemplateDefinition {

    @Override
    public boolean supports(Action action) {
        //only execute when looking at a place overview page
        return (action instanceof PlaceOverviewAction);
    }

    @Override
    public String getHeadTemplateName() {
        //no meta tags or css for this
        return null;
    }

    @Override
    public String getBodyTemplateName() {
        //template containing Javascript to modify the DOM
        return "jive.test.app.body";
    }

    @Override
    public Object getModel(ActionInvocation ai, Object actionModel) {
        //making available the data that I want
        Map<String, Object> model = new HashMap<String, Object>();

        Place place = ((PlaceViewBean) actionModel).getPlace();
        if(place.getObjectType() == JiveConstants.SOCIAL_GROUP) {
            List<String> owners = getSocialGroupOwners(place);
            model.add("owners", owners);
        }

        return model;
    }
}

 

The support() method simply checks whether this PluginTemplateDefinition should be executed for the current action.  In the case of this example, we only want it to execute when the PlaceOverviewAction is invoked.  If we wanted to execute on every page, we could just return true.

 

getHeadTemplateName() and getBodyTemplateName() will return fully-qualified soy template names.  The head template should only contain CSS includes and meta tag information.  In many cases, you won't need anything here, and can just return null.  The body template will contain the Javascript necessary to modify the DOM structure of the page being displayed.

 

In the getModel() method, you will create and return the data you want to be displayed on the page.  Here, you have access to the ActionInvocation itself, as well as the data returned by the action.  The actionModel parameter will be either a Soy model, for Soy-driven Actions, or the action itself, for legacy Struts actions.  You can access anything you want here, but should be wary of modifying any of the data in the model.

 

spring.xml

Registering your PluginTemplateDefinition is a matter of adding it to the list of plugin template definitions defined in Spring.  So, you would add the following to your plugin's spring.xml file:

<bean class="com.jivesoftware.community.util.spring.MergeableCollection" parent="pluginTemplateDefinitions">
    <property name="source">
        <util:list>
 <bean class="my.plugin.MyPluginTemplateDefinition" />
        </util:list>
    </property>
</bean>

 

Of course, if your PluginTemplateDefinition class has dependencies, you would define them here, as well.

 

Soy template

Your soy template will contain the Javascript needed to augment the DOM structure and display your data.

 

{namespace jive.test.app}

/**
* @param appParams
*
* @depends path=/resources/scripts/apps/my_amazing_js_app/main.js
*/
{template .body}
    {call jive.shared.soy.resourceInlineJs}
        {param id}plugins{/param}
        {param code}new jive.Amazing.App.Main({lb}buildJson({$appParams}{rb});{/param}
    {/call}
{/template}

 

This example assumes that you would be implementing some sort of complex, interactive visual layer on the screen.  If you're looking just for a simple inclusion of data on the screen, you could do something as simple as:

{namespace jive.socialgroupaccess}

/**
* @param owners
*/
{template .body}
    <script type="text/javascript">
        $j('#some-element').append('<p>{$owners}</p>');
    </script>
{/template}


 

Keeping in mind that you may also want to include another soy template here, rather than using HTML literals, just to keep things modularized.

 

Enjoy!