How to uglify code only for deployment in maven - maven

I want to uglify my javascript code before deployment on aws. I do not want to uglify the code during development. Do I need two separate pom files or is there a smart way to tell maven about that? I am using the uglifyjs plugin for maven.
Ren

Credit to #Michael for answering this, I will still answer formally in order to close this thread.
Here is what my maven profiles look like, note the activation block at the top, this is here to specify how to use this profile over the default profile, in this case I need to give the extra argument:
$ mvn -Ddeployment
<profiles>
<profile>
<activation>
<property>
<name>deployment</name>
</property>
</activation>
<pluginRepositories>
<pluginRepository>
<id>uglifyjs-maven-plugin</id>
<url>https://raw.github.com/tqh/uglifyjs-maven-plugin/master/repo</url>
</pluginRepository>
</pluginRepositories>
<build>
<plugins>
<plugin>
<groupId>net.tqh.plugins</groupId>
<artifactId>uglifyjs-maven-plugin</artifactId>
<version>1.0</version>
<configuration>
<sourceDirectory>target/snapshot/javascript</sourceDirectory>
<outputDirectory>target/snapshot/javascript</outputDirectory>
</configuration>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>uglify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
... other plugins here ...
</plugin>
</plugins>
</build>
</profile>
</profiles>

Related

How can you use a dependency from the plugin's dependency scope in the maven-antrun-plugin?

