What are all the Maven constructs that reference JDK compiler version? - maven

I have a massive Java 6 migration planned for Maven projects that are currently using JDK4 and JDK5.
In doing so, i'd like to script as much as possible. One thing I'd like to script is to replace all Maven references to a JDK4 or JDK5 to JDK6.
The question is, what are all the ways a Maven file can reference JDK?
Here are the ones I know of, listed as XPath's:
//plugin/artifactId[.='maven-compiler-plugin']
//maven.compiler.source
//maven.compiler.target
EDIT: Found another one
/project/profiles/profile/activation/jdk
EDIT: User added one
The aspectj-maven-plugin has source and target configuration.
Am I missing any?

Related

Need to control Maven Version Numbers for multiple projects

It's a long story. My current place uses Ant for builds. They create about 20 different foundation class jars that are used in multiple projects. Originally, the projects would check in the particular versions of the various jars they needed and then never updated them. That meant that each application had incompatible jars with other projects and our servers. Hilarity ensued.
To handle this, I immediately brought in a Maven repository, and integrated Ivy into our Ant builds. No more checking in jars. Instead, you fetch the correct version from the Maven repository. Originally, I expected the developers to keep the version numbers in the ivy.xml up to date, but they never did. Instead, the Ivy integration and setup depends upon an external Subversion project. This allowed me to integrate Ivy with minimal changes to the old build.xml files. I added a ivy.version.properties file to that external ivy project and maintain the version numbers of various jars in there. There's a corporate wide version number.
The various projects use the ${corporate.version} property for our foundation jars version numbers. When I update that ivy.version.properties file, all projects get updated with the right version number for our foundation classes. We use <ivy:makepom> to generate a pom.xml for our projects and use this to deploy our jars and wars into our Maven repository.
The result: I no longer have to worry about the developers keeping the version numbers of their projects in sync. I, as the release engineer handle that by updating that one ivy.version.properties file. All projects are in sync.
Now, we're moving to Maven, and I want to be able to do the same thing. I doubt developers will remember to update their pom.xml with the correct version numbers, so I want to read that in from another file, and use that.
There are two issues: One is that Maven first reads in the version number of a project before it executes any goal. No version number in the pom.xml, no version number for the generated jar.
Even if I manage to get by that first step, we have the fact that the pom.xml has no version number in it for foundation classes. When Maven pulls down the pom.xml to get the dependencies, it can't figure out which revision.
Yes, I could put that into a corporate pom.xml and have that as a parent project for all of the other projects. We already have a parent project to help set up various aspect of all projects. I could put a foundation class version number in there. However, that means that the developers now have to update the parent project's version number with each release. If developers can't be trusted to update the version number of their project with each release, what makes you think they'll do that with the parent's version for each release?
I know other people must have run into a similar issue. How do you handle this?
I could have an Ant script that generates the pom.xml from a template pom.xml, but that seems a bit silly.
I was wondering if is it possible for Maven to generate a pom.xml on the fly and then to use that to continue the executing the right goal. For example, I type in mvn package, and Maven will take a template.pom.xml file, fill in the missing version numbers to generate a generated.pom.xml file, then execute mvn package on that generated pom.
Or, is there a better way to solve this issue? Basically, I need to control the version number of our releases across all projects. This way, all projects are using the same version of our foundation classes. Also, I control some other versions of other jars (like log4j) this way. I've done this with Ant and Ivy, and now I want to move to Maven.
I think the best option is to create a pom.xml with all the dependencies to your packages in its and then import it in your developer project paren pom.xml using import
So, in the project parent POM:
<properties>
<corporate.version>...</corporate.version>
<properties>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.mycompany.libs</groupId>
<artifactId>foundation<artifactId>
<version>${corporate.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
...
</dependencies>
</dependencyManagement>
So for new set of foundation libraries, you deploy a new pom.xml with all the versions in it and update the ${corporate.version} in the relevant parent pom.xml file. You can even have when the versions are not yet fixed define a -SNAPSHOT artifact with these version numbers.
for more information, see: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Importing_Dependencies
We actually have the same kind of problem and I know that there is trade-off between "lazy programmers" who never update their poms and the stability aspect: Changing the versions of the foundation jars "suddenly" which may cause unexpected build fails.
If you really want the behaviour you describe, I would put the desired dependencies into a SNAPSHOT pom and use it either as a parent pom or import it as a BOM. In this way, you can change the content and everybody pulls in the new content with the next update.
I've decided that this a stupid idea and should never have been done. It's the developers' responsibility to update their own damn POM and make sure they're pulling the correct version. This is the way it really should be and developers should simply learn to do it (what's the technical term? ...oh yeah) the Correct Way.
I originally implemented this because the company had something like this (which wasn't working) and I had problems getting the developers to do what should be their job. And, the developers liked it because I was now officially responsible when something goes wrong rather than them. It's what you get when you do someone else's job.
I've convinced the company to stop trying to keep all our core jars (the jars used in our other projects) and our releases at the same version number. Instead, every project will have its own versioning. Jars will version only when there's an actual change and not when we force an upgrade to the version. And, the developers must know what versions of the various jars they depend upon.
Use the maven-release-plugin. This plugin can stamp a version number on all pom.xml files. The plugin also understands version control and knows how to tag a maven project for release (or branching).

How to run plugin on maven dependency

I'm setting up a (java) maven project that depends on a library (Jettison, among others) that is in the Maven repo. Jettison, in turn, depends on stax. I need to run a tool (Jar Jar Links) on stax (to change the namespace). How do I alter the rules for a transitive dependency in a maven project? My transitive dependencies are being included in my target folder using the copy-dependencies goal (I assume this is how things are usually done). I assume that this is the point where the plugin would be run on the transitively-generated artifact.
Extra question: I don't need this at this point but how would I go about altering the source in the transitive dependency? I can get the jar of the source with mvn dependency:sources but, from there, I'm not sure what the right approach is.
Victory!
Seems at least two people are even more clueless about Maven than me so let me explain what I'm doing before I report the fix at the bottom of this post (spoiler alert: it looks to be a bug in JarJar).
Android uses Java but its missing a lot of the java core (specifically, javax classes). The Android DEX compiler (which converts .jars to Android .dex files) won't even allow you to compile things in the java.* or javax.* namespace because it'll (usually) break stuff. However, in some (many) cases, there are routines that you might want to include -- specifically because they are used by existing libraries. The most legendary is StAX, which is why Google posted an example of how to include it here in the Dalvik repo's wiki. The example uses JarJar... with ant. Transitive dependencies are not really an issue when you aren't using a repo so they are not addressed in the wiki.
I was able to get JarJar to run on my source with Maven but without changing the namespaces in the dependencies (and transitive dependencies), that's worthless. Hence my question.
I thought that the copy-dependencies plugin might be useful for... copying the dependencies and running a transforming plugin in the process. Copying dependencies is mentioned as a step in the official "Maven in 5 minutes" doc so it seemed like a good start but maybe the the people who wrote the official docs don't know how to use it :-) . Either way, it it didn't help -- there is no simple way I could see to transform the jars as it copies.
Using the verbose spew from Maven, I was able to see that Jar Jar was in fact processing my jars properly... and then throwing out the result. It would have packaged the converted classes from the transitive dependencies in my artifact with the rest of my code but, instead, it "Excluded" them. Jar Jar parameters are basically undocumented and most of the tags aren't even listed in the docs but all of the examples I could find use a section with wild-cards that tell it what classes to hold onto. At least I thought (think?) that's what the section is for. Instead, it seems to randomly throw out stuff. Basically, the section is busted. For example, I had:
<keep>
<pattern>com.example.**</pattern>
</keep>
...thinking that this would keep classes that began with com.example. Wrong. It keeps whatever the hell it wants. I tried a million things in that spot until one worked:
<keep>
<pattern>*.**</pattern>
</keep>
This only keeps the classes I wanted -- the classes it updated and the originals of the ones that it didnt touch. Note that ** doesn't even work. This is version 1.8 of the JarJar plugin (the version most poms Ive found use).
Back to work.

How to easily copy/rename/remove files with Maven (as in Ant)

I am working on a project and using Maven to build it. The project is a quite big Java web application and it is supposed to work with both Mysql and Oracle databases.
The problem is that there are some specific annotations related to either of the two databases in the source code, plus some other differences, so that I am forced to manually comment/uncomment part of the code before building the application for one of the two databases.
Basically what I would like to achieve is to have my build script, maybe via a Maven profile, to automatically switch the source classes before building depending on the database I want my war to work against.
Putting it simply, the idea is to have MyClass.oracle and MyClass.mysql, and depending on my build profile I should move one of the two in the source dir, rename it MyClass and build. This should be done for some packages, classes, and also configuration files.
Is there any way I can achieve it via "pure" Maven? The only solution I came across till now is to use an antrun plugin and reference an Ant build.xml inside of it.
Thank you,
Mattia
A pure maven solution would be to develop your own maven plugin. Depending on your requirements this can be an overkill, however it is not hard at all, you can see how to achieve this here.
This is a limitation of Maven. One of Maven's purposes is to not have a build script. You should simply use the plugins as available, and setup your project the right way, and magically, everything will build!
There is one solution: Use Ant. Well, not to redo your whole project with Ant, but with the antrun plugin, you can run a few Ant tasks at various phases of your Maven build life cycle.
It's been a long, long time since I've used this, so I am not going to try to write a test pom.xml, but I don't remember it being very difficult to use.
Of course, the correct Maven solution is to divide your project up into "common core" code, and then a separate Oracle and MySql client that uses the "common core". By the way, I hope you're not patching source code. Instead, you're using a properties file to do this for you.

specify a maven2 dependency version from the commandline

I'm working a contract that has some build oddities... they're using maven, but the pom file is actually edited by the build script to replace the version number with the jenkins build number, and then that same number is used to replace the version of other internal projects which will be used at build time by this project. I am new to maven, but know enough to know this feels wrong.
I can pass in the version number, but putting the same property in the dependency block doesn't seem to work.
I know the tao of maven is serious business, please understand this is a very short term contract and build system isn't in my statement of work - I just want to get to a place where the source controlled files aren't edited by the simple act of running a build.
You can definitely define a Maven property with a version value, and reference it in the dependency declaration. And, with Maven properties, they can be passed into maven using the "-D" command line option.
What I'm not sure of it whether the timing of how Maven runs will allow this to change the dependency version. I think (so, I'm not 100% certain) that the dependency management will be managed before command-line options are processed.
I'd try defining a maven property with the dependency version in it, and reference the maven property in the dependency declaration appropriately. Then, when running mvn, supply the desired version as a property value. That'd be the most-likely approach.

Maven shipping scripts

I am completely new to Maven and come from an ant world. I am having lots of trouble something that might be really trivial.
I want to have a maven project that is made out of non-code items that I want to ship along my jars. These items are DDL scripts, installer scripts a couple of utility scripts, readmes etc.
I do not want to use "resources" in the corresponding java projects since I do not want them living in the actual product jars. I want them shipped as separate artifacts that just like any other jar.
It is acceptable to bundle them up in a jar or zip, etc.
Is there a way to do this?
Thanks!
Use the build helper plug-in to add additional artifacts to the Maven module.
Check out the answer to the following question
Ok, I found it and it was pretty simple. Just created a project added a simple pom with no plugin pacakging jar and I create the proper dir structure
src/main/resources/...
This builds it into a jar

Resources