 Hi everyone, I'm Brian DeMers and today I'm going to show you how to build a Maven plugin. I'm going to use IntelliJ but you can use your favorite IDE. I also have a blog post for this example if you'd like to read that instead and cut and paste the code. There's also a GitHub link in that post, you can check that out as well. So first up I'm going to create a new IntelliJ project and it's just a basic Maven project and I'm going to use Java 1.8 and I'm going to call the group ID com to octa.example and the artifact ID is important. The structure is going to be some identifier. I'm going to say example dash Maven plugin and it's the dash Maven plugin at the end. That's the important part. I'm going to clean up this directory name a little bit to keep it the same as the artifact ID and I've built this a few times so I'm going to give it a new directory. This is your pretty standard Maven project creation screen. Nothing new yet. So here we go. So we have a basic empty Maven projects and I'm going to enable auto imports because I'm going to change some of the palm information and I'm going to add some other standard attributes. So like any good developer I always give a name and a description. In my case this is the example Maven plugin and an even simpler description. I'm also going to define some common properties. So I'm telling the source and the target of the compiler to be Java 1.8 and I'm setting the encoding to UTF-8. So next up I'm going to define a dependency block and I'm going to define my dependencies. In my case I'm using the Maven plugin API because I'm building a plugin. Maven core is also pretty standard and then I'm also defining the plugin annotations. These all have a scope of provided. These dependencies are provided to you by the Maven runtime that you're using to run the project. The last thing I need to do is add some plugins. Since I've already defined this project as a Maven plugin I just need to tweak a few of the versions of the plugins that I'm using. So the Maven plugin plugin is the Maven plugin that builds plugins. How about that for a mouthful? So I'm going to bump the version to 3.6 and I'm also adding the site plugin here while I'm here. So that's it. So just a few simple dependencies, a few simple plugin tweaks and again I'm using plugin management here because the plugins and the goals that are used are already defined based on the project type which I forgot which is packaging Maven plugin. That is important. So next up I'm going to create a new package. I'm going to call it com to octa example, a class. So I'm going to call mine the git version mojo. So a mojo is a Maven term, a Maven plain old Java object just the same as your pojo. So I'm going to extend an abstract mojo and it's going to make me implement one method which is execute. So that's where all the logic for my plugin is going to go. So I could do something incredibly basic right now, get log, info, cool, a Maven plugin. Alright so this is almost done but I need to add an annotation to this class. So Maven knows it's a mojo. So I'm going to call mine version. So the mojo name is the name of a goal, a plugin typically consists of one or more goals and each goal runs at some phase during the life cycle. In my case I'm just executing command in the command line. So I want to do this early on in the Maven life cycle. So I'm going to say it's initialize. And we also need to provide Java doc. And obviously that's important everywhere but in our case it'll get used for the documentation later on. So I'm going to cheat and spit out some preform out of doc. So that's it. So I could run this right now and it'll spit out this bit of text. So let's do that. So first I need to build the plugin. So Maven install, great. And then I'm going to execute the plugin. So plugins are executed with the standard format of group ID which in our case is com to octa.example. Then artifact ID which is example Maven plugin. And then the goal name which in our case is version. So there we go. Cool. A Maven plugin. That's not much more useful than a hello world example. So let's let's add something useful to our plugin. So back in our mojo class, I'm going to define some parameters. So first up, I'm going to say I have a string called command, oops, string command. And we're going to find this as a parameter. I'm going to give it a property name of git.command. And then the default value, we're going to say it's git rev parse short head. Not overly complicated. But what this is doing is this is saying this command is a parameter. You can either pass it in through the command line with a dash D git.command notation, or you can use it in an XML file just by using command. And the default value, if you don't specify one is going to be this, this git rev parse. One more thing, I'm also going to inject the Maven project itself. So private Maven project, Maven project, let's just call this project. I'm also going to annotate this field with a parameter and its property is project. And it is read only. So we're also missing some Java doc. So let's add that as well. This is the command used to get current revision easy enough. So now that we have a command, let's do something with it. So I have something ready to go. So I have this method called git version, which takes a command and just executes that with a Java runtime. So just executes it, captures the output and returns it as a string. So from our plugin, we can do string version equals git version command. And then we can use the Maven project. We're going to get all the properties and then we're going to add a new one. So we're going to put example version, and we're going to set the version right here. And I'm also going to print something useful to the log, which is git hash version. All right. So that's our quick Maven plugin. So I'm going to build this again and then run it. All right. So let's run that the same way we did before. Well, this project isn't a Maven repo. So I'm going to git, git init, git add, the palm and the source directory, git commit. Not super excited. Let's do that again. There are. Here's our git hash. Excellent. Now, if I want to change the command of the command line, I could do that with dash d git command equals git rev parse head. And then it will be the longer hash, no longer the short hash. Look at that. Cool. So we have a plugin, everything's crammed into this single class, which is fine for basic examples. But often you want to break up your code into modular chunks to make it easily testable. I'm going to show you how to do that right now. We're just going to pull out this git version method into into a new class and then inject it into our plugin. So we go back to our example package, I'm going to create a new class, a new interface sorry, I'm going to call this version provider, and then I'm just going to lift the method signature from this class here, the mojo itself, keep things nice and simple. And then I'm going to create implementation of this interface. I'm going to call it run time XE version provider. And of course, this implements our version provider. And I'm going to lift this get method right from the mojo itself, paste it over here. So the only thing left to do is annotate our class. So using the standard at inject or JSR 330 annotations, I'm just going to do at named and then at singleton. So if you're a spring fan, this is the equivalent of using the component annotation. So back in our mojo, I need to just inject the version provider using the standard at inject. And then version provider calls version provider, and then fix our new compiler error here. And that's it. So once again, I'm just going to build the plugin and execute it the same way I did before. Sorry, maybe an install. There we go. And then I'm going to execute it once again. There we go. So executed the same, our code is just broken up into chunks. All I had to do is add some standard annotations to my components. And now my execute method is literally just three lines. Very nice. All right, so typically, maybe plugins are defined in your palm dot XML file. So let's create an example that uses our new plugin. So we'll cheat a little and we'll define a new palm right within our project. Oops, new file, put in a director called usage example. Palm dot XML. And I have one ready, I'm going to call this example palm. This is just so you don't have to watch me type all of this. And it's just a simple example palm with a definition of our Maven plugin, the example Maven plugin. And I'm setting the command to a very short hash less, less useful, but it still illustrates the point. And I'm also using this echo Maven plugin to print out the new example version property of defined. This will simply print out the project version is version, which in our case is 1.0 dash snapshot dash, this very useless short hash. So if we run this on the command line, we have MVN package. And we say it's dash F usage example palm. And there we go. So we have the hash as reported in our plugin, right here. And then the echo plugin also uses our new property to print this line. Great. Well, that's cool. So now we have a plugin, we've used the plug in both on the command line directly and in another palm file. So the only thing left to do is to show you how to document your project. So if we go back to the projects that plug in palm file, we're going to add a few things here. So all you really need is a reporting section. So if you use it once again, the Maven plugin plugin and define the report as report, that is all you need. But because we're good developers, I'm also going to add some more metadata to my palm. So let's do to find the organization. So give it the great name of example, Inc. And we'll use this Google search URL. And then I'm also going to use some prereqs, which in our case, I'm going to say the lowest version you should use with this plugin is Maven 3.5. So now if I run the site build, which is just MVN site, this will take a couple seconds because it's building the project and generating a bunch of reports. There's some there's some ways to to speed this up. But that's outside the scope of this video. So it should be almost done here. And then I'll open the page in my favorite browser. So just open target site plugin info, which is the the generated HTML file. And here we go. So we have our name. We have the version. We have the description from our Java doc. We have our Maven version here, which is 3.5, which I just set the example version goal. And that has the information pulled from the annotation and the Java doc. So as you can see, the default value is get rev parse short head. And then the user property, like we used before, was get doc command. So this is one of my favorite things about Maven plugins. All of the documentation generally looks the same. It's really easy to navigate because due to the consistency. That's it. I've showed you how to build a Maven plugin, how to break it up into components and how to generate the documentation. Be sure to check out the description below for the link to the original blog post that has all the code and everything you need to copy and paste this example. If you like this video, click that subscribe button. We have new videos coming out weekly. And check out our blog for even more content. Thank you.