Following maven-ci-friendly article in official Maven documentation, this multimodule project (minimal example) was created.
There are three modules and a root project (inception):
/inception
/modules
/base (common parent of 'core' and 'facade')
/core (child of 'base')
/facade (child of 'base' having 'core' as a dependency)
Executing mvn package from inception works as expected - all 3 *.jar artifacts are being created in the corresponding target forlders.
I would like to have an option of building facade module separately.
Unfortunately, mvn package from modules/facade fails to collect dependencies and fails with error
[ERROR] Failed to execute goal on project sample-facade:
Could not resolve dependencies for project sample.group:sample-facade:jar:0.0.1:
Failed to collect dependencies at sample.group:sample-core:jar:0.0.1:
Failed to read artifact descriptor for sample.group:sample-core:jar:0.0.1:
Could not transfer artifact sample.group:sample-base:pom:${revision}
The surface problem is that ${revision} is not being resolved into 0.0.1.
Could you help me workaround this issue?
The flatten-maven-plugin solves the problem.
Thanks to #khmarbaise, who adviced in the comments reading the docs to the end.
Adding the plugin to /modules/base/pom.xml solved the problem with building a submodule separately:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>1.2.5</version>
<configuration>
<updatePomFile>true</updatePomFile>
<flattenMode>resolveCiFriendliesOnly</flattenMode>
</configuration>
<executions>
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
</execution>
<execution>
<id>flatten.clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
Before starting a phase on facade module, it is required to have base and core in the local repository, so maven could find the artifacts. Hence, here is the sequence of actions in root:
mvn install -pl modules/base,modules/core (or just mvn install)
mvn package -pl modules/facade
Related
I have multi-module maven project. The acceptance-tests module has dependency from api module in pom.xml (Replacing real company name by xxx to keep confidentiality). I am trying to import some classes from api module in my acceptance-tests.
Here is my pom.xml dependency of acceptance-tests module:
<dependency>
<artifactId>xxx-api</artifactId>
<groupId>com.xxx</groupId>
<version>${xxx.api.version}</version>
</dependency>
The api module separately is being installed and packaged (mvn install, mvn package) by maven without any issue. The jar file is being created in my local .m2.
However, when I try to compile the acceptance-tests module, I get a compilation error saying that the the classes cannot be imported because the package is not found.
Here is the actual error:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project xxx-acceptance-tests: Compilation failure: Compilation failure:
[ERROR] /Users/andranik_chorokhyan/mydisk/Projects/XXX/automation/xxx-project-test-automation/xxx-acceptance-tests/src/main/java/com/xxx/xxx/utilities/api/ApiPayloadUtils.java:[17,38] package com.xxx.domain.dto does not exist
[ERROR] /Users/andranik_chorokhyan/mydisk/Projects/XXX/automation/xxx-project-test-automation/xxx-acceptance-tests/src/main/java/com/xxx/xxx/utilities/api/ApiPayloadUtils.java:[18,38] package com.xxx.domain.dto does not exist
[ERROR] symbol: class MappingData
[ERROR] location: class com.xxx.utilities.api.ApiPayloadUtils
One more interesting fact is that there is no error visible in Intellij IDEA. No red underline, no compilation error, no problem with navigating to the appropriate imported file.
And in reality, the com.xxx.domain.dto package does exist and the MappingData class as well.
I removed whole xxx directory from my local .m2 repository and executed mvn clean dependency:resolve command. It succeeded as well.
Does anybody know what's the problem here and how it can be solved?
Thanks in advance!
Finally I have found the solution. Thanks JF Meier and khmarbaise for hints.
It appeared Maven doesn't allow dependency from executable jar. This was my case. My api module was an executable Spring Boot application and not reusable library.
So, the solution was the following:
It was necessary to find the Application.java file in api module.
Add maven-jar-plugin with exclusion of the Application.java file and specification of some classifier
Making dependency in acceptance-tests module from the above specified classifier instead of standard jar
Plugin specification in api module below:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>qa</classifier>
<excludes>
<exclude>**/Application*</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
Dependency in acceptance-tests module below:
<dependency>
<artifactId>xxx-api</artifactId>
<groupId>com.xxx</groupId>
<version>${api.version}</version>
<classifier>qa</classifier>
</dependency>
I was also getting symbol not found errors while compiling with maven, and the solution is for spring boot 2 you need to configure plugin as below, classifier exec
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>exec</classifier>
</configuration>
</plugin>
If you are working with spring boot 1
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
Migrate from Ant Ivy to Maven build tool.
Little info about project:
Multi-module project with few deploying artifacts.
On Ant Ivy everything fine, compilation and deploy passes normal.
Migrate on Maven pass successfully with 2.7.0 GWT version. After increasing version to 2.8.1, stared to get gwt compilation error.
[ERROR]com.example.gwt.client.module.user.GWTEventBus:
Method createInfoPage: No instance of com.example.gwt.client.module.user.presenter.
info.InfoPresenter is defined. Have you forgotten to annotate your event handler
with #Presenter or #EventHandler?
[INFO] at com.mvp4g.util.config.loader.annotation.EventsAnnotationsLoader.
buildPresentersAndEventHandlers (EventsAnnotationsLoader.java:425)
...long stack trace ...
at com.google.gwt.dev.Compiler.main(Compiler.java:125)
[INFO][ERROR] Errors in 'com.example.gwt.GWTModule'
[INFO][ERROR] Line 137: Failed to resolve 'com.mvp4g.client.Mvp4gModule' via deferred binding
Line 137 contain Mvp4gModule module = GWT.create(Mvp4gModule.class);
Attempts to fix:
1. Compared classpath mapped dependencies from Ant Ivy with Maven classpath, everything the same. All versions of dependencies and plugins are fine, without any conflicts.
2. Tried with two different gwt maven plugins, but get the same error with any configurations:
<plugin>
<groupId>net.ltgt.gwt.maven</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>1.0-rc-6</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>import-sources</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
<configuration>
<moduleName>com.example.gwt.GWTModule</moduleName>
<jvmArgs>
<jvmArg>-Xmx768M</jvmArg>
<jvmArg>-Xss10M</jvmArg>
</jvmArgs>
<failOnError>false</failOnError>
<sourceLevel>1.8</sourceLevel>
<compilerArgs>
<arg>-compileReport</arg>
<arg>-XcompilerMetrics</arg>
</compilerArgs>
<warDir>${project.build.directory}/${project.build.finalName}</warDir>
<classpathScope>compile+runtime</classpathScope>
<startupUrls>
<startupUrl>Validation.html</startupUrl>
</startupUrls>
</configuration>
</plugin>
Main strangeness is that Ant compile successfully. Ant's compile-gwt target has the same configuration and arguments as Maven's gwt-plugin.
My Maven project with the JAXB2 plugin works without errors if I run
mvn clean install
but it always fails if I skip the clean and run
mvn install
In this case the generated classes are not generated again which is correct:
[INFO] No changes detected in schema or binding files - skipping JAXB generation.
But then I get an compilation error that the generated classes and packages can not be found when the rest of the static Java sources in this Maven project are compiled:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.2:compile (default-compile) on project [...]: Compilation failure: Compilation failure:
[ERROR] [...] package [...] does not exist
[ERROR] [... ]cannot find symbol
Here is the relevant part of my pom.xml (the rest is only dependencies):
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>xjc-core</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<sources>
<source>${project.basedir}/src/main/xsd/core</source>
</sources>
<packageName>com.example.core</packageName>
<clearOutputDir>false</clearOutputDir>
</configuration>
</execution>
<!-- ... and more <execution> -->
</executions>
Am I correct that the only solution is to separate the static sources and generated sources into different Maven modules? Or is there any other way?
There is a bug in jaxb2-maven-plugin v2.2 https://github.com/mojohaus/jaxb2-maven-plugin/issues/35.
This bug has been fixed in v2.3
I am using properties-maven-plugin to read a external property file under root dir to maintain the version of parent module since there are quite a number of sub-modules in my project and the dependency tree is kinda deep.
It works fine when I build locally and install the artifacts into local repo but got the 401 error when I try to use "mvn clean deploy" to publish them to Nexus. I am pretty sure this is caused by the ineligible artifact name(releaseurl/{external.version}), external.version is supposed to be the property read from the external file. However, it ended up not being read and it just worked fine when I explicitly declare the version in the project.parent.version tag. Any thoughts or workaround? or even how you handle the version control when trying to use same version for parent and child in all the modules when dealing with a multi-module porject.
The maven pom for the plugin is as below, I saw some comments online regarding the phase, not sure if it will work if change initialize to something else:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>external-file.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
Something bother me a lot...
On a big project with many dependencies, some of them are set as SNAPSHOT in Maven2.
The matter is that it seems i can't get the sources through Eclipse without loading the project or fixing the dependency to the last release.
For debugging, it's really annoying me...
EDIT
This is what i get in eclipse maven console:
26/08/10 11:31:46 CEST: Downloading http://repo-maven/archiva/repository/snapshots/com/blabla/1.1-SNAPSHOT/blabla-1.1-20100824.213711-80-javadoc.jar
26/08/10 11:31:47 CEST: Could not download sources for com.blabla:blabla:1.1-20100824.213711-80
On archiva i can see the deployed stuff i want to retrieve in eclipse...
Repository snapshots
Group ID com.blabla
Artifact ID blabla
Version 1.1-20100824.213711-80
Packaging jar
Parent com.blabla bla 1.1-SNAPSHOT (View)
Other Versions 1.1-20100824.213535-79
I can download sources of this artifact with my browser but not within Eclipse... Any idea?
The matter is that it seems I can't get the sources through Eclipse without loading the project or fixing the dependency to the last release. For debugging, it's really annoying me...
Well, these modules are probably not publishing source JARs as part of the "regular" build process (i.e. outside the release). If these modules are under your control (which is my understanding), configuring the Maven Source Plugin to produce source JARs for them and deploying them in your corporate repo should solve the problem. From the Usage page:
Installing the sources along with your artifact
There are two ways to do this. You can
either bind this plugin to a phase or
you can add it to a profile. The goals
source:jar-no-fork and
source:test-jar-no-fork are preferred
for binding the goal to the build
lifecycle.
Installing the sources using a phase binding
Here is how you would configure the
plugin in your pom.xml to run
automatically during the verify phase:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
We are using the verify phase here
because it is the phase that comes
before the install phase, thus making
sure that the sources jar has been
created before the install takes
place.
Installing the sources using a profile
If you want to install a jar of your
sources along with your artifact
during the release process, you can
add this to your pom.xml file:
<project>
...
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
...
</project>
Using a profile would probably be a good idea so that building source JARs will only be done by the build running at the CI server level but not on developer machines.