I have just installed maven on an new ubuntu system, which includes the maven-compiler-plugin. I have a java project that was previously building fine, defaulting to a javac source and target of 5 (jdk 1.5). However, the project is now trying to compile using jdk1.3 on the new system. Is there an easy way to configure the system to use >=jdk5 ?
Here's some of the configuration details of the system:
$ java -version
java version "1.6.0_45"
$ dpkg -s maven
Package: maven
Status: install ok installed
Priority: optional
Section: java
Installed-Size: 1489
Maintainer: Ubuntu Developers <ubuntu-devel-discuss#lists.ubuntu.com>
Architecture: all
Version: 3.0.4-2
$ dpkg -s libmaven-compiler-plugin-java
Package: libmaven-compiler-plugin-java
Status: install ok installed
Priority: optional
Section: java
Installed-Size: 75
Maintainer: Ubuntu Developers <ubuntu-devel-discuss#lists.ubuntu.com>
Architecture: all
Source: maven-compiler-plugin
Version: 2.0.2-6
I've checked the maven-compiler-plugin-2.0.2.pom file, and plexus-compiler-javac.originalVersion and others are set to 1.5.3.
I know I can set this on a per-project basis by including a source/target tag in a plugin context, but I'd like to configure maven-compiler to default to jdk5 or higher without having to do this across a large number of projects.
how can i do this?
In your pom specify the following to set the compiler to JDK5:
<properties>
<maven.compiler.source>1.5</maven.compiler.source>
<maven.compiler.target>1.5</maven.compiler.target>
</properties>
i.e.
<project>
<properties>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
...
</project>
I specify mine prior to the dependencies, although so long as its part of the project element you should be able to place it anywhere inside the pom.
I ran into a similar issue with Maven previously, this fixed it for me. Essentially what this does is set the -source and -target flags to the value specified and passes it to the compiler. Newer plugins default to 1.5.
In order to use the default approach without specifying the properties, you will need to be running a later version of Maven.
I suppose you could also set up a template via your IDE to include this in all new pom files. Of course the actual implementation would depend upon your IDE...
See The apache maven compiler plugin documentation as well as Setting the source and compiler examples for more details.
I tried the maven-compiler-plugin approach and it proved cumbersome as there are plugins like maven-surefire-plugin and maven-cobertura-plugin which still fail due to incompatibility issues.
The better approach was to use maven-toolchain-plugin.
Step 1
Create /.m2/toolchains.xml
<?xml version="1.0" encoding="UTF8"?>
<toolchains>
<!-- JDK toolchains -->
<toolchain>
<type>jdk</type>
<provides>
<version>1.8</version>
<vendor>sun</vendor>
</provides>
<configuration>
<jdkHome>/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home</jdkHome>
</configuration>
</toolchain>
<toolchain>
<type>jdk</type>
<provides>
<version>1.7</version>
<vendor>sun</vendor>
</provides>
<configuration>
<jdkHome>/Library/Java/JavaVirtualMachines/jdk1.7.0_67.jdk/Contents/Home</jdkHome>
</configuration>
</toolchain>
<toolchain>
<type>jdk</type>
<provides>
<version>1.6</version>
<vendor>apple</vendor>
</provides>
<configuration>
<jdkHome>/Library/Java/JavaVirtualMachines/1.6.0_65-b14-462.jdk/Contents/Home</jdkHome>
</configuration>
</toolchain>
<!-- other toolchains -->
<!--
<toolchain>
<type>netbeans</type>
<provides>
<version>5.5</version>
</provides>
<configuration>
<installDir>/path/to/netbeans/5.5</installDir>
</configuration>
</toolchain>
-->
Step 2
Add maven-toolchain-plugin to plugins section in your project pom.xml.
*If using maven 3, ensure this goes into pluginManagement as well *
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-toolchains-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<goals>
<goal>toolchain</goal>
</goals>
</execution>
</executions>
<configuration>
<toolchains>
<jdk>
<version>1.7</version>
<vendor>sun</vendor>
</jdk>
</toolchains>
</configuration>
</plugin>
Voila all your other plugins pick up the right JDK. Hope it helps. I spent almost half day on this exact issue today.
Default value for source and target was 1.3 in older versions of maven-compiler plugin (like 2.0.2-6).
Use at least a 3.0 version of the Maven compiler plugin to get this back to the original behaviour, or just configure that plugin to get source and target to appropriate values.
I used following settings to set maven default java compiler version.
first, modify maven settings.xml:
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
second, in eclipse preferences, make the java home point to jdk home
Suggestion: Use the latest maven compiler plugin.
In order to change the defaults, you should set source and target.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
More Info: maven-compiler-plugin
The simplest solution to such things is using an up-to-date version of Maven (3.1.1) and in particular create a parent pom.xml file for all your projects where you define the configuration and version of your maven-compiler-plugin via pluginManagement or better all of your plugins.
Based on Chinto's answer I got it running on my windows machine with this:
<?xml version="1.0" encoding="UTF8"?>
<toolchains>
<!-- JDK toolchains -->
<toolchain>
<type>jdk</type>
<provides>
<version>1.8</version>
<vendor>openjdk</vendor>
</provides>
<configuration>
<jdkHome>C:\path\to\openJDK1.8.0</jdkHome>
</configuration>
</toolchain>
</toolchains>
Related
I am working on a project where we want to use the plexus-compiler-eclipse plugin during a Jenkins pipeline to check for increases in the number of warnings generated by the Eclipse compiler. We still want to use the javac compiler for the normal build and test stage, so I am trying to create a maven profile we can run during the warnings stage that utilizes the Eclipse compiler.
When I run the Eclipse compiler over our code, I get a compile error about JAXB dependencies being missing. I know this is due to our move to Java 11 from Java 1.8, but we do not get this error when building with the javac compiler. I have tried adding the jakarta.xml.bind-api dependency to the maven-compiler-plugin, but this does not help, nor does adding the org.glassfish.jaxb dependency or the javax.xml.bind:jaxb-api dependency.
I cannot share the full pom because this project is proprietary, but the profile I'm building looks like this:
<profile>
<id>eclipse-compile</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1></version>
<configuration>
<compilerId>eclipse</compilerId>
<source>${java.version}</source>
<target>${java.version}</target>
<compilerArguments>
<properties>${project.basedir}/.settings/org.eclipse.jdt.core.prefs</properties>
</compilerArguments>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-eclipse</artifactId>
<version>2.8.8</version>
</dependency>
<dependency>
<groupId>org.eclipse.jdt</groupId>
<artifactId>ecj</artifactId>
<version>3.25.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
I was putting the various JAXB dependencies I tried in the <dependencies> section under the org.eclipse.jdt entry.
Anyone else encounter this or know what to do about it?
The issue stemmed from the Maven build running in Java 11 but our normal compile stage forking to a Java 1.8 executable. Because the Plexus compiler cannot fork to a new environment, there was not a way for it to access the Java EE dependencies. We just need to update our entire project to be compatible with Java 11 at compile-time.
I used the org.openjfx:javafx-archetype-simple Maven archetype to start my first JavaFX project.
The resulting POM:
<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>
<groupId>com.example.invoicing</groupId>
<artifactId>Invoicer</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>14</maven.compiler.source>
<maven.compiler.target>14</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>14</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>14</release> 🡄 ???
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.4</version>
<configuration>
<mainClass>com.example.invoicing.App</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
➥ What is the purpose of the <release>14</release> line in <configuration> for the plugin <artifactId>maven-compiler-plugin</artifactId>?
I found this documentation for the Maven Compiler Plugin, Compiling Your Java Sources. But it only mentions <!-- put your configurations here -->. So I do not know anything about specific configuration options here.
Is <release>14</release> the version of Java being used to compile? Is it the version of OpenJFX? Something else?
I tried using 28 arbitrarily. Doing a Maven > install threw this error with an unhelpful error message with no clue as to a release of what product:
Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project Invoicer: Fatal error compiling
The release flag is equivalent to specifying the source and target of the same value for the compiler plugin. It supports the -release argument for the Java compiler since Java-9.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>14</source>
<target>14</target>
</configuration>
</plugin>
Note: For the same reason, you can get rid of the redundant properties declared as
<maven.compiler.source>14</maven.compiler.source>
<maven.compiler.target>14</maven.compiler.target>
Further: What is the --release flag in the Java 9 compiler? | The -release flag in javac was introduced to Compile for Older Platform Versions.
To complete the answer over the part where you've tried the version value as 28. While using Maven version -
Apache Maven 3.6.1 (d66c9c0b3152b2e69ee9bac180bb8fcc8e6af555; 2019-04-05T00:30:29+05:30)
The error message reads very clearly what it should (if you could share the complete logs in the question)
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project forty-bits-of-java:
Fatal error compiling: error: release version 28 not supported
The compile options page states that this ends up as the -release argument passed to javac.
And about --release release:
Compiles against the public, supported and documented API for a specific VM version. Supported release targets are 6, 7, 8, and 9.
As I understand it, Java 9 introduced a feature that helps developers build on a recent compiler, targeting an older runtime, but at the same time preventing the old problem that let code compile with references to newer APIs while being targeted at old runtimes.
See: JEP 247: Compile for Older Platform Versions
Ex: If you use Java 8 to compile code that uses new Java 8 APIs (such as Collection.stream()), with a target of 1.7, this code compiles but will fail at runtime on Java 7 with a NoSuchMethodError.
On JDK 9, if you use --release 1.7, the compiler will know that Collection.stream() can't be correctly targeted at Java 7 and will fail the build.
tl;dr
In your POM, replace the two tags source & target as seen here:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--The following `source` and `target` tags are now replaced by `release` seen further down below.-->
<!--<maven.compiler.source>14</maven.compiler.source>-->
<!--<maven.compiler.target>14</maven.compiler.target>-->
</properties>
…with the new release tag, placed further down in POM:
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
…
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<!--Enable Java language preview features. Specify Java version.-->
<!--This `release` tag replaced the pair of `source` and `target` tags seen commented-out near top of this POM.-->
<release>14</release>
</configuration>
</plugin>
…
…to tell the Java compiler the version of Java on which you intend to deploy. This tag passes a release flag to the Java compiler. The compiler errors out any of your code trying to use an API added to later versions of Java.
See another Question: What is the --release flag in the Java 9 compiler?
Details
Both Answers by Naman and by ernest_k are correct and important. But I need to write this Answer to combine them and show the direct solution.
Problem
The issue is that JEP 247: Compile for Older Platform Versions added a feature in Java 9 for a new compiler flag -release to replace the combination of older -source, -target, and -bootclasspath flags. This plugs a hole that plagued programmers trying to work on the latest compiler while writing code limited to making API calls of an earlier version of Java.
For example, I may be writing on my Mac using Java 12 yet deploying to a server running Java 8. I want the compiler to stop me from accidentally using features that arrived in later versions of Java. Otherwise, my app will succeed at compile-time yet fail at run-time when those features are unavailable on the older JVM.
To quote the JEP:
Summary
Enhance javac so that it can compile Java programs to run on selected older versions of the platform.
Motivation
javac provides two command line options, -source and -target, which can be used to select the version of the Java language accepted by the compiler and the version of the class files it produces, respectively. By default, however, javac compiles against the most-recent version of the platform APIs. The compiled program can therefore accidentally use APIs only available in the current version of the platform. Such programs cannot run on older versions of the platform, regardless of the values passed to the -source and -target options. This is a long-term usability pain point, since users expect that by using these options they'll get class files that can run on the the platform version specified by -target.
Solution
In a Maven-driven project, we pass those flags to the Java compiler by setting tags on our Maven POM file.
In your Maven POM file’s tag hierarchy of:
<project> …
<build> …
<pluginManagement> …
<plugins> …
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
…nest the following tag hierarchy, within which we specify our desired deployment version of Java.
<configuration>
<release>14</release>
By the way, if using a version of Java offering "preview" features, we can nest a further tag and value if we wish to enable those preview features.
<compilerArgs>--enable-preview</compilerArgs>
The old-school settings replaced by the new release tag were a pair of tags, source and target. These two could be set in Maven to be passed along to the Java compiler. So if you add the release tag seen above, check to see if your POM has this pair of tags. If found, delete them.
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>14</maven.compiler.source> 🡄 Delete if using `release` tag.
<maven.compiler.target>14</maven.compiler.target> 🡄 Delete if using `release` tag.
</properties>
Example POM file
Here is a complete example POM file for Maven 3.6.3, for a basic Java project.
We are using all the latest versions of various plugins and dependencies. This example uses Java 15 with preview features such as Records enabled.
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>work.basil.demo</groupId>
<artifactId>Demo5</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Demo5</name>
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--The following `source` and `target` tags are now replaced by `release` seen further down below.-->
<!--<maven.compiler.source>15</maven.compiler.source>-->
<!--<maven.compiler.target>15</maven.compiler.target>-->
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.7.0-M1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<!--Enable Java language preview features. Specify Java version.-->
<!--This `release` tag replaced the pair of `source` and `target` tags seen commented-out near top of this POM.-->
<release>15</release>
<compilerArgs>
--enable-preview
</compilerArgs>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>3.0.0-M1</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.0.0-M1</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.8.2</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.1.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
JavaFX
You mentioned JavaFX in your Question. Note that this discussion applies to any and all Maven-driven Java projects. This includes JavaFX projects as well as Jakarta Servlets, console apps, and so on. Nothing here is specific to JavaFX.
I have a project that consist of 3 different libraries. When I run install script it takes all libraries from repo and run mvn clean install on them. But this version of library already installed in repo. Is there a way to skip install phase if version in pom.xml equal version in my local repo.
I know that I can use local repo and just set dependencies. But my boss want that our project can build only with public repos and without any our repos.
You can bypass like this
-Dmaven.install.skip=true
<profiles>
<profile>
<id>skipInstall</id>
<activation>
<property>
<name>maven.install.skip</name>
<value>true</value>
</property>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>default-install</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
Last week Olivier Lamy patched this jira.
MINSTALL-73
Most maven plugins can be skipped by specifying something like:
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>X.Y</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
you can also set up build profiles to set properties and use that to determine the value. for example, running the command: mvn -Pexample would select the "example" profile. The POM would then contain:
...
<properties>
<skip.install>false</skip.install>
...
</properties>
...
<profile>
<id>example</id>
<properties>
<skip.install>false</skip.install>
</properties>
</profile>
...
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>X.Y</version>
<configuration>
<skip>${skip.install}</skip>
</configuration>
</plugin>
...
Using these POM additions, the default behavior for the install plugin will be to perform its default goal, but if the example profile is selected, then the install plugin will skip its goal.
Using what I learned from the other answers, this was the cleanest result for me.
In my super pom I added a pluginManagement/plugin to disable default-install and default-test phases when the property deployOnly is set.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>default-install</id>
<configuration>
<skip>${deployOnly}</skip>
</configuration>
</execution>
<execution>
<id>default-test</id>
<configuration>
<skip>${deployOnly}</skip>
</configuration>
</execution>
</executions>
</plugin>
So on the command line, I can disable install and test phases by adding -DdeployOnly.
mvn clean install #build and test everything
mvn deploy -DdeployOnly #just deploy it
I know that I can use local repo and just set dependencies. But my boss want that our project can build only with public repos and without any our repos.
Are you sure you understood correctly what you boss meant? I interpret the above as "don't install third party libraries in your local repository, use only libraries available in public repositories". This is different from "don't use your local repository" which is basically impossible, that's just not how maven works. I'd try to clarify this point.
Apart from that, I don't get the question which is very confusing (what repo are you talking about? What is the install script doing? Why do you call clean install on libraries? etc).
Extending the other answers, from the future.
Maven plugins have a surprisingly high freedom, how do they run. If they want, they can ignore/override the typical pom.xml settings. Furthermore, also the <configuration><skip>true</skip></configuration> is only a convention, nothing obligates a plugin to follow it, except that most of them is developed so.
My experiments with the recent problem show, that both #Cemo's and #MiloshBoroyevich solution should be utilized, also the plugin requires both to really let us in peace. More concretely, the only working configuration by me was this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>default-install</id>
<phase>none</phase>
</execution>
</executions>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
One of your options is to put the deployment to another module. I.e. have one pom.xml build the artifact and install it to the local repo, and another pom.xml to deploy it. This separation is quite common in larger projects, where the testsuite is sometimes a separate module or even a project, the packaging happens in several stages, etc.
- pom.xml - myProject-root - type=pom
- pom.xml - myProject-artifact - type=jar
- pom.xml - myProject-deploy - type=pom, does the deployment, skips it's own `install` goal
I am trying to implement semantic versioning in our project. I tested maven semver plugin but that didn't help me so please don't ask me why. I finally ended up using maven groovy. It works like a charm, however, when I install or deploy the maven project the version in repository is the variable name.
This is despite the fact that all the artefacts and jar files are packaged with correct version.
So please look at my pom.xml
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mytest.test</groupId>
<artifactId>test-tag</artifactId>
<version>${revision}</version>
<description>Test</description>
<properties>
<ChangeType>TO_BE_SET</ChangeType>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<providerSelection>2.0</providerSelection>
<properties>
<script>git describe --abbrev=0 --tags</script>
</properties>
<source>
def tagIt = 'git tag -a vXXXX -m "Auto tagged"'
def changeType = project.properties.ChangeType
def command = project.properties.script
def process = command.execute()
process.waitFor()
def describe = process.in.text.trim()
println "Setting revision to: " + describe
if(!describe.startsWith("v")) {
describe = "1.0.1"
} else {
describe = describe.substring(1)
}
project.properties.setProperty('revision', describe)
</source>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>default-testResources</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>default-test</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
the version is ${revision} a variable name that is being set in groovy script. What groovy code does is getting the last tag from GIT and and then set it to the property 'revision'.
The final jar file has the correct version extracted but when installed into repository, the folder name and jar name are like:
m2\repository\com\mytest\test\test-tag\${revision}\test-tag-${revision}.jar
I tried to default 'revision' to a value using:
<properties>
<revision>1.0.1</revision>
</properties>
but then groovy code setting the value has no effect.
I also tried different phase for the maven groovy plugin, no luck. Have I missed anything? Can anyone please help me on this?
I'd like to mention that as vatbub and StefanHeimberg mentioned I can use versions:set to set the version but this requires me to do an extra commit to GIT which I am trying to avoid, wondering if I can achieve this by writing a maven plugin instead?
With Maven you can set the version at build time with
mvn versions:set -DnewVersion=${bamboo.inject.version}
as #vatbub already commented in your question.
In addition to this i wrote a Shell script that can be used in build pipeline to generate the version according to the maven project version and add the build number from the build server.
https://gist.github.com/StefanHeimberg/c19d7665e8df087845c036fe8b88c4f2
The Script reads the maven project version, add a the build number and writes a text file with all the new numbers that can be used.
The next step is to inject this text file in the Build Pipeline and call the versions plugin as stated above
pom.xml:
something like
<project>
<groupId>ch.stefanheimberg.example</groupId>
<artifactId>your-awesome-app</artifactId>
<version>5.1.2-SNAPSHOT</version>
</project>
or
<project>
<groupId>ch.stefanheimberg.example</groupId>
<artifactId>your-awesome-app</artifactId>
<version>5.1-SNAPSHOT</version>
</project>
Step 1:
./generate_version_txt.sh ${bamboo.buildNumber}
Step 2:
Inject generated version.txt in the build system that all the properties can be used in all tasks / plugins, etc...
In my case Bamboo CI ready the version.txt file and declares the content of the file as environment variables under the bamboo.inject. prefix.
For example ${bamboo.inject.long_version}
Step 3:
Update Maven Project version
mvn versions:set -DnewVersion=${bamboo.inject.version}
Step 4:
Run Maven Build
mvn clean verify
Step 5:
Run Docker build
for example use it also as docker tag version. etc...
docker build --build-arg version=${bamboo.inject.version} --tag your-awesome-app:${bamboo.inject.version} .
Example Dockerfile:
FROM jboss/wildlfy
ARG version
ADD target/your-awesome-app-${version}.war /opt/jboss/wildfly/standalone/deployments/
I know that can be a problem / not possible in your case with the groovy script. but perhaps it is an other view at your problem. and possibly also another solution for it.
(sorry for my english. but i hope it is understandable what i mean)
I ran into a similar problem and ended up using the maven flatten plugin to ensure that all variables are removed from the POMs before being deployed. This remove all references to the string ${revision} and replace by the actual value at build time, without interfering with the original POMs.
Okay, I'm pretty sure I'm missing a fundamental point here, but I'm stumped. I'm playing around with maven to get main and test sources to compile at different levels (1.7 & 1.8) - found a lot of posts but haven't gotten it working yet, so back to basics with an empty project.
So first, I want to try off by having maven not compile my code by setting the maven-compiler-plugin to source level 1.7 and using 1.8 code (stream).
This is my test code:
public static void main(String[] args) {
new ArrayList<>().stream();
}
And this is my pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
IntellIJ is not having any of it and complains about the source level as expected until I change it. Now, why is it that when running maven from the command line...
$ mvn compile
or
$ mvn install
Maven won't complain?
maven version 3.5.0
java version 1.8.0_131
There's nothing in the syntax that won't work in Java 7. However, the stream() method was only introduced in JDK 8. This code compiles because you happen to be using JDK 8. If you switch to an older JDK, your code will break.
One way to prevent such potential bugs is to use the Animal Sniffer Maven Plugin which allows you to check that you aren't using parts of the JDK that are too new, even when compiling against the aforementioned new JDK:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>animal-sniffer-maven-plugin</artifactId>
<version>1.15</version>
<configuration>
<signature>
<groupId>org.codehaus.mojo.signature</groupId>
<artifactId>java17</artifactId>
<version>1.0</version>
</signature>
</configuration>
<executions>
<execution>
<id>animal-sniffer</id>
<phase>compile</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>