We have a profile that uses maven-antrun-plugin to run a downloaded JAR.
Exhibit A: (this works)
We can reference the downloaded JAR using the property ${maven.dependency.com.foobar.target-jar.jar.path} (Can I use the path to a Maven dependency as a property?). But in this solution, the custom dependency and repository information isn't limited to just the scope of the profile.
<project>
...
<repositories>
<repository>
<id>thirdparty</id>
<name>Third Party</name>
<url>
[URL for the repository that holds the target JAR]
</url>
<layout>default</layout>
</repository>
</repositories>
...
<dependencies>
<dependency>
<groupId>com.foobar</groupId>
<artifactId>target-jar</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
...
<profiles>
<profile>
<id>runJARprofile</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<inherited>false</inherited>
<executions>
<execution>
<id>run-jar</id>
<phase>package</phase>
<configuration>
<target name="runJar" fork="true">
<java jar="${maven.dependency.com.foobar.target-jar.jar.path}" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
...
</project>
Exhibit B: (haven't gotten it working)
Here, we moved the dependency and repository information into the profile. Maven downloads the artifact successfully, but we no longer know how to reference it by property.
<project>
...
<profiles>
<profile>
<pluginRepositories>
<repository>
<id>thirdparty</id>
<name>Third Party</name>
<url>
[URL for the repository that holds the target JAR]
</url>
<layout>default</layout>
</repository>
</pluginRepositories>
...
<id>runJARprofile</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<inherited>false</inherited>
<dependencies>
<dependency>
<groupId>com.foobar</groupId>
<artifactId>target-jar</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>run-jar</id>
<phase>package</phase>
<configuration>
<target name="runJar" fork="true">
<java jar="${?????}" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
...
</project>
I crated a POM similar to your Exhibit B here and got the following message during a mvn package -P runJARprofile:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.8:run
(run-jar) on project so-36848518: An Ant BuildException has occured:
Cannot execute a jar in non-forked mode. Please set fork='true'.
[ERROR] around Ant part ...<java jar="${my:test:jar}"/>...
I changed the respective line to:
<java jar="${my:test:jar} fork="true"/>
and:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

mvn release:perform distributionManagement url

I have this configuration in my pom.xml:
<distributionManagement>
<downloadUrl>http://mydomain/downloads/<downloadUrl>
<repository>
<id>Id</id>
<name>Name</name>
<url>scp://ipaddress/downloads/</url>
</repository>
</distributionManagement>
When I do mvn release:perform and navigate to http://mydomain/downloads/, there is a directory hierarchy com/my/application that is my app groupId and, inside that, I have the .apk file (is an Android app).
Is there any way to deploy the apk in http://mydomain/downloads/ instead of http://mydomain/downloads/com/my/application ? I mean, ignore the groupId.
Thanks!
You can't ignore the groupId cause this is the foundation on which a maven repository is based.
If you like to do it in an other way than you shouldn't use deployment of Maven. The solution can be to use a particular plugin like wagon-maven-plugin
Thanks to khmarbaise, I found the solution using wagon plugin:
<build>
...
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
<version>2.8</version>
</extension>
</extensions>
...
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>upload-apk</id>
<phase>deploy</phase>
<goals>
<goal>upload</goal>
</goals>
<configuration>
<fromDir>${project.build.directory}</fromDir>
<includes>${project.build.finalName}.apk</includes>
<url>scp://ipaddress/downloads/${artifactId}</url>
<serverId>downloads</serverId>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Furthermore, I put <serverId> tag beacuse its credentials are stored in settings.xml.

Skip exec-maven-plugin from Command Line Argument in Maven

By default in my project POM, exec-maven-plugin, rpm-maven-plugin will be executed,
which is not required in local compilation/build.
I want to skip these plugin execution by passing Command Line Arguments
I tried below command to skip them like normal plugins, but didn't work though!
mvn install -Dmaven.test.skip=true -Dmaven.exec.skip=true
-Dmaven.rpm.skip=true
This page should tell you that the name of the argument to be passed by cmdline (i.e. the user property) is called skip, which is a poorly chosen name. To fix this do the following:
<properties>
<maven.exec.skip>false</maven.exec.skip> <!-- default -->
</properties>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<skip>${maven.exec.skip}</skip>
</configuration>
</plugin>
Try -Dexec.skip from specification:
http://www.mojohaus.org/exec-maven-plugin/java-mojo.html#skip
Using profiles (as little as possible) and execution phase you may achieve what you want for plugins that do not handle the skip property:
Plugin configuration:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>rpm-maven-plugin</artifactId>
<executions>
<execution>
<phase>${rpmPackagePhase}</phase>
<id>generate-rpm</id>
<goals>
<goal>rpm</goal>
</goals>
</execution>
</executions>
<configuration>
...
</configuration>
</plugin>
Profile configuration:
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<rpmPackagePhase>none</rpmPackagePhase>
</properties>
</profile>
<profile>
<id>rpmPackage</id>
<activation>
<property>
<name>rpm.package</name>
<value>true</value>
</property>
</activation>
<properties>
<rpmPackagePhase>package</rpmPackagePhase>
</properties>
</profile>
</profiles>
Invocation:
mvn package -Drpm.package=true [...]

Maven - skip plugin if property is empty/null

I want to obtain the following behavior: when I specify a value for the property "my.prop", I want the dependency and clean plugins to be executed. If a value is not specified for that property, I want them to be skipped.
I created "my.prop" like this:
<properties>
<my.prop></my.prop>
</properties>
Then I read that profile activation works only for system properties, so I deleted the above and used the surefire plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<systemPropertyVariables>
<my.prop></my.prop>
</systemPropertyVariables>
</configuration>
</plugin>
I tried using profiles, like this:
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<skipDependecyAndCleanPlugins>false</skipDependecyAndCleanPlugins>
</properties>
</profile>
<profile>
<id>skip-dependency-and-clean-plugins</id>
<activation>
<property>
<name>my.prop</name>
<value></value>
<!-- I also tried: <value>null</value> without success.-->
</property>
</activation>
<properties>
<skipDependecyAndCleanPlugins>true</skipDependecyAndCleanPlugins>
</properties>
</profile>
</profiles>
Later, for each plugin I do something like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.9</version>
<configuration>
<skip>${skipDependecyAndCleanPlugins}</skip>
</configuration>
....
</plugin>
But the plugins are still executed...
How can I determine Maven to skip the executions of the plugins when "my.prop" is empty/null?
The simplest solution would be to use the activation in the following form:
<profiles>
<profile>
<activation>
<property>
<name>debug</name>
</property>
</activation>
...
</profile>
</profiles>
The above means you can define any value for debug which means -Ddebug is enough.
An empty value can't be defined a pom file cause <value></value> is equivalent to <value/> which means the same as not defined.
Update:
I would suggest to use a profile and NOT a property. So you can simply define on command line mvn -Pxyz install or leave it.
You can use my.prop property in plugin's configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.9</version>
<configuration>
<skip>${my.prop}</skip>
</configuration>
....
</plugin>
Now when you execute:
mvn ... -Dmy.prop=true
then plugin will be skipped
You were very close. You can achieve what you described by using the !my.prop syntax in profile activation.
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<configuration>
<skip>${skipDependecyAndCleanPlugins}</skip>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>skip-dependency-and-clean-plugins</id>
<activation>
<property>
<name>!my.prop</name>
</property>
</activation>
<properties>
<skipDependecyAndCleanPlugins>true</skipDependecyAndCleanPlugins>
</properties>
</profile>
</profiles>
According to Maven documentation, the skip-dependency-and-clean-plugins profile will be activated when the system property my.prop is not defined at all.
Here is a solution that directly addresses the OP's original request: the ability to skip a plugin's execution if a POM property (not a system property) my.prop is not defined. This solution relies on the Apache Maven Help Plugin. It is a kludge, but given Maven's paucity of expression prowess, this is about the best you're gonna get. At least it relies on a well-known, hopefully-maintained plugin, and should work 100% of the time. Oh, and it may make your head explode. Or make you cry. Or both. You've been warned.
First declare the latest version of the Maven Help Plugin in the <build><pluginManagement> section:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.3.0</version>
</plugin>
Then add this "secret sauce" in the <build><plugins> section, which will check to see if my.prop is defined:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>set-is-skip-true-or-prefixed</id>
<phase>validate</phase>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>is-skip</name>
<value>_${my.prop}</value>
<regex>_\$\{my.prop\}</regex>
<replacement>true</replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
<execution>
<id>set-is-skip</id>
<phase>initialize</phase>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>is-skip</name>
<value>${is-skip}</value>
<regex>_.*</regex>
<replacement>false</replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
</executions>
</plugin>
Now you have a POM property (not a system property) named is-skip, which you can use in any later phase to disable a plugin—provided that plugin has a <skip> or similar option taking a Boolean value. If my.prop is not defined at all, is-skip will be set to true; otherwise is-skip will be set to false.
<plugin>
<groupId>org.example</groupId>
<artifactId>foobar-plugin</artifactId>
<executions>
<execution>
<id>foo</id>
<phase>package</phase>
<goals>
<goal>foo</goal>
</goals>
<configuration>
<skip>${is-skip}</skip>
</configuration>
</execution>
</executions>
</plugin>
There is one caveat: don't define my.prop at all, even to the empty string, or this solution will consider it defined and set is-skip to false. Setting is-skip to true if my.prop is set but empty would require an additional regex evaluation clause above. For my use case I didn't need it, as an empty my.prop isn't valid and I didn't define my.prop at all in the parent POM.
I'll leave it to you to understand how it works (my head exploded already when I was writing it), but I'll be happy to answer any questions.
In step #2 above, be sure and put the two regex evaluations in different phases, such as validate and initialize as used here. The reason is because Maven gets confused if you mix in the same plugins in in the same phase a child POM, and may scramble the execution order. (See MNG-5987.) My kludge of a solution relies on the order of evaluation.

How does maven default life cycle get executed on maven project

I have this very simple question in the context of maven. In the maven world, it says everything about my project is defined in the project object model.
So, when I put <packaging> element inside my project object model to be war etc, then maven will apply appropriate goals to default life cycle of maven.But to make it work, I have to define the project maven-war-plugin inside the build section of my project object model. But when I inspect my pom and super pom, it does not have maven-war-plugin included. I am using maven 3.0.5 and super pom is located inside
\maven-model-builder-3.0.5\org\apache\maven\model
following is the content of the super pom. So I'am confused here from where does it take this plugin if it is not described in the project object model. definition of pom says that everything about my project is defined inside the project object model. Could anybody help me here to understand the concept clearly. Thanks in advance for any help
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- START SNIPPET: superpom -->
<project>
<modelVersion>4.0.0</modelVersion>
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>http://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Central Repository</name>
<url>http://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
<build>
<directory>${project.basedir}/target</directory>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<finalName>${project.artifactId}-${project.version}</finalName>
<testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<scriptSourceDirectory>src/main/scripts</scriptSourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>${project.basedir}/src/test/resources</directory>
</testResource>
</testResources>
<pluginManagement>
<!-- NOTE: These plugins will be removed from future versions of the super POM -->
<!-- They are kept for the moment as they are very unlikely to conflict with lifecycle mappings (MNG-4453) -->
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
</plugin>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<reporting>
<outputDirectory>${project.build.directory}/site</outputDirectory>
</reporting>
<profiles>
<!-- NOTE: The release profile will be removed from future versions of the super POM -->
<profile>
<id>release-profile</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<inherited>true</inherited>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<updateReleaseInfo>true</updateReleaseInfo>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
<!-- END SNIPPET: superpom -->
Take a look at the default-bindings.xml, particularly the definition for <role-hint>war</role-hint>:
<component>
<role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
<role-hint>war</role-hint>
<implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
<configuration>
...
<package>
org.apache.maven.plugins:maven-war-plugin:2.2:war
</package>
This defines what goal will be run for this packaging type's package phase by reference to the war-specific plugin.
This is covered by the Introduction to the Build Lifecycle in Built-in Lifecycle Bindings.

Resources