I have a maven project that creates a JCA connector (.rar file). Now to use this connector in another project I build this thing for, I want to import the interfaces for the connector.
Can I somehow add a build target to the connector pom.xml, which creates a new maven artifact with just the interfaces from the connector project (lets say connector-interfaces)?
Thanks!
Maven has a strong rule, that 1 project -> 1 artifact. I suggest to split your project:
connector
+ pom.xml
++ connector-interfaces
+++ pom.xml
++ connector-impl
+++ pom.xml
The pom.xml of the connector would contain 2 modules:
<modules>
<module>connector-interfaces</module>
<module>connector-impl</module>
</modules>
In the module connector-impl, you will need to add a dependency on connector-interfaces. Add this in the pom.xml of connector-impl:
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>connector-impl</artifactId>
<version>${project.version}</version>
</dependency>
If you use the maven release plugin, add this to the parent pom:
<project>
<build>
<plugins>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<configuration>
<autoVersionSubmodules>true</autoVersionSubmodules>
</configuration>
</plugin>
</plugins>
</build>
</project>
That way, maven will only ask for the version 1 time when you release.
Although #WimDeblauwe is suggesting a best practice and it would probably be best to follow it his way, there is another way you can accomplish this. There is an assembly plugin that can be used to do this. Normally it's meant to package your whole project in one jar, but it can also be used to make a subset of classes and make a jar out of that.
It can be a little tricky though. To do it you'll probably need to create a custom descriptor and reference this documentation to see how to format your descriptor file. Here's an example from the documentation of how to point to a custom descriptor:
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/src.xml</descriptor>
</descriptors>
</configuration>
[...]
</project>
In that src.xml file you'll want to <excludes> all classes except for the interfaces and set <includeDependencies> to false.
Related
I have a multi module maven project wie quarkus modules and some custom libraries which are local maven repositories (so they can be used by the other maven projects/modules). However, so that local maven repositories are recognizable und usable by your other local maven projects, you have to manually index them for some reason. I.e. add a config like this for quarkus index to the application.properties of the project including the local maven repo dependency:
quarkus.index-dependency.<index-name>.group-id = <group-id-of-local-maven-repo>
quarkus.index-dependency.<index-name>.artifact-id = <artifact-id-of-local-maven-repo>
The problem is, this causes issues for me becausse if you have 3 layers of project dependencies, say:
Project A (custom local maven repo library)
Project B (custom local maven repo library, includes Project A dependency)
application.properties (indexing Project A library dependency)
Project C (Local maven project for an end product, includes Project B
library dependency - and through it indirectly Project A).
application.properties (indexing Project B library dependency and config for datasources or other app related things)
Then when you generate an uber-jar (fat jar) of Project C for deployment, it for some reason uses application.properties of Project B in the packaged jar, instead of from the project which im building (Project C). Thus, the app is missing key configs and does not work. Maven seems to use an inverse priority here, which i dont know if thats a bug or not. When i asked about this, i was simply told that:
"My dependencies should not have application.properties".
I tried to find a way to prevent manual indexing via application.properties and found the maven jandex plugin - which is supposed to generate an index. The next problem is, this seems to only work in some projects but not in others in the dependency hierarchy, resulting in the same situation as before, and i don't understand why. This is the pom.xml config for the plugin i have included in all 3 projects (the entire pom.xml for all is too long, so let me know if you need more info):
<properties>
...
<jandex.skip>false</jandex.skip>
...
</properties>
...
<build>
...
<plugin>
<groupId>io.smallrye</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<version>3.0.5</version>
<inherited>true</inherited>
<executions>
<execution>
<id>make-index</id>
<goals>
<goal>jandex</goal>
</goals>
</execution>
</executions>
<configuration>
<skip>${jandex.skip}</skip>
</configuration>
</plugin>
...
The odd thing is, this works to the extend that i no longer have to index Project B library dependency in Project C application.properties, but Project B library dependency still has to manually index Project A library dependency - thus rendering the entire exercise futile. Project C having an application.properties was never the issue, and is obviously needed. Project B still requires a properties file to point to Project A now, how do i solve this?
I have a parent module POM in the root folder containing all these projects, over which this maven jandex dependency is distributed to all modules, so it looks like this:
Maven parent module (contains all dependencies and versions used by all project sub modules)
Project A (custom local maven library repo), own pom.xml with inheritance from parent module
Project B (custom local maven library repo, includes Project A library), own pom.xml with inheritance from parent module
application.properties - Indexes Project A dependency manually, this is the problematic one which needs to go!
Project C (Local maven project for REST API etc., includes Project B library), own pom.xml with inheritance from parent module
pom.xml (parent module POM, containing maven jandex dependepency among others)
Edit: One of the projects, "entity", where all the database access objects are stored, does not run the jandex plugin during mvn clean install. This is the POM of the project:
<?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.compamny.project</groupId>
<artifactId>entity</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm</artifactId>
<version>2.16.1.Final</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-validator</artifactId>
<version>2.16.1.Final</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
<version>2.16.1.Final</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>2.13.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.smallrye/jandex-maven-plugin -->
<dependency>
<groupId>io.smallrye</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<plugin>
<groupId>io.smallrye</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<version>3.0.0</version>
<inherited>true</inherited>
<executions>
<execution>
<id>make-index</id>
<goals>
<goal>jandex</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
When i force the execution of the jandex goal with mvn io.smallrye:jandex-maven-plugin:3.0.0:jandex it creates an META-INF/jandex.jdx file, but it does not produce one when i run mvn clean install. This is not a solution since i need to build the project, run the jandex plugin and install it into my local repositories separately. Also, notice that im using the "io.smallrye" version of the jandex plugin since the "org.jboss" version seems to not work at all.
I figured it out. The jandex plugin was set in the <pluginManagement> section of the POM configuration, which made it not run on mvn clean install. I had to move it to the plugins section so it gets executed. Thanks #Ladicek for making me look closer and keep trying!
I am beginner on Spring and Maven.
In Spring Framework,
I want to manage a separate version control flow.
1. Main Project that already exist.
2. Module of the partial use that packaged by maven war.
Two projects should be treated separately when Push and Pull.
But Files on two projects may be present in the same folders.
How can I use this?
This is actually related with version control system you currently use. Git for example supports submodules. You can create a maven module directly in your root project folder and define it as git submodule. So they have different git tracks and may seperately maintained.
I believe what you need might be achievable by using 'war-overlays' as documented here
To summarize, you specify the 'child' project as a dependency in the 'Main' project:
...
<dependencies>
<dependency>
<groupId>com.example.projects</groupId>
<artifactId>documentedprojectdependency</artifactId>
<version>1.0-SNAPSHOT</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
...
</dependencies>
...
And you define the overlay in the maven-war-plugin's configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<overlays>
<overlay>
<id>my-webapp-index.jsp</id>
<groupId>com.example.projects</groupId>
<artifactId>my-webapp</artifactId>
<includes>
<include>index.jsp</include>
</includes>
</overlay>
<overlay>
<!-- empty groupId/artifactId represents the current build -->
</overlay>
</overlays>
</configuration>
</plugin>
I am currently building an EAR file in Maven. When I build it, I get the following in my target folder:
-target/
-MyProject.ear
-MyProject/
-MainProject.jar
-Dependency.jar
If I open up MyProject.ear in 7Zip, I see the same file structure that exists in MyProject/
I have been asked to change this so that all dependencies are in a subfolder, like this:
-target/
-MyProject.ear
-MyProject/
-MainProject.jar
-lib/
-Dependency.jar
Now I can make this work for the one dependency by making the following change to my pom.xml file:
<build>
[...]
<plugins>
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>2.9</version>
<configuration>
<modules>
<jarModule>
<groupId>Dependency</groupId>
<artifactId>Dependency</artifactId>
<bundleDir>lib</bundleDir>
</jarModule>
</modules>
</configuration>
</plugin>
</plugins>
</build>
However in the real project, I have about 30 dependencies. I could manually add a <jarModule> tag for each and every dependency, but ideally I would like for it to automatically move all of the dependencies to a subdirectory (making an exclusion for MainProject.jar).
I had hoped that I could declare <jarModule> once and use wild card characters for the groupId and artifactId, like Maven allows with exclusions:
<!-- Moving all for the time being, add the exclusion if it works -->
<jarModule>
<groupId>*</groupId>
<artifactId>*</artifactId>
<bundleDir>lib</bundleDir>
</jarModule>
I would expect the above to take all artifacts and put them into a lib folder. Unfortunatley, this doesn't seem to work in Maven 3.2.1, providing an error saying that Artifact[jar:*:*] is not a dependency of the project
So how can I move all of my dependencies to a subfolder when building an EAR in Maven?
You should move the bundle directory restriction under your maven-ear-plugin build configuration as below:
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>${maven-ear-plugin.version}</version>
<configuration>
<modules>
<jarModule>
<groupId>${group_id}</groupId>
<artifactId>${artifact_id}</artifactId>
<bundleDir>lib</bundleDir>
</jarModule>
<webModule>
...
</webModule>
</modules>
<defaultLibBundleDir>/lib</defaultLibBundleDir>
</configuration>
</plugin>
</plugins>
Hope it helps.
Thanks to a happy accident of failing to fully clean up my pom file after a test, I discovered how to do this.
In the <configuration> tag, add <defaultLibBundleDir>/lib</defaultLibBundleDir>. This will put all modules by default in a lib folder in a root of a directory. No wildcards are needed; in fact, Maven doesn't support wild cards in this part, probably because there are no clear bounds (it could be interpreted as "move all artifacts ever"). Wild cards only work for exclusions because there are clear bounds; it's a subset of a clearly defined set of artifacts.
If you'd like to make an exception, then you specify the module and type in <bundleDir>/</bundleDir>, which will place it back in the root. The full XML looks like this:
<build>
[...]
<plugins>
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>2.9</version>
<!-- All dependencies not otherwise specified are going in /lib -->
<defaultLibBundleDir>/lib</defaultLibBundleDir>
<modules>
<jarModule>
<!-- An exception to keep the main project in the root -->
<groupId>MainProject</groupId>
<artifactId>MainProject</artifactId>
<bundleDir>/</bundleDir>
</jarModule>
</modules>
</configuration>
</plugin>
</plugins>
This results in the original goal of putting all dependencies in a lib folder except for MainProject.jar:
-target/
-MyProject.ear
-MyProject/
-MainProject.jar
-lib/
-Dependency.jar
Provided two Maven projects: J (jar), W (war); both depend on one parent P (pom). The parent has a plugin, which must only run for the project "W".
How does one go about doing this:
without creating separate parent projects
without using a profile (so build must still be executed with mvn clean package)
J (jar)
<project>
<parent>
<artifactId>P</artifactId>
</parent>
<artifactId>J</artifactId>
<packaging>jar</packaging>
</project>
W (war)
<project>
<parent>
<artifactId>P</artifactId>
</parent>
<artifactId>W</artifactId>
<packaging>war</packaging>
</project>
P (pom)
<project>
<artifactId>P</artifactId>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>classes</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I think you can achieve this using Profile Activation. Ideally, the activation condition would be something like "packaging type is war", but apparently, this condition cannot be implemented in Maven. However, in your case, there is a condition that can be implemented and that is probably equivalent in practice: "there is a src/main/webapp directory".
This is how your pom.xml might look like:
<profiles>
<profile>
<activation>
<file>
<exists>src/main/webapp</exists>
</file>
</activation>
<build>
[plugin configuration]
</build>
</profile>
</profiles>
One way to do this would be to place the plugin in the parent pom within <pluginManagement> section. Thereafter specify the plugin in the project(s) that you want it to run.
In your case, you would specify the plugin for project J and not W.
P
<build>
...
<pluginManagement>
<plugins>
<plugin>
<groupId>...</groupId>
<artifactId>...</artifactId>
... other plugin details ...
</plugin>
</plugins>
</pluginManagement>
...
</build>
J
<build>
...
<plugins>
<plugin>
<groupId>...</groupId>
<artifactId>...</artifactId>
<plugin>
</plugins>
...
</build>
Short answer: Maven doesn't appear to have a good way to do what you're trying to do. I've spent a fair amount of time trying to solve a similar problem and haven't found anything satisfactory.
You've already discovered two of the possible solutions: introduction of an additional parent pom for the wars (perhaps the additional pom extends the original parent so you don't have to duplicate all of its config), or duplicating the jar plugin config in all of the war poms. As you've said, neither of these is ideal.
Another possibility is to use the maven-assembly-plugin instead of the jar plugin to build the classified jar for the war projects. The assembly plugin is not included in the default lifecycles for either jar or war packaging, so you could configure it in the parent's <pluginManagement> section and then only reference it in the war projects as Raghuram described. If you need a custom assembly descriptor you will probably want to follow the sharing the assembly descriptors example.
There is a multi-module Maven-3 project, where one of sub-modules is used as <dependency> in all other modules. At the same time, all sub-modules inherit from parent module. Such a structure leads to cyclic dependency. How can I resolve it?
Project structure is rather typical:
/foo
/foo-testkit
/foo-core
This is parent foo/pom.xml:
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<configLocation>checkstyle/checks.xml</configLocation>
</configuration>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>foo-testkit</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
In parent foo/pom.xml I specify how and when checkstyle plugin has to be executed in every sub-module. But I don't need checkstyle to be executed in foo-testkit, which is a sub-module inheriting from foo, but is at the same time a dependency..
One way is to disable the checkstyle plugin for module foo-testkit by adding the below to foo-testkit's pom.xml file.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
If that is not to your liking, another way is to move the checkstyle plugin configuration from build/plugins to build/pluginManagment/plugins in the parent pom.xml file. Then in each module you want checkstyle executed, add this to the build/plugins section of each module's pom.xml file:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
This invokes the plugin for that module and the configuration specified in the parent pom.xml under the pluginManagement section will be applied. You can verify that is working correctly by running mvn help:effective-pom on that module.
I agree with Tim Clemons's answer, but there is also an alternative, make your project nested.
root
/ \
common sub-root
/ | \
sub1 sub2 sub3
Define the dependency to common in the sub-root pom. I'm not saying this is a best practice, but it is a solution to your problem.
So I take it the parent pom is referencing one of the submodules as a dependency? I would suggest if you have any build logic going on in the parent module you push it down into a new submodule. The parent should limit itself to specifying the <modules>, <pluginManagement>, and <dependencyManagement> sections. All other work should be farmed out to submodules.
See the following for more advice on organizing multi-module projects:
http://www.sonatype.com/books/mvnref-book/reference/pom-relationships-sect-pom-best-practice.html
If you don't actually need it in foo (only in its sub modules), you can solve the cyclic issue by moving the plugin definition from the build segment to a pluginManagement segment in foo/pom.xml.