Maven-embedder 3.1.1


(Michel Krämer) #1

Hi!

I’m trying to use maven-embedder 3.1.1 with Gradle 1.9. Starting with version 3.1.0 Maven uses slf4j for logging. maven-embedder tries to configure the log level and then runs into the following error:

java.lang.NoClassDefFoundError: ch/qos/logback/classic/Level

I was able to reproduce the issue with the following minimal build script:

import org.slf4j.LoggerFactory
import ch.qos.logback.classic.LoggerContext
  task testLog << {
    //this is exactly what maven-embedder is doing
    //see org.apache.maven.cli.logging.impl.LogbackConfiguration
    def lf = (LoggerContext)LoggerFactory.getILoggerFactory()
    println(lf)
}

This script does not work, because slf4j is in the classpath but logback is not. I tried to add logback to the classpath, but this failed as well:

buildscript {
    repositories {
        mavenCentral()
    }
      dependencies {
        classpath 'ch.qos.logback:logback-classic:1.0.9'
    }
}
  import org.slf4j.LoggerFactory
import ch.qos.logback.classic.LoggerContext
  task testLog << {
    def lf = (LoggerContext)LoggerFactory.getILoggerFactory()
    println(lf)
}

I received the following error:

> Cannot cast object 'ch.qos.logback.classic.LoggerContext[default]' with class 'ch.qos.logback.classic.LoggerContext' to class 'ch.qos.logback.classic.LoggerContext'

Is there a solution for this?

Thanks, Michel


(Dmitry Maslakov) #2

Michel, have you managed to workaround this issue?


(Dmitry Maslakov) #3

Finally I found how to call maven using Ant which is integrated into gradle.

The idea is described at http://stackoverflow.com/questions/4120575/how-to-use-the-maven-ant-task-from-gradle

For me the following code works:

configurations {
 mavenAntTasks
}
  dependencies {
 mavenAntTasks 'org.apache.maven:maven-ant-tasks:2.1.3'
}
  task runMvn() << {
 ant.typedef(resource:'org/apache/maven/artifact/ant/antlib.xml',
   classpath: configurations.mavenAntTasks.asPath)
 ant.mvn(mavenVersion:'3.1.1', pom:file('pom.xml').toString(), failonerror:true) {
   arg(value:'package')
 }
}

The drawback is only missing output to console from maven build.


(Michel Krämer) #4

Nice solution, but doesn’t this fork another instance of Maven? What I wanted to do is use maven-embedder to make things faster and to save some resources.

I finally came up with the following solution which works at least in my setup. I’m using maven-embedder in my ‘buildSrc/build.gradle’:

dependencies {

compile ‘org.apache.maven:maven-embedder:3.1.1’

compile ‘org.apache.maven.wagon:wagon-http-lightweight:2.4’

compile ‘org.eclipse.aether:aether-connector-wagon:0.9.0.M2’

}

In order to override the Maven’s logging configuration I had to add a file named ‘buildSrc/src/main/resources/META-INF/maven/slf4j-configuration.properties’ with the following contents:

ch.qos.logback.classic.LoggerContext DummyLogbackConfiguration

Of course I had to implement this new ‘DummyLogbackConfiguration’ in ‘buildSrc/src/main/groovy/DummyLogbackConfiguration.groovy’.

import org.apache.maven.cli.logging.BaseSlf4jConfiguration
import org.apache.maven.cli.logging.Slf4jConfiguration.Level
    public class DummyLogbackConfiguration extends BaseSlf4jConfiguration {
    @Override
    public void setRootLoggerLevel(Level level) {
        // do not change Gradle's log level
    }
          @Override
    public void activate() {
        // no op
    }
}

I hope this helps. If you have questions, don’t hesitate to ask.

Cheers, Michel


(Dmitry Maslakov) #5

but doesn’t this fork another instance of Maven?

Michel, as Ant’s Mvn task is inherited from Ant’s Java task which allows manage forking with parameter ‘fork’, quite flexible.