Mojo development - Handling unresolved dependencies in multi module projects - java

I have a mojo annotated with #requiresDependencyResolution test.
It works for multi-module projects with a single layer of nesting, but a user has reported an issue with a structure such as below.
-- my_project
|
-- pom.xml
-- submodule1
|
-- pom.xml
-- submodule2
|
-- pom.xml
-- submodule21
|
-- pom.xml
-- submodule22
|
-- pom.xml
If submodule21 depends on submodule1 maven reports
Failed to execute goal on project submodule21: Could not resolve
dependencies for project org.my:submodule21:jar:1.0-SNAPSHOT: Could
not find artifact org.my:submodule1:jar:1.0-SNAPSHOT
Removing the requiresDependencyResolution=test annotation prevents this problem but then I do not have access to the information I require for the mojo to run.
From brief scan of the surefire code on github, it looks to also use requiresDependencyResolution=test but is able to run against this project without issue.
https://github.com/apache/maven-surefire/blob/master/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java
https://github.com/apache/maven-surefire/blob/master/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
The only obvious difference from my own code is that it uses java annotations rather than old style javadoc ones.
How is the surefire mojo achieving this?
My code is
http://code.google.com/p/pitestrunner/source/browse/pitest-maven/src/main/java/org/pitest/maven/PitMojo.java
Example project displaying issue
http://code.google.com/p/pitestrunner/issues/detail?id=71

For the benefit of anyone else having this issue - I eventually solved this problem. There was no issue with the plugin.
The difference between surefire and my own plugin was simply the way in which they were being run. Surefire was bound to the test phase, my own plugin was being run by calling a goal directly. When I bind my plugin to the verify phase, everything resolves without issue.

Related

maven install - Failed to execute goal org.apache.maven.plugins, Fatal error compiling [duplicate]

Trying to compile a Maven project using JDK 9.0.1 I'm facing this stacktrace without much of an explanation:
Exception in thread "main" java.lang.AssertionError
at jdk.compiler/com.sun.tools.javac.util.Assert.error(Assert.java:155)
at jdk.compiler/com.sun.tools.javac.util.Assert.check(Assert.java:46)
at jdk.compiler/com.sun.tools.javac.comp.Modules.enter(Modules.java:250)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.readSourceFile(JavaCompiler.java:821)
at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$ImplicitCompleter.complete(JavacProcessingEnvironment.java:1510)
at jdk.compiler/com.sun.tools.javac.code.Symbol.complete(Symbol.java:633)
at jdk.compiler/com.sun.tools.javac.code.Symbol$ClassSymbol.complete(Symbol.java:1314)
at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.complete(Type.java:1139)
at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.getTypeArguments(Type.java:1065)
at jdk.compiler/com.sun.tools.javac.code.Printer.visitClassType(Printer.java:237)
at jdk.compiler/com.sun.tools.javac.code.Printer.visitClassType(Printer.java:52)
at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:992)
at jdk.compiler/com.sun.tools.javac.code.Printer.visit(Printer.java:136)
at jdk.compiler/com.sun.tools.javac.util.AbstractDiagnosticFormatter.formatArgument(AbstractDiagnosticFormatter.java:197)
at jdk.compiler/com.sun.tools.javac.util.AbstractDiagnosticFormatter.formatArguments(AbstractDiagnosticFormatter.java:165)
at jdk.compiler/com.sun.tools.javac.util.BasicDiagnosticFormatter.formatMessage(BasicDiagnosticFormatter.java:111)
at jdk.compiler/com.sun.tools.javac.util.BasicDiagnosticFormatter.formatMessage(BasicDiagnosticFormatter.java:67)
at jdk.compiler/com.sun.tools.javac.util.AbstractDiagnosticFormatter.formatArgument(AbstractDiagnosticFormatter.java:183)
at jdk.compiler/com.sun.tools.javac.util.AbstractDiagnosticFormatter.formatArguments(AbstractDiagnosticFormatter.java:165)
at jdk.compiler/com.sun.tools.javac.util.BasicDiagnosticFormatter.formatMessage(BasicDiagnosticFormatter.java:111)
at jdk.compiler/com.sun.tools.javac.util.BasicDiagnosticFormatter.formatMessage(BasicDiagnosticFormatter.java:67)
at jdk.compiler/com.sun.tools.javac.util.JCDiagnostic.getMessage(JCDiagnostic.java:771)
at jdk.compiler/com.sun.tools.javac.api.ClientCodeWrapper$DiagnosticSourceUnwrapper.getMessage(ClientCodeWrapper.java:799)
at org.codehaus.plexus.compiler.javac.JavaxToolsCompiler.compileInProcess(JavaxToolsCompiler.java:131)
at org.codehaus.plexus.compiler.javac.JavacCompiler.performCompile(JavacCompiler.java:174)
at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:1075)
at org.apache.maven.plugin.compiler.CompilerMojo.execute(CompilerMojo.java:168)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:154)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:146)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:309)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:194)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:107)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:993)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:345)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:191)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Not really sure what's causing this, is this a bug in the JDK?
Additional details:
Maven 3.5.0 with maven-compiler-plugin 3.7.0
I'm just executing mvn clean install
The source code is not open source unfortunately, so I'm not at liberty to share it
There are no module-info.java files yet, I'm just trying to compile a project using Java 9
Strangely enough if I leave the source level on 1.8, the code compiles, but it fails with the above exception if I specify it as 9
Just add this
<forceJavacCompilerUse>true</forceJavacCompilerUse>
to your maven compiler build plugin in your POM and you'll see all the javac errors! Source with more details
Debugging
Step one should be to add the maven-compiler-plugin and enable
<forceJavacCompilerUse>true</forceJavacCompilerUse> as the top answer suggests.
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<forceJavacCompilerUse>true</forceJavacCompilerUse>
</configuration>
</plugin>
...
This will point out the actual compilation error.
[main] INFO org.apache.maven.plugin.compiler.CompilerMojo - -------------------------------------------------------------
[main] ERROR org.apache.maven.plugin.compiler.CompilerMojo - COMPILATION ERROR :
[main] INFO org.apache.maven.plugin.compiler.CompilerMojo - -------------------------------------------------------------
[main] ERROR org.apache.maven.plugin.compiler.CompilerMojo - last round: true
/home/vsts/work/1/s/src/main/java/com/company/services/TemplateService.java:[3,61] error: cannot find symbol
symbol: class VariableNotFoundException
Root Cause
For me the root cause was that I made a commit and pushed it to the server which triggered CI, but did not include one class in the commit that was being used somewhere. Hence the compiler was not able to find it in the CI environment.
throws VariableNotFoundException {
The solution is to make sure you don't have any Git staged files that you forgot to include as part of your commit.
UPDATE
Most of the time this error seems to occur, when the compiler is trying to report a compilation error, but it blows up in the process. So far mainly two approach helped to resolve these issues:
Disable annotation processing by using -proc:none compiler argument (it seems like that annotation processing can upset the compiler, so if you are not meant to use any, this is a free win).
Debug the compiler using a conditional breakpoint and walk the stack until a compiler error message can be found, and then fix that error...
ORGINAL SOLUTION
After lots of trial and error I was able to work around/fix this problem locally, my approach in the end was the following:
I had an assumption that maybe the dependencies are somehow interfering with the build result, so I started to comment out Maven <dependency> entries in the failing module's POM.
the build then started to fail, but it did so with the expected cannot find symbol and similar compilation errors instead of the unhelpful AssertionError failure
it turned out that there was one particular dependency that triggered this AssertionError.
After code analysis, I couldn't determine any good reason why that dependency would cause problems, so I started to look at the transitive dependencies
I then used the same approach as before, but instead of uncommenting the faulty dependency, I've inserted all of its transitive dependencies into the POM
the build again failed, and after lots and lots of testing it turned out that I could trigger the AssertionError when both io.vavr:vavr:0.9.0:compile and javax.servlet:servlet-api:3.0.1:test were included in the dependency graph
It is still beyond me how a test scoped dependency could have any effect on the project's compilation... It also turned out that javax.servlet:servlet-api:3.0.1:provided was already amongst the dependencies of the failing module, and the test scoped dependency wasn't actually used for anything.
In the end I just removed the incorrectly defined test scoped servlet-api dependency from the bug triggering module and suddenly Maven was able to compile the previously failing module.
I'm fairly sure that this is a very obscure answer to a very obscure question in the first place, but hopefully my approach will be of use for someone else.
I got the same error on java 11. Adding jaxb api dependency to the pom solved my issue.
I had a similar stacktrace (abbreviated):
Exception in thread "main" java.lang.AssertionError at
jdk.compiler/com.sun.tools.javac.util.Assert.error(Assert.java:155)
...
...javac.main.JavaCompiler.readSourceFile(....
Since this occurred after a recent change to a library I had made, I traced the issue to a case change in a class name in one of my dependencies.
My dependency had changed from having a class with, for example, BlahMDCCustomizer to having a class with the same name but camelcase for 'Mdc' - BlahMdcCustomizer.
The source code I was trying to compile that used this library, had not yet been updated to the new name and still referenced the non-existent BlahMDCCustomizer.
No amount of mvn cleaning, invalidating caches or restarts would resolve the issue.
Once I updated my bad reference to BlahMDCCustomizer to the new name BlahMdcCustomizer, then mvn compile succeeded.
So it would seem that the compiler code has some case-sensitive assertions inside a case-insensitive process. Posting this in case it sheds light on the issue for someone more familiar with the source!
This was using JDK11 & maven 3.5.2, on Windows.
The part of the stack trace
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.readSourceFile(JavaCompiler.java:821)
relates to the line of code
throw new CompletionFailure(c, diags.fragment("cant.resolve.modules"));
This would possibly happen when you're trying to build a maven module which is not based on Java9 and/or does not have(correct) module declaration module-info.java with a release version specified as 9 where it won't be able to resolve modules with/without the declaration.
In my case (IntelliJ), it happened due to the caches. So I had to remove .idea (rm -rf **/.idea) and .iml(rm -f **/*.iml) directories/files and re-import the project, Rebuild the project.
Previously, the project was in JDK8 and upgraded in the maven and IntelliJ settings but still some of the configurations remained the same. Hence removing those files reimporting, and rebuilding the project resolved the issue.
I encouter the same crash with the same stack trace.
For me it was due to a spring-boot-maven-plugin in two maven modules (our app's module and an app's library of us). That was pointed to in the existing spring boot multi module spring-boot-maven-plugin compilation failure.
In my case it happened because I before applied
dependency:purge-local-repository
and I had missing dependencies without compile.
So I compiled my missing dependencies and retry
and all went well.
Need to execute mvn clean. It helped me.

Getting coverage from .war-dependency in multi-module-project

I have setup a Jacoco-subproject to allow Jacoco to handle multi-module-projects in my maven-project as described here. The Jacoco project depends on all .jar-modules in my project as described in the tutuorial. But this setup only seems to work for .jar-files. Instead of understanding that my .war-project produces a .war-file Jacoco is looking for a .jar.
What do I have to do to make the .war-file to get coverage?
maybe this issue will help.
Just add <type>war</type> to the dependency in the dedicated module.
but after doing that, I got another error:
Execution default of goal org.springframework.boot:spring-boot-maven-plugin:1.5.4.RELEASE:repackage failed: Unable to find main class -> [Help 1]
after add <packaging>pom</packaging> to the dedicated module for collecting all test result, jacoco works as usual.

How to avoid "The job exceeded the maximum time limit for jobs, and has been terminated." when accessing mvnsearch.org on Travis CI?

Since approx. 72h I'm getting The job exceeded the maximum time limit for jobs, and has been terminated. on TravisCI which seems to be related requesting artifacts from mvnsearch.org, e.g. https://travis-ci.org/document-scanner/document-scanner-aggregator/builds/266942578. I assume it's a remote repository which I'm not using, but some of the project's dependencies are.
mavensearch.org seems to be unreachable or responding very slowly. I don't find any news on their operational status. It's odd that the issues isn't fixed within 72h, so I assume a long-time issue.
The only possible solution I could imagine would be to add the download and installation of a maven proxy to the Travis CI build script and proxy mavensearch.org in a Maven settings.xml file. Is there any way to avoid this?
It doesn't work to use the mirror element in ~/.m2/settings.xml because it references the repository id in referenced POMs which can be those of transitive dependencies and can change if snapshots are used and need to be checked and eventually adjusted after every version change.
A couple of actions may be done:
The Common Build Problems: My builds are timing out - Travis CI answer provides a couple of solutions. One of them is «to extend the wait time» for the Maven process.
Enable caching of the Maven dependencies: Caching Dependencies and Directories: Caching directories (Bundler, dependencies): Arbitrary directories - Travis CI.
Use a repository manager: «act as dedicated proxy server for public Maven repositories».
Additional references:
Nexus example:
Maven Repositories - Nexus Repository Manager 3 - Sonatype Help. See «Browsing and Searching Maven Repositories» (general information) and «Configuring Apache Maven» (settings.xml-related information) sections.
«User manual» for the use case: Using Nexus 3 as Your Repository – Part 1: Maven Artifacts | TheNEXUS.
The general question: How does one mirror a maven repository?.
Enabling caching on Travis CI by adding
cache:
directories:
- $HOME/.m2
to .travis.yml turned out to be not the solution at all or only a temporary one (for approx. 40 builds over the last week; because mvnsearch.org became available again or for other reasons hard to figure out), I found the following more promising solution (which is way easier than setting up a Nexus repository manager instance which can be used as a mirror):
Add
- echo -e '<?xml version="1.0" encoding="UTF-8"?>\n<settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd" xmlns="http://maven.apache.org/SETTINGS/1.1.0"\n xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\n <mirrors>\n <mirror>\n <id>mvnsearch-unavailable</id>\n <name>mvnsearch-unavailable</name>\n <mirrorOf>mvnsearch</mirrorOf>\n <url>http://repo1.maven.org/maven2</url>\n </mirror>\n </mirrors>\n <profiles>\n <profile>\n <id>no-mvnsearch</id>\n <repositories>\n <repository>\n <id>mvnsearch</id>\n <url>http://www.mvnsearch.org/maven2</url>\n <releases>\n <enabled>true</enabled>\n </releases>\n <snapshots>\n <enabled>true</enabled>\n </snapshots>\n </repository>\n </repositories>\n </profile>\n </profiles>\n <activeProfiles>\n <activeProfile>no-mvnsearch</activeProfile>\n </activeProfiles>\n</settings>' > $HOME/.m2/settings.xml
- cat $HOME/.m2/settings.xml
to .travis.yml which will override uses of http://www.mvnsearch.org/maven2 in any hard to control transitive dependency and use the Maven central repository http://repo1.maven.org/maven2 which covered all dependencies in my case (it might not in other cases).
Note that Murphy's Law applies as it does to anything: Maven 3.1.1 ignores this setting even though it claims to use the mirror in its debug output (ouch!).
The build is now 7 minutes faster than it was with the temporary working caching solution.

Automatically detecting cyclic dependencies with Maven?

I want to automatically fail a build when a cyclic dependency is detected (to avoid build loops in Jenkins, among other things). The problem is the detection.
Maven 3 itself detects cyclic dependencies when the cyclic dependency is within the reactor (ie. executed from the same top-level module). Otherwise it is useless in that regard.
There is the extra maven enforcer rule banCircularDependencies. However, it seems to be limited to what "mvn dependency:tree" does, ie. it fails to recognize transitive test scope dependencies.
scope
The scope to filter by when resolving the dependency tree, or null to
include dependencies from all scopes. Note that this feature does not
currently work due to MNG-3236.
Is there any other solution to that problem?
One way is to set up a unit test using the JDepend API and assertions corresponding to what you want.
JDepend jdepend = new JDepend();
jdepend.addDirectory("target/classes");
jdepend.analyze();
// add assertion here;

Where can I see the default execution plan for a Maven plugin?

In a current project I am on, we use the flexmojos-plugin to compile a small Flex application. The plugin has all kinds of configuration, but there is no goal configured, and so I am wondering what makes Maven "know" what goals are to be executed or not?
The plugin has something like 25 goals, and as far as I can see, it does not run them all. Therefore I assume there must be some kind of configuration in the plugin that says which goals are to be executed by default - some kind of default execution. I looked at the source for the swf-compile Mojo, and I could not see anything like a "#default" annotation, so where is it configured?
The actual mapping of plugins' goals to lifecycle's phases results from packaging type and is provided within a plugin that defines this packaging (excluding predefined packagings like jar, ejb etc. that are provided by the Maven distribution).
For Flexmojos, you can find it here:
http://www.jarvana.com/jarvana/view/org/sonatype/flexmojos/flexmojos-maven-plugin/4.0-pre-alpha-1/flexmojos-maven-plugin-4.0-pre-alpha-1.jar!/META-INF/plexus/components.xml
This file defines Plexus' components of type LifecycleMapping that provide these mappings for its own packaging types: swc, swf, air.
If you go onto a particular goal than you see page which documents to which lifecycle phase this goal is bound to.
For example https://repository.sonatype.org/content/sites/maven-sites/flexmojos/3.8/compile-swc-mojo.html which is bound to the compile lifecycle phase. In the source code you can see to which lifecycle phase the goal is bound by #phase.
Furthermore if you do a simple mvn clean package you can see the goals in the output during the run. Things like the following:
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) # xsd ---

Categories

Resources