How do I use mvn test with multiple modules? - java

I have two maven modules, A and AB, with AB depending on test files in A. Both reference a parent pom.
I discovered the magic of test-jar which allowed me to compile my program, but I still cannot run tests with mvn test.
Strangely enough, mvn package tests seems to work.
Here's my basic configuration:
...
<parent>
<groupId>com.acme.parent</groupId>
<artifactId>parent</artifactId>
<relativePath>../pom.xml</relativePath>
<version>1.0</version>
</parent>
<groupId>com.acme</groupId>
<artifactId>A</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Project AB (depends on A)
...
<parent>
<groupId>com.acme.parent</groupId>
<artifactId>parent</artifactId>
<relativePath>../pom.xml</relativePath>
<version>1.0</version>
</parent>
<artifactId>AB</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<dependency>
<groupId>com.acme</groupId>
<artifactId>A</artifact>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.acme</groupId>
<artifactId>A</artifact>
<version>1.0</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
...
And finally, the relevant bits from the parent pom:
...
<groupId>com.acme.parent</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<modules>
<module>A</module>
<module>AB</module>
</module>
...
So, with all that said, how do I make mvn tests run as expected?
I'm using maven 2.2.1 by the way.

This may be related to one of the unresolved bugs like MNG-3559.
Essentially, the test classes of Project A are not visible to Project AB if only mvn test is run from parent pom. They are visible once the jar for package A is created (during the package phase).

Related

JavaFX with Maven fails to import module from the same project

I have the following folder structure in a Java project:
main-module (Java module)
sub-module-to-import (Java module)
ImportedClass.java
sub-module (Java module)
fx-sub-module (JavaFX module)
- pom.xml and classes.
Whenever I import sub-module-to-import into fx-sub-module from maven, I can access ImportedClass.java after importing it in fx-sub-module's classes (instantiate the class, access its methods etc. in the IDE), but whenever I try to compile the module using mvn clean compile, I get a compilation error of type "cannot find symbol", where the symbol is a method of ImportedClass. Whenever I reload the maven project after adding the module as a dependency, everything is okay, with no XML errors or warnings, I can even ctrl + left click on sub-module-to-import's name and get sent to its pom.xml without issues. The project is a modular one, but I have removed the module-info file in order to not have to use modularity. I am using IntelliJ IDEA.
Here is the pom.xml file:
<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/maven-v4_0_0.xsd">
<parent>
<artifactId>sub-module</artifactId>
<groupId>com.project</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>fx-sub-module</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.project</groupId>
<artifactId>sub-module-to-import</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>13</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>13</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>16</release>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.6</version>
<executions>
<execution>
<id>default-cli</id>
<configuration>
<mainClass>com.project.sub-module.fx-sub-module.MainClass</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
After reading a lot about it on the internet and not managing to find a solution, I tried simple things like adding sub-module-to-import to the parent pom.xml of fx-sub-module (which is the pom.xml file of sub-module), but that didn't change anything. I also tried changing plugin/dependency versions, but this also did not help. I would really appreciate any help and will be quick to answer for further clarification on the question. Thanks in advance.
Ensure:
mvn install has been run on the sub-module-to-import maven module.
The Idea project has been synchronized with the maven project after that.

Create jar A without dependencies and make dependent project C download the dependency B that this dependency A depends on

I have successfully created jar A that does not contain dependencies. This jar A depends on Jar B. I don't want to create a fat jar. I just want dependent project (lets call it C) to add my jar A as dependency, and as soon as jar A is added, project should pull in jar B.
Is this possible?
Question ends here. Below is just what I have tried so far:
What I have done:
I created Fat Jars first with both maven and gradle. Now this has all the dependencies, but my own classes are buried somewhere inside. And dependent project cannot find my classes.
Then I created a jar that does not contain any dependency. I created them separately with maven and gradle. This resolved my classes not being found issue. But then I ran into another issue. As soon as I run the project, it complains that jar B is missing. Rightfully so, as I never included it.
I will just show you my pom.xml
<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>custom-spring-boot-starter</groupId>
<artifactId>custom-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<scope>provided</scope>
</dependency>
<dependency> //THIS IS WHAT DEPENDENT PROJECT WILL NOT HAVE.
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-servicebus</artifactId>
<version>0.9.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>10</release>
</configuration>
</plugin>
</plugins>
</build>
This created a jar without dependencies. I added it to dependent project C. But it is complaining that it cannot find dependent B (azure-servicebus in my example). I was hoping that because pom.xml file is present in the jar file, dependent project will download another dependency automatically.
Then I rewrote my pom.xml:
<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>custom-spring-boot-starter</groupId>
<artifactId>custom-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>10</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-servicebus</artifactId>
<version>0.9.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>10</release>
</configuration>
</plugin>
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<executions>
<execution>
<id></id>
<goals>
<goal>revision</goal>
</goals>
<phase>validate</phase>
</execution>
</executions>
<configuration>
<dateFormat>yyyy-MM-dd-HH:mm:ss</dateFormat>
<dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
<prefix>git</prefix>
<verbose>false</verbose>
<generateGitPropertiesFile>true</generateGitPropertiesFile>
<generateGitPropertiesFilename>${project.build.outputDirectory}/git.properties</generateGitPropertiesFilename>
<format>json</format>
<gitDescribe>
<skip>false</skip>
<always>false</always>
<dirty>-dirty</dirty>
</gitDescribe>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Build-Jdk>${java.version} (${java.vendor} ${java.vm.version})</Build-Jdk>
<Digital-Voltage-Library-Version>${project.version}</Digital-Voltage-Library-Version>
<Build-Timestamp>${git.build.time}</Build-Timestamp>
<Build-Revision>${git.commit.id}</Build-Revision>
<Build-OS>${os.name} ${os.arch} ${os.version}</Build-OS>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
This is the stacktrace of the error:
Caused by: java.lang.ClassNotFoundException: com.microsoft.windowsazure.services.servicebus.ServiceBusContract
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:190)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:499)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:374)
at org.springframework.util.ClassUtils.forName(ClassUtils.java:275)
at org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanSearchSpec.getReturnType(OnBeanCondition.java:505)
at org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanSearchSpec.addDeducedBeanTypeForBeanMethod(OnBeanCondition.java:491)
... 22 common frames omitted
This error easily goes away if I add azure-servicebus dependency to target project. But I don't want to do that. I want the dependency to pull in azure-servicebus.
This is how I am pulling in my jar A into project C.
compile fileTree(dir: '/lib', include: 'custom-spring-boot-starter-0.0.1-SNAPSHOT.jar')
Yes, if A has a Maven dependency on B, then B is automatically pulled when C depends on A. This is the Maven transitive dependency resolution.
Note that this has nothing to do with fat jars. B is not included in A, it is just mentioned as dependency in the POM of A.
I asked this question without knowing something very important.
When jars are put into artifactory, a corresponding .pom file also has to be placed alongside it (outside of the directory, just look at below link to understand directory structure). This pom file is what tells the dependent project that the jar you are dependent upon, requires so and so dependencies itself.
If you do mvn clean install, it automatically installs jar file and pom file at the correct location for you in your local maven repository.
This answer helped me understand:
https://stackoverflow.com/a/50002072/4828463
Thanks to everyone who tried.

Jar packaging in Spring boot

I am creating a Spring Boot multi module project.. Module A has a dependency on Module B ..
Module A runs fine when I run in exploded form..
mvn spring-boot:run
But I am unable to package the jar along with dependencies
so that I can execute it as
java -jar Module-A.jar
Module A pom.xml is below:
<parent>
<artifactId>Module-Test</artifactId>
<groupId>com.module</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Module-A</artifactId>
<packaging>jar</packaging>
<properties>
<start-class>com.NotifyApp</start-class>
<main.class>com.NotifyApp</main.class>
</properties>
<dependencies>
<dependency>
<groupId>com.module</groupId>
<artifactId>Module-B</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.4.2.RELEASE:repackage (default) on project Module-A: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:1.4.2.RELEASE:repackage failed: Source must refe
r to an existing file
Parent pom.xml
<modelVersion>4.0.0</modelVersion>
<artifactId>Module-Test</artifactId>
<groupId>com.module</groupId>
<version>1.0.0-SNAPSHOT</version>
<modules>
<module>Module-A</module>
<module>Module-B</module>
<module>Module-C</module>
</modules>
<packaging>pom</packaging>
<parent>
<artifactId>Module-Parent</artifactId>
<groupId>com.parent</groupId>
<version>1.0.2</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.module</groupId>
<artifactId>Module-A</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.module</groupId>
<artifactId>Module-B</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.module</groupId>
<artifactId>Module-C</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.module</groupId>
<artifactId>starter-service</artifactId>
<version>${starter.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
I usually use this plugin https://maven.apache.org/plugins/maven-dependency-plugin/examples/copying-project-dependencies.html for maven, which will put all of the dependency jars into target/dependencies when you run
mvn clean package
Then I copy the jars into a folder (which I usually call lib) and I include lib/* in my classpath. The final run script usually looks like
java -cp lib/*: my.package.MySpringBootMain
Remove the
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
It's not needed.
Add dependency of module B in module A's pom.xml
<dependencies>
<dependency>
<groupId>com.module</groupId>
<artifactId>Module-B</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Use maven clean compile package install command for module B, to build module B first and then run maven clean compile package on Module A. This will out Module B into Module A.
There is no module A's reference required in Module B's pom.xml
you sure know, but you can initialize your project from this link
Spring Initializr
, it automatically generates the configuration with what you need

maven-ear-plugin, Cannot find 'version' in class org.apache.maven.plugin.ear.EjbModule

Desperatley trying to create a EAR bundle with some modules, using the maven EAR plugin version 2.10.1 with Maven 3. There is a problem with the generate-application-xml goal, I´m getting the error:
Failed to execute goal org.apache.maven.plugins:maven-ear-plugin:2.10.1:generate-application-xml (default-generate-application-xml) on project wineapp-ear: Unable to parse configuration of mojo org.apache.maven.plugins:maven-ear-plugin:2.10.1:generate-application-xml for parameter version: Cannot find 'version' in class org.apache.maven.plugin.ear.EjbModule -> [Help 1]
here is the pom.xml snippet:
<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>
<parent>
<artifactId>wineapp-parent</artifactId>
<groupId>com.jueggs</groupId>
<version>1.0.0</version>
</parent>
<artifactId>wineapp-ear</artifactId>
<packaging>ear</packaging>
<name>wineapp-ear</name>
<dependencies>
<dependency>
<groupId>com.jueggs</groupId>
<artifactId>wineapp-ejb</artifactId>
<version>1.0.0</version>
<type>ejb</type>
</dependency>
<dependency>
<groupId>com.jueggs</groupId>
<artifactId>wineapp-web</artifactId>
<version>1.0.0</version>
<type>war</type>
</dependency>
<dependency>
<groupId>com.jueggs</groupId>
<artifactId>wineapp-jpa</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.jueggs</groupId>
<artifactId>wineapp-common</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>2.10.1</version>
<configuration>
<!--<version>6</version>-->
<!--<applicationXml>/src/main/application/META-INF/</applicationXml>-->
<modules>
<ejbModule>
<groupId>com.jueggs</groupId>
<artifactId>wineapp-ejb</artifactId>
<version>1.0.0</version>
<bundleFileName>ejb.jar</bundleFileName>
</ejbModule>
<webModule>
<groupId>com.jueggs</groupId>
<artifactId>wineapp-web</artifactId>
<version>1.0.0</version>
<bundleFileName>web.war</bundleFileName>
</webModule>
<jarModule>
<groupId>com.jueggs</groupId>
<artifactId>wineapp-common</artifactId>
<version>1.0.0</version>
<bundleDir>lib</bundleDir>
<bundleFileName>common.jar</bundleFileName>
</jarModule>
<jarModule>
<groupId>com.jueggs</groupId>
<artifactId>wineapp-jpa</artifactId>
<version>1.0.0</version>
<bundleDir>lib</bundleDir>
<bundleFileName>jpa.jar</bundleFileName>
</jarModule>
</modules>
</configuration>
</plugin>
</plugins>
</build>
what the hack is wrong here? or is it just a f.. typo in the xml? inside the configuration element, the automatic tag detection by IDE (how is the word for that..) also not working, but i compared it with examples nearly a thousand times. don´t know what else matters for error finding, there´s also a parent pom
An module did not have a version tag see modules. The version is already defined by the dependency blog and the module blog is just use for renaming the artifacts in the ear file (since you define a new bundleFileName). So try to remove all version tags in your modules like this:
<modules>
<ejbModule>
<groupId>com.jueggs</groupId>
<artifactId>wineapp-ejb</artifactId>
<bundleFileName>ejb.jar</bundleFileName>
</ejbModule>
<webModule>
<groupId>com.jueggs</groupId>
<artifactId>wineapp-web</artifactId>
<bundleFileName>web.war</bundleFileName>
</webModule>
<jarModule>
<groupId>com.jueggs</groupId>
<artifactId>wineapp-common</artifactId>
<bundleDir>lib</bundleDir>
<bundleFileName>common.jar</bundleFileName>
</jarModule>
<jarModule>
<groupId>com.jueggs</groupId>
<artifactId>wineapp-jpa</artifactId>
<bundleDir>lib</bundleDir>
<bundleFileName>jpa.jar</bundleFileName>
</jarModule>
</modules>
Or better remove the complete modules blog because I do not think its important for you to rename the dependencies in the ear and it is OK to use the Maven default names.

maven - Can't release project due to non released dependencies

I am using a multi-module pom setup and when using the release plugin I am unable to do so.
I get the error:
Failed to execute goal org.apache.maven.plugins:maven-release-plugin:2.5:prepare (default-cli) on project libraryparent: Can't release project due to non released dependencies :
com.xyz:libraryparent:pom:1.1-SNAPSHOT
in project 'utils' (com.xyz:utils:jar:1.1-SNAPSHOT)
the command I runs is:
mvn -B release:clean release:prepare release:perform -DdryRun=true -DdevelopmentVersion=1.2-SNAPSHOT -DreleaseVersion=1.1
Here is the major portions of the files that I think is relevant:
libraryparent
<modelVersion>4.0.0</modelVersion>
<groupId>com.xyz</groupId>
<artifactId>libraryparent</artifactId>
<version>1.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>parent library</name>
<description>A parent pom for all library modules</description>
<modules>
<module>../util</module>
<module>../streams</module>
</modules>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.5</version>
<configuration>
<releaseProfiles>release</releaseProfiles>
<goals>deploy assembly:single</goals>
<!--
<autoVersionSubmodules>true</autoVersionSubmodules>
-->
</configuration>
</plugin>
util
<project .....>
<modelVersion>4.0.0</modelVersion>
<artifactId>util</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>com.xyz</groupId>
<artifactId>libraryparent</artifactId>
<relativePath>../libraryparent/pom.xml</relativePath>
<version>1.1-SNAPSHOT</version>
</parent>
</project>
streams
<project .....>
<modelVersion>4.0.0</modelVersion>
<artifactId>streams</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>com.xyz</groupId>
<artifactId>libraryparent</artifactId>
<relativePath>../libraryparent/pom.xml</relativePath>
<version>1.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.xyz</groupId>
<artifactId>util</artifactId>
<version>1.1-SNAPSHOT</version>
<!--
<version>${project.parent.version}</version>
-->
<classifier>j2me</classifier>
<optional>true</optional>
</dependency>
</dependencies>
</project>
I would suspect that the release plugin can set the versions to their release versions,etc.
Thanks.
The maven-release-plugin verifies if the parent and dependencies are part of the multimodule project. If it's not recognized it's either because of a different version or because of a typo in the groupId and/or artifactId. com.xyz is probably fake, so please check that value again.
Some may say that flat-projects (like this one) are not supported by the maven-release-plugin. However, there are a lot of integration-tests which do confirm that flat projects are supported.
I think I have just found the solution,
I will do a more complete test and post results shortly.
Change the maven-release-plugin goals from this:
<goals>deploy assembly:single</goals>
to this
<goals>deploy</goals>
...the end...

Categories

Resources