Organize imports with Maven2, Eclipse-style? - java

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.

Related

Why sign a project's artifacts with GnuPG using Maven-GPG-Plugin?

I have two questions to ask;
The first is that I am needing to know what the importance is of signing a java project's artifacts with "GnuPG".
My current situation is that I am looking into releasing my first public java project. I am using Maven to build and manage the project, and came across the "Maven-GPG-Plugin". The documentation on the plugin is extremely vague and does not describe why one should sign artifacts with "GnuPG". I have no experience with GnuPG/Maven-GPG, so I am wondering what the benefit is of using this maven plugin?
The second question I have is how would I go about using this plugin on my java project in Eclipse?
Would just adding the following to my pom.xml sign the project for me when I build it?
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
If not, how would I go about properly signing the project with maven in Eclipse?
Thank you!
I have no experience in actually using GnuPG with Maven (I have never released Maven-plugins), thus I'll limit my answer to the first part of your question.
The documentation on the plugin is extremely vague and does not describe why one should sign artifacts with "GnuPG". I have no experience with GnuPG/Maven-GPG, so I am wondering what the benefit is of using this maven plugin?
Simple hash sums that can only be used to realize accidental transmission problems like bit flips. Unlike those, GnuPG issues cryptographic signatures, which also are capable of recognizing transmission issues, but additionally enables you to verify the author of the signed data.
Without cryptographic signatures, there is no way to know whether the code/program you're downloading and executing is actually the one you're expecting. Missing or unverified cryptographic signatures again and again result in downloads with backdoors, just recently Linux Mint had such an issue.
Cryptographic signatures do not mean the code is correct and has no (security) issues, but at least know you have the same code the author published, which reduces chances of backdoors significantly.

Log statements in pom.xml or Tracking flow of Maven

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.

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.

Creating a self-contained source release with Maven

Up until now we used Ant in my company. Whenever we wanted to send the application to the client we run a special Ant script that packaged all our source code with all jar libraries and Ant itself along with a simple batch file.
Then the client could put the files on a computer with no network access at all (and not even Ant) and run the batch file. As long as the computer had a valid JDK the batch script would compile all the code using the jars and create a WAR/EAR that would finally be deployed by the client on the application server.
Lately we migrated to Maven 2. But I haven't found a way to do the same thing. I have seen the Maven assembly plugin but this just creates source distributions or binary ones. Our scenario is actually a mix since it contains our source code but binary jars of the libraries we use (e.g. Spring, Hibernate)
So is it possible to create with Maven a self-contained assembly/release/package that one can run in a computer with no network access at all??? That means that all libraries should be contained inside.
Extra bonus if Maven itself is contained inside as well, but this is not a strict requirement. The final package should be easily compiled by just one command (easy for a system administrator to perform).
I was thinking of writing my own Maven plugin for this but I suspect that somebody has already encountered this.
From your dev environment, if you include the following under build plugins
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
and invoke mvn assembly:assembly, you would get yourApp-version-with-dependencies.jar in the target folder. This is a self-sufficient jar, and with a Main-class MANIFEST.MF entry, anybody can double click and run the application.
You might try this approach:
Use mvn ant:ant to create ant build
scripts from a maven project
Make sure ant is a project dependency
Use the assembly to build an ant
system
or plan b:
Use mvn ant:ant to create ant build
scripts from a maven project
Make sure ant is a project dependency
Write a "bootstrap class" to call Ant and run the build
Use appassembler to build a
scripted build and install environment
In plan b, you'd write scripts to set up a source tree someplace from the packaged source jars, and then use the appassembler build bat or sh scripts to call the bootstrap and build via ant. Your bootstrap can do anything you need to do before or after the build.
Hope this helps.
Perhaps an answer that I submitted for a similar question could be of some assistance. See Can maven collect all the dependant jars for a project to help with application deployment? The one piece missing is how to include the source code in the assembly. I have to imagine that there is some way to manage that with the assembly plugin. This also doesn't address the inclusion of Maven in the distribution.
What was the reason for moving from Ant to Maven? It sounds like you had everything worked out well with the Ant solution, so what is Maven buying you here?
If it is just dependency management, there are techniques for leveraging Maven from Ant that give you the best of both worlds.
the source plugin will give you a jar containing the source of a probject "source:jar". you could then use the assembly plugin to combine the source jars from your internal projects (using the sources to reference these source jars) and the binary jars from the external projects into one distribution.
however, as for turning this into a compilable unit, i have no suggestions. you could certainly bundle maven, but you'd need to create a bundle containing all the plugins you need to build your project! i don't know of any existing tool to do that.
This is how I do it... on the build part of the pom add in this:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
And then on the profiles section add this bit in:
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
And when I do a maven install it builds the jar and also checks in a jar of the source.

Categories