How to install Grails plugins through Maven pom.xml? - java

I'm building a Grails project with Maven, which is the required way of building at my company.
On my local machine, I have installed a Grails plugin in the usual way grails install-plugin foo. Of course, when the project is built by Maven on the build server, it knows nothing about this plugin.
I've seen that the following can be useful for the case where the plugin is available in the plugins directory of Grails:
<plugin>
<groupId>org.grails</groupId>
<artifactId>grails-maven-plugin</artifactId>
<version>1.1</version>
<extensions>true</extensions>
<executions>
<execution>
<id>create plugins folder</id>
<phase>validate</phase>
<goals>
<goal>install-plugin</goal>
</goals>
<configuration>
<pluginUrl>${env.GRAILS_HOME}/plugins/grails-hibernate-1.1.zip</pluginUrl>
</configuration>
</execution>
</executions>
</plugin>
but suppose the plugin was not on the machine at all? What would the pluginUrl be in the case where Maven or Grails will need to go to the internet to find the plugin?
Edit:
I've found that the pluginName and pluginVersion tags are useful, and I've added the following execution to the grails-maven-plugin:
<execution>
<id>Hibernate plugin</id>
<phase>validate</phase>
<goals>
<goal>install-plugin</goal>
</goals>
<configuration>
<pluginName>hibernate</pluginName>
<pluginVersion>1.3.7</pluginVersion>
</configuration>
</execution>
This almost works. If I check out my code in a new directory, and delete the contents of my plugins directories, Maven is able to build the project, successfully finding all plugin dependencies.
Yet it still doesn't work on the build server. Any ideas?

Try adding this dependency to your pom.xml
<dependency>
<groupId>org.grails.plugins</groupId>
<artifactId>fields</artifactId>
<version>1.3</version>
<type>zip</type>
<scope>runtime</scope>
</dependency>
when you recompile your App maven will download and install the plugin

You need to use Grails Maven plugin, so the pom will get updated with changes to the plugin list. Have a look at Grails documentation describing Maven integration, especially the section on "mavenizing" the project.

Related

How to prevent Maven project from downloading specific dependencies?

I wanted to remove all direct / transitive dependencies using older log4J version, particularly version 1.27.1 from my project.
I have made sure that my project's pom.xml and lib folder does not contain log4J 1.27.1.
However, whenever the project builds into a .war file, there are some other libraries in my project which is still using log4j 1.27.1 resulting in log4j-1.27.1.jar being downloaded into the build for deployment.
Is there any means we can force the Maven project by preventing it from downloading a specific dependency? For example, by adding some
configurations to the pom.xml file?
Edit 1: Understand that one way to do it is to do exclusions in the pom.xml file. But that requires me to explicitly mention all the artifacts . Is there anyway to do it as though I am stating "hey, I don't want to see log4j-1.27.1.jar downloaded in my Maven project at all, be it any artifact is depending on it" ?
Use the enforcer plugin to ban all unsecure log4j versions. Any use will fail your build and tell you where it's being used, allowing you to overwrite the log4j dependency with a secure version or exclude it altogether.
From Gunnar Morling's gist (warning: update the log4j minimum version here to the log4j version with no vulnerabilities reported):
<!-- plug-in configuration to put into your parent POM for avoiding any usages of
outdated log4j2 versions, some of which are subject to the RCE CVE-2021-44228
("Log4Shell"), CVE-2021-45046, and CVE-2021-45105. Make sure to check for the
latest version of log4j2 at
https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>ban-bad-log4j-versions</id>
<phase>validate</phase>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedDependencies>
<excludes>
<exclude>org.apache.logging.log4j:log4j-core:(,2.17.0)</exclude>
</excludes>
</bannedDependencies>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>

Downloading JMeter Official Distribution as part of maven dependency (Not using maven plugi-in)

