Log statements in pom.xml or Tracking flow of Maven - java

I am new to Maven and I am trying to get strong hold of it. I have gone through the beginner's tutorials and I am able to understand the basic stuff, but I have a complex pom.xml file in my project and my next goal is to understand that.
With the limited knowledge acquired from beginner's guide it is not possible for me to understand that complex pom.xml, so i was thinking of adding some sort of log statements in pom.xml or looking for an alternative via which i could track the flow of execution in pom.xml, since that would help me in knowing how things are moving.

You could printout some log messages to maven console using the maven-antrun-plugin, you can also specify the phase you want to print the message in, see the code below (it goes to the plugins section)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>print-log</id>
<phase>initialize</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo message="Your log message for project ${project.artifactId}" />
</target>
</configuration>
</execution>
</executions>
</plugin>

I believe that output generated by debug option in maven can be quite huge and time consuming for reading. I use it only for some specific problem analysis.
For me it allways worked to go through complicated pom.xml files by reading and try to understand intent of the author of the particular section (I think good reference for the pom.xml elements can be found on: http://maven.apache.org/pom.html).
Once you run build afterwards, you can see what and when is it executed and you can find mapping between what you've learned before and how it really works :)

You can start by issuing
mvn -X install
That will give you the flow of execution.
According to mvn --help:
-X,--debug Produce execution debug output
An alternative if you want to see all your dependencies, properties, plugins, directories etc. the try this:
mvn help:effective-pom

I would recommend to read more about Maven build lifecycle. Maven is not a script-like build automation tool (like ant or make). It's a different approach. Logs should be less important than output artifacts produced in ./target directory.

Related

Antlr4 "Test Rig" and maven

I am struggling a little bit to figure out how I can use the antlr4 maven plug in to run the TestRig class?
I've read though the output of mvn antlr4:help -Ddetail=true, which is the only documentation I have been able to find, but this doesn't mention how to use the TestRig. So, what's the recommended way of using the test rig together with maven? using the grun alias method doesn't seem very elegant here.
UPDATED - Reasoning
Hello :)
Right, don't get me wrong but I really don't understand why you wouldn't want this functionality in the maven plugin? And I don't understand why its soul purpose should be to compile grammars?
Currently, if I maintain a build with Maven, and I use the antlr4-maven-plugin , it will install both the plugin and the antlr 4.1 in my maven repository. With this already there, why would I start adding things to my classpath and creating aliases when maven can take care of that? I mean, this is what maven is for really. If I had a antlr4:TestRig goal, then all I would do was use that. No need to manually maintain the class path, or create bash aliases. It would just work.
And be far far more elegant that hard-coding elements from my local maven repository in my class path, and maintaining bash aliases. Or alternatively, maintain two installations per. version of antlr I wish to use (one maintained by me, simply to use TestRig, and one maintained by maven for everything else).
Additionally, if I wanted to use a different version of antlr, then I wouldn't need to update the classpath and my aliases, maven would simply manage all this for me :)
This is how I invoke TestRig with Maven:
mvn exec:java -Dexec.mainClass="org.antlr.v4.runtime.misc.TestRig"
-Dexec.args="<DOT_NOTATION_GRAMMAR_CLASSPATH> <START_RULE>
-gui <INPUT_FILE>"
So if you've got MyGrammar.g4 in src/main/antlr4/com/test/parser with a starting rule of startRule:
mvn exec:java -Dexec.mainClass="org.antlr.v4.runtime.misc.TestRig"
-Dexec.args="com.test.parser.MyGrammar startRule
-gui <INPUT_FILE>"
I had a similar question, in that I wanted to use the TestRig -gui option for debugging my grammar. I didn't find a way to run the GUI via the antlr4-maven-plugin, but I did manage to build a satisfactory CLASSPATH. The key was to include target/classes.
# Assuming your project is in $PROJECT ..
CLASSPATH=".:/usr/local/lib/antlr-4.1-complete.jar:$PROJECT/target/classes"
alias grun='java org.antlr.v4.runtime.misc.TestRig'
mvn -q compile
grun MyGrammer startingRule -gui < test_input
Should produce a lovely GUI view of the syntax tree.
Why would the Maven plugin run the TestRig class? The Maven plugin's job is converting the .g4 grammar files to .java source files in the proper package locations and ensuring those generated files get compiled. TestRig is not used for any part of that.
Edit: I have been using ANTLR for many years, in many applications. In all that time I have never updated my system classpath, nor operated ANTLR/gunit/TestRig from the command line or created aliases for it. Doing so is not helpful for automated testing and inevitably leads users into the problems you described. That said, the thought that TestRig needed special support in the Maven plugin also never crossed my mind, because better solutions already exist.
Some alternatives
You can use the surefire plugin, and write a JUnit test that performs operations on your grammar directly (create a lexer/parser, parse some input, and perhaps even call inspect() on the resulting parse tree.
You can use the surefire plugin, and write a JUnit test that explicitly calls TestRig.main(String[]) with the correct arguments.
You can modify the ANTLR 4 Maven plugin to add a new goal for running TestRig, and submit a pull request to the project to have it included in a future release (you would need to make a very compelling case since there are already 2 alternatives that are more suited to long-term successful testing of a project using ANTLR 4).
I like the idea of using Maven to run the TestRig. But I do not like to add the dependency org.antlr:antlr4 to my code (because I already have org.antlr:antlr4-runtime) so my solution is to configure the exec plugin with an additional dependency.
<properties>
<antlr.version>4.7.1</antlr.version>
</properties>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>TestRigGui</id>
<phase>none</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>org.antlr.v4.gui.TestRig</mainClass>
<arguments>
<!-- Grammar -->
<argument>de.humanfork.experiment.antlr.Hello</argument>
<!-- start rule -->
<argument>hello_rule</argument>
<!-- enable gui -->
<argument>-gui</argument>
<!-- input file -->
<argument>example.txt</argument>
</arguments>
<includePluginDependencies>true</includePluginDependencies>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4</artifactId>
<version>${antlr.version}</version>
</dependency>
</dependencies>
</plugin>
Then use: mvn exec:java#TestRigGui to start the GUI
BTW: in ANTLR 4.7.1 the TestRig main class is: org.antlr.v4.gui.TestRig

Maven 3.0.4 - execute annotation processors after compile

I would like to run the following basic procedure within my Maven 3.0.4 project. I have all the basics in place and haven't had any issues but am running into problems on step #3. For some reason the basic solution is eluding me, since it seems like something that should be very obvious.
Run a basic clean/install (without annotation processing)
Request that a site build be run
Before the site build kicks off, run annotation processing on the compiled classes using an annotation processor class that was compiled in the initial steps
I tried setting up the annotation processing goal as follows:
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<executions>
<execution>
<id>process</id>
<goals>
<goal>process</goal>
</goals>
<phase>pre-site</phase>
<configuration>
<outputDirectory>${basedir}/target/generated-documentation</outputDirectory>
<processors>
<processor>com.mydomain.MyFancyAnnotationProcessor</processor>
</processors>
</configuration>
</execution>
</executions>
</plugin>
For some reason this doesn't seem to be working.
I feel like I'm doing something very, very silly that is preventing it from working.
I am using the Maven Annotation Plugin instead of the basic, Mojo Apt Plugin. I don't mind switching if someone has a working solution with that one. I tried both without any immediate signs of success. Again, it feels like it's just something obvious that I'm overlooking.
Error received:
[INFO] diagnostic error: Annotation processor 'com.mydomain.MyFancyAnnotationProcessor' not found
[ERROR] error on execute: error during compilation
My guess would be that the plugin is not including the current project itself in its classpath. The best solution would be to separate the annotation processor into its own (sub-)module if possible. If you can't do that, you may be able to just add this project itself as a dependency of the plugin (using a <dependencies> section under the plugin node).
As a diagnostic note, you can run maven with the '-X' argument to see detailed info about the build. This should show you exactly what is on the classpath when the plugin is executed.

Moving to Maven from GNUMake

I've been a long time user of the Make build system, but I have decided to begin learning the Maven build system. While I've read through most of the online docs, none seem to give me the analogies I'm looking for. I understand the system's lifecycle, but I have not see one reference to compile step dependencies. For example, I want to generate a JFlex grammar as part of the compile lifecycle step. Currently, I see no way of making that step a pre-compile phase step. Documentation seems to be limited on this. In general, the concept of step dependencies seem to be baked into Maven and require a plugin for any alteration. Is this the case? What am I missing, because currently the Maven build system seems very limited in how you can setup compilation steps.
You can do anything in Maven. It generally has a default way to do each thing, and then you can hook in and override if you want to do something special. Sometimes it takes a lot of Stack Overflowing and head scratching to figure it out.
There is even an official JFlex Maven plugin.
Whenever possible, find someone who has made a Maven plugin do what you want. Even if it isn't 100% right, it may at least give you an idea on how to make maven do something.
Minimal configuration
This configuration generates java code of a parser for all grammar files (.jflex , *.jlex , *.lex , .flex ) found in src/main/jflex/ and its sub-directories. The name and package of the generated Java source code are the ones defined in the grammar. The generated Java source code is placed in target/generated-source/jflex , in sub-directories following the Java convention on package names.
pom.xml
<project>
<!-- ... -->
<build>
<plugins>
<plugin>
<groupId>de.jflex</groupId>
<artifactId>jflex-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<!-- ... -->
</build>
<!-- ... -->
</project>
This feels like the maven way to do things. Put your stuff in the right folders (src/main/flex), and this plugin will automatically build it into your project. If you want to do fancier custom stuff, there are some options. but Maven is all about favoring convention over configuration.
To be frank I think that your current mindset maps much better to ant than to maven, and I would suggest starting with that.

Organize imports with Maven2, Eclipse-style?

I'm a lone Emacs user in a group that's hung up on Eclipse. Time and again, code diffs are made larger by imports that have been "organized" or "cleaned up" by Eclipse.
I don't have a strong opinion on the subject of import style in Java, but I do want to minimize our diffs. What can I do?
We use Maven2 for builds; is there a plugin that can help me? Can a piece of Eclipse be abstracted out & turned into a Maven plugin? I currently use ImportScrubber and have encountered a few other stand-alone pieces that do the same thing. What I'm really looking for is a Maven plugin that can integrate with the build.
Barring the above, I'll put an ImportScrubber invocation into my .git/hooks/post-commit.
The Hybridlabs beautifier which is used internally in the openArchitectureWare project (an open source generator framework) is doing what you're looking for. As explained in this blog entry, the beautifier is available as a Google Code project and its documentation describes a maven 2 plugin:
<plugin>
<groupId>org.hybridlabs</groupId>
<artifactId>maven-beautifier-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>beautify-imports</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- Recursively scan for *.java and beautifies imports -->
<inputDirectory>${pom.basedir}/..</inputDirectory>
<!--outputDirectory>${pom.basedir}/..</outputDirectory>
<runBeautifier>true/runBeautifier>
<runJalopy>false</runJalopy-->
</configuration>
</plugin>
There is indeed a mojo in the source tree but it doesn't match the groupId mentioned above (this is a bit confusing) and I've not been able to find the plugin in maven's public repository.
Maybe you'll be more lucky with the version available in AndroMDA plugin repository as documented in this thread (the plugin is indeed present in http://team.andromda.org/maven2/).
The plugin is under
org.apache.maven.plugins.maven-beautifier-plugin.
It can be run with the short form:
mvn beautifier:beautify-imports. It
can also be run as part of a project
pom by adding the plugin declaration
under <build><plugins>:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-beautifier-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<goals>
<goal>beautify-imports</goal>
</goals>
</execution>
</executions>
<configuration>
<inputDirectory>${pom.basedir}/target/src</inputDirectory>
</configuration>
</plugin>
Or contact the project's author (e.g. through twitter or by mail).
I think all of you (Eclipse, Emacs or whatever users) should use something like Jalopy which supports both Eclipse and Maven. This way it becomes irrelevant where the code was modified as long as it has been run through pretty-printer as part of checking code in. Said that - I'm not sure if Jalopy supports organizing imports beyond sorting these up
I have also found an ImportScrubber plugin. Can't as of yet attest to its quality.
Does your shop have code standards for how imports should be organized? If so then you are out of luck. Minimizing diffs is a small sacrifice to make towards incremental code improvement.

How to send out email notification for Maven build

Is there a simple way to send out email notifications in Maven for each build without outside CI tools, just like Ant?
If CI is not an option I would use a simple script wrapper:
mvn install 2>&1 | tee build.log && cat build.log | mail -s 'Maven build output' user#example.com && rm -f build.log
If you do decide to use a CI tool, I would strongly recommend Hudson. The installation page shows how easy it is to run. Continuous integration server sounds pompous and enterprisey, but Hudson is dead-simple.
I'd strongly recommend using a CI tool to manage this for you, I personally like to configure which emails are to be sent on the build to avoid spamming. For example only notify when the build starts failing, or starts working again, not on every failure.
If you're sure this is the right approach, you can use the maven-changes-plugin to send an email on each build. You can customise the mail template with velocity, and bind the execution of the goals to an appropriate phase so it is sent when you want it.
I'd also put the configuration in a profile so it is sent when you want it to be (i.e. when the profile is active).
The configuration looks something like this:
<profiles>
<profile>
<id>notify</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-changes-plugin</artifactId>
<executions>
<execution>
<!--send an email in the install phase,
could be changed depending on your needs-->
<phase>install</phase>
<goals>
<goal>announcement-mail</goal>
</goals>
</execution>
</executions>
<configuration>
<smtpHost>mail.yourhost.com</smtpHost>
<smtpPort implementation="java.lang.Integer">25</smtpPort>
<toAddresses>
<toAddress implementation="java.lang.String">
someones#email.com</toAddress>
<toAddress implementation="java.lang.String">
someoneelse#email.com</toAddress>
</toAddresses>
<!--using a custom velocity template in
src/main/resources/mailTemplate/announcement.vm -->
<template>announcement.vm</template>
<templateDirectory>mailTemplate</templateDirectory>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Though the question is a bit older, it might be possible that someone still needs a different solution: I have created a plugin for just that purpose. Have a look at the plugin's page at github.com.
Multipart-alternative MimeMessages aren't implemented (have a look at the FAQ for the reasons), as well as a decent templating, but as long as you simply want to send a text mail with attachements it should do the trick.
I plan to submit it to mojo.codehaus.org, hence the gId. For now, you have to compile it yourself - sorry for that inconvenience.
There is also a highly customizable Postman mail plugin which gives you options to send test results or even an arbitrary html specifying a source file. Here's a good thread explaining how it should be configured.
I don't use Maven, but I think you can do this with a plugin.

Categories