This seems like it should be a simple question, but I can't seem to find any information about it. When a maven plugin has a required dependency, is it possible to tell it to use an artifact defined elsewhere in the section of the pom?
As an example, I'm trying to add the 'maven-processor-plugin' to my build. That plugin has a dependency on 'hibernate-jpamodelgen'. I'm working with wildfly, so I already have that jar as a dependency of the project. I want to ensure I am using the same version for both. Is what I'm trying to do even possible?
Some code snippets:
<dependencies>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-ejb3</artifactId>
<version>${version.server.bom}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArguments>
<processor>-proc:none</processor>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>4.5</version>
<executions>
<execution>
<id>process</id>
<goals>
<goal>process</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<outputDirectory>${project.build.directory}/generated-sources/java/jpametamodel</outputDirectory>
<processors>
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
</processors>
<overwrite>true</overwrite>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<!-- How do I handle this without hard coding the version? -->
<!-- <version>???</version> -->
</dependency>
</dependencies>
</plugin>
</build>
Define a property like <hibernate-jpamodelgen.version> in the <properties> section of the POM.
Then use that property for the version like ${hibernate-jpamodelgen.version}.
Related
We can use the maven-enforcer-plugin to prevent duplicate dependencies with difference versions.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>no-duplicate-dependencies</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<banDuplicatePomDependencyVersions/>
</rules>
</configuration>
</execution>
</executions>
</plugin>
What about for duplicate dependency declarations of the same version?
Consider that we are building a multi-module project.
Say we start with project Foo.
Foo pom.xml
<dependencies>
<dependency>
<groupId>someGroup</groupId>
<artifactId>someArtifact</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
Later, we introduce the module Bar, which also depends on the same version someArtifact.
Bar pom.xml:
<dependencies>
<dependency>
<groupId>someGroup</groupId>
<artifactId>someArtifact</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
And Foo depends on Bar, so we update the POM.
Foo pom.xml
<dependencies>
<dependency>
<groupId>myGroup</groupId>
<artifactId>bar</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>someGroup</groupId>
<artifactId>someArtifact</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
As in the above example, and as our projects grow, we may forget that the same version of dependencies are already transitive dependencies.
In my mind, for organization sake, I find it messy to leave these duplicate declarations, such as it is with someArtifact.
I could write a new maven-enforcer-plugin rule, but maybe there is already a solution.
Try with dependencyConvergence rule. Add this to your parent pom.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M3</version>
<executions>
<execution>
<id>enforce</id>
<configuration>
<rules>
<dependencyConvergence/>
</rules>
</configuration>
<goals>
<goal>enforce</goal>
</goals>
</execution>
</executions>
</plugin>
Reference :: https://maven.apache.org/enforcer/enforcer-rules/dependencyConvergence.html
I have a maven multiple module project and I use IntelliJ for development (importing the POM). The project structure is:
project
entities-module (JPA entities)
query-module (jOOP codegen maven plugin using JPADatabase)
app-module(app logic module)
The problem I'm having is that IntelliJ is not running jOOQ codegen plugin (I'm using Intellij build logic, not delegating to Maven goals).
What I'm doing right now is to do a build from Maven, to force jOOQ code gen and then work from IntelliJ. But this is error prone and I would like to avoid it.
Following the corresponding snippets of my POM:
pom.xml/project/build/pluginManagement/plugins:
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<version>${jooq.version}</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.jooq</groupId>
<artifactId>jooq-meta-extensions</artifactId>
<version>${jooq.version}</version>
</dependency>
<dependency>
<groupId>org.jooq</groupId>
<artifactId>jooq-meta-extensions-hibernate</artifactId>
<version>${jooq.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>jooq-codegen</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<generator>
<database>
<name>org.jooq.meta.extensions.jpa.JPADatabase</name>
<properties>
</properties>
</database>
</generator>
</configuration>
</plugin>
pom.xml/project/build/plugins:
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<dependencies>
<dependency>
<groupId>org.foo</groupId>
<artifactId>foo-lib</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<configuration>
<generator>
<database>
<properties>
<property>
<key>packages</key>
<value>
org.foo.data
</value>
</property>
</properties>
</database>
<target>
<packageName>org.foo.data</packageName>
<directory>target/generated-sources/jooq</directory>
</target>
</generator>
</configuration>
</plugin>
I am testing jax-rs web services with Arquillian, and I use an embedded Wildfly 10 container. This is my pom.xml:
..
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>1.1.13.Final</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
..
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.wildfly.arquillian</groupId>
<artifactId>wildfly-arquillian-container-embedded</artifactId>
<version>2.1.0.Final</version>
</dependency>
..
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- You need the maven dependency plugin to download locally a zip with
the server, unless you provide your own, it will download under the /target
directory -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>process-test-classes</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-dist</artifactId>
<version>10.1.0.Final</version>
<type>zip</type>
<overWrite>false</overWrite>
<outputDirectory>target</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
<configuration>
<!-- Fork every test because it will launch a separate AS instance -->
<forkMode>always</forkMode>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
</systemPropertyVariables>
<redirectTestOutputToFile>false</redirectTestOutputToFile>
</configuration>
</plugin>
</plugins>
</build>
..
with arquillian.xml in src/test/resources:
<arquillian xmlns="http://jboss.org/schema/arquillian"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<container qualifier="wildfly10" default="true">
<configuration>
<property name="jbossHome">target/wildfly-10.1.0.Final/</property>
<property name="modulePath">target/wildfly-10.1.0.Final/modules</property>
</configuration>
</container>
..
But when type: mvn clean verify, I get the following error:
WFLYPRT0023: Could not connect to remote+http://127.0.0.1:9990. The connection timed out
This question was one of the first links I found in Google about error WFLYPRT0023.
I got the same error code when connecting via jboss-cli and fixed it by setting the time-out on the command line.
The default time-out is 5000 milliseconds which doesn't seem to be nearly enough, especially when the network is slow.
This sets the time-out to 30 seconds
jboss-cli.bat --timeout=30000 ...
As far as setting this in Arquillian is concerned, you should be able to add the
startupTimeoutInSeconds
property in your
arquillian.xml
file. I assume that this setting is the same as the one above.
There is some more information about Arquillian here Arquillian and Wildfly: set timeout for management connection
I've come across some sample code which specifies dependencies inside the plugin tag like this :
<build>
<plugins>
<plugin>
<dependencies>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.2.8</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
It look strange to me because mostly I see people put the dependencies tag outside the build tag.
When you add <dependency> to project it is available to that project depending on its scope (compile, test, runtime, etc)
But when you add <dependency> inside plugin's execution you are making that artifact available to that plugin in classpath at runtime
For example:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>check my sources</id>
<goals>
<goal>check</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>checkstyle</groupId>
<artifactId>checkstyle</artifactId>
<version>4.4</version>
</dependency>
</dependencies>
</plugin>
in this snippet checkstyle:checkstyle:4.4 is being available to maven-checkstyle-plugin at runtime
Read More
How to override a plugin's dependency in Maven
How can I use the maven dependency plugin, unpack-dependecies goal to unpack to an absolute path, that is, NOT relative inside the generated target folder in the project tree? For example, I want to unpack the artifacts of the two dependencies below in /usr/local/*
<dependencies>
<dependency>
<groupId>package.org.apache.apr</groupId>
<artifactId>apr-bin</artifactId>
<version>1.4.6</version>
<classifier>bin</classifier>
<type>tar.gz</type>
</dependency>
<dependency>
<groupId>package.org.apache.apr-util</groupId>
<artifactId>apr-util-bin</artifactId>
<version>1.4.1</version>
<classifier>bin</classifier>
<type>tar.gz</type>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.7</version>
<executions>
<!-- Unpack header files and libraries for build -->
<execution>
<id>apr-bin-unpack</id>
<phase>generate-sources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<excludeTransitive>true</excludeTransitive>
<!-- This element does NOT make a difference -->
<outputdirectory>/usr/local</outputdirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Check the capitalization. It should be:
<outputDirectory>/usr/local</outputDirectory>