Integrating JMeter as part of Maven project
Extending the above question, is the possible to do the below steps through maven dependency itself, ideally we don't want to rely on the local installation of JMeter for running the test and don't want to use JMeter Maven Plug-in since we cannot specify which JMeter version we want to use to run the JMeter Script.
The answer mentioned is to use AntRunner but not sure how to do that through maven any pointer will be helpful
My scenario is to,
Download and Unzip the JMeter official distribution as maven dependency
Copy to target folder
JMeterUtils.setJMeterHome("copied-target-folder/bin")
jmeter.run();
You can use AntRunner and the following Ant tasks:
get
unzip
Example:
<get src="url of jmeter"
dest="${build.dir}/${zip}"
usetimestamp="true" ignoreerrors="false"/>
<unzip dest="${build.dir}" src="${build.dir}/${zip}">
The maven-dependency-plugin has a goal called unpack which downloads a dependency (using maven coordinates) and unpacks it on a local directory. You can use that goal to download a given JMeter instance.
The syntax would go like this (not tested, you will have to adjust it):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>unpack</id>
<phase>process-test-classes</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.apache.jmeter</groupId>
<artifactId>jmeter</artifactId>
<version>1.0</version>
<type>zip</type>
<overWrite>false</overWrite>
<outputDirectory>target/jmeter</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
That would fulfill your first step:
Download and Unzip the JMeter official distribution as maven dependency
But I'm not sure there is a full zip version of JMeter published as a Maven dependency. You can unpack the jar files, maybe that's enough. Or maybe you just need to execute those ant steps.
You can execute any ant script (build.xml) using the antrunner plugin. You can find documentation and examples on the Maven AntRun Plugin page.

How to generate separate jar files for application, source, and documentation (for central.sonatype.org)

Sonatype has a repository that I want to deploy a jar file to, and they ask for separate files for application, sources, and javadocs:
Example:
example-application-1.4.7.pom
example-application-1.4.7.jar
example-application-1.4.7-sources.jar
example-application-1.4.7-javadoc.jar
In Scala SBT, I have a command called "package" that generates the jar file for the project, but that only generates "example-application-1.4.7.jar".
Question: What should I do to generate the other two jar files?
In Maven, in order to get the additional -sources and -javadoc artifacts, add to your POM file the following:
<build>
<plugins>
<!-- additional plugin configurations, if any.. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Note the snippet above:
We are invoking the Maven Source Plugin to create an additional jar files for sources
We are invoking the Maven Javadoc Plugin to create an additional jar files for javadoc
Executing
mvn clean package
You will find these two additional jars in the target folder.
The .pom file instead is generated during the install phase, but it is not placed under the target folder. Basically, it is a copy of your pom.xml file, with a different extension and used by Maven during the dependency mediation process to check which transitive dependencies are required by the concerned artifact.
Executing
mvn clean install
Maven will install the artifact in your local cache (in your machine), under path_to_cache/.m2/repository/your_groupId/your_artifactId/your_version/. In this folder, you will also find the .pom file, which normally you don't need to distribute (it is created automatically by Maven).
Further note: you probably don't want to generate these additional jar files at each and every build, so to speed up normal builds and have them only on demand, you could wrap the snippet above in a Maven profile.
You can achieve this by removing the snippet above from your build section and add a further section at the end of your pom:
<profiles>
<profile>
<id>prepare-distribution</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
So that normal builds would not create these jars anymore, but when executing the following:
mvn clean install -Pprepare-distribution
You would instead get them back. the -P option is actually activating on demand the profile defined with the id prepare-distribution.
With Maven 3 a default profile already comes as part of the super pom which perform exactly the same actions (sources and javadoc artifact), hence no need to add anything to your existing project. Simply run:
mvn clean install -Prelease-profile
Or, to activate it via a property
mvn clean install -DperformRelease=true
However, as also specified in the super pom, this profile may be removed in future releases (although there since first Maven 3 version till version 3.3.9 so far)
NOTE: The release profile will be removed from future versions of the super POM
The main reason behind this warning is most probably to push for the usage of the Maven Release Plugin, which indirectly makes use of this profile via the useReleaseProfile option of the release:perform goal.
As highlighted by comments, if you are not familiar with maven (especially via console) I would definitely recommend to
Go through the official Maven in 5 minutes documentation for a quick but worthy look.
Play with Maven from the command line, is there where Maven gives you its best. IDE integrations are great, but command line is the real turning point.
Then play with the POM customization above, to get familiar with some concepts and behaviors, first directly as part of your default build, then moved to a profile.
Then, and only then, move to the Maven Release Plugin usage. I recommend it as last step because you would already have acquired more confidence and understanding and see it as less magic and more reasonable approach.

maven 3.3 support for Websphere 8.5.5 - pom.xml

I could not find a way to deploy my war file in websphere 8.5.5 using maven's pom.xml.
I see there is a plugin called was6-maven-plugin-1.2.1. and it can support WAS 6+, 7+, 8+ as well it seems.
But i could not deploy a war file using this plugin. It throws the following error.
[ERROR] Failed to execute goal org.codehaus.mojo:was6-maven-plugin:1.2.1:installApp (default-cli) on project TEST: Bad archive: C:\test.war -> [Help 1]
Please comment on...
My pom.xml configuration FYR:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>was6-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>integration-test</id>
<phase>integration-test</phase>
<goals>
<goal>installApp</goal>
</goals>
</execution>
</executions>
<configuration>
<wasHome>C:\Program Files (x86)\IBM\WebSphere\AppServer</wasHome>
<host>127.0.0.1</host>
<server>server1</server>
<node>localhostNode01</node>
<virtualHost>default_host</virtualHost>
<verbose>true</verbose>
<conntype>SOAP</conntype>
<port>8880</port>
<earFile>test.war</earFile>
<verbose>true</verbose>
<updateExisting>true</updateExisting>
<applicationName>${project.build.finalName}</applicationName>
</configuration>
</plugin>
For developing project for WebSphere using Maven, follow this document Setting up your environment for Maven to configure environment.
Especially for WAS 8.5.5 you should use the following entry in pom.xml:
<dependency>
<groupId>com.ibm.tools.target</groupId>
<artifactId>was</artifactId>
<version>8.5.5</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
For this POM target, you are required to use launch configuration scripts that copy runtime libraries to the local Maven repository.
See the Configuring dependency POM files that emulate the classpath of specific WebSphere runtime environments for detailed instructions how to copy these libraries.

How to create runnable jar with dependencies in extra folder on mutimodule project?

I have a common library that is shared among different project. As the library is constantly extended (at least for now), it should just be picked up from eclipse workspace during build.
I'm trying to use the maven-dependency-plugin to copy all dependencies in a /lib folder next to the runnable jar. But it does not work:
<dependencies>
<!-- A jar that is opened as project in workspace, not installed into maven repo, and not a submodule. It should just be picked up and added as jar during package. -->
<dependency>
<groupId>my.domain</groupId>
<artifactId>project-commons</artifactId>
</dependency>
</dependencies>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib/</outputDirectory>
<overWriteReleases>true</overWriteReleases>
</configuration>
</execution>
</executions>
</plugin>
[ERROR] Failed to execute goal
org.apache.maven.plugins:maven-dependency-plugin:2.8:copy-dependencies
(copy-dependencies) on project mydomain: Artifact has not been
packaged yet. When used on reactor artifact, copy should be executed
after packaging: see MDEP-187. -> [Help 1]
The error ocures when maven tries to copy the commons project that is open in the workspace. Did I miss anything?
I ran into this problem myself today, downloading the latest version of CTAKES (3.2) that integrates YTEX which would build on the command line but not in Eclipse. The error is a result of apparently a known issue with the plugin (https://jira.codehaus.org/browse/MDEP-187).
I eventually fixed it (and I think this will fix your problem) by changing the phase from package to prepare-package.
package
to
prepare-package
Try that and see if it works for you.

Categories