birgersp
birgersp

Reputation: 4916

How can I build a Maven project, as a dependency to the root project, with Gradle?

I have a root project with multiple subprojects. Initially, we've kept the projects as separate Maven projects but I've realized Gradle is much more suitable for me to use. But for one of the subprojects we'd rather not convert it to a Gradle project, but keep it as a Maven project.

So I've tried to keep a Maven project as a subproject to a Gradle project, but building fails because the dependencies listed in the Maven projects pom.xml are not included. Below is my experiment

Folder/project structure

root (gradle root project)
|- api (maven project)
|- project (gradle subproject, depends on the "api" project)

root/settings.gradle

rootProject.name = 'root'

def subDirs = rootDir.listFiles(new FileFilter() {
    public boolean accept(File file) {
        if (!file.isDirectory()) {
            return false
        }
        if (file.name == 'buildSrc') {
            return false
        }
        return new File(file, 'build.gradle').isFile()
    }
});

subDirs.each { File dir ->
    include dir.name
}

root/build.gradle

import org.gradle.api.artifacts.*

apply plugin: 'base' // To add "clean" task to the root project.

subprojects {
    apply from: rootProject.file('common.gradle')
}

task mergedJavadoc(type: Javadoc, description: 'Creates Javadoc from all the projects.') {
    title = 'All modules'
    destinationDir = new File(project.buildDir, 'merged-javadoc')

    // Note: The closures below are executed lazily.
    source {
       subprojects*.sourceSets*.main*.allSource
    }
    classpath.from {
        subprojects*.configurations*.compile*.copyRecursive({ !(it instanceof ProjectDependency); })*.resolve()
    }
}

root/common.gradle

//
// This file is to be applied to every subproject.
//

apply plugin: 'java'
apply plugin: 'maven'

String mavenGroupId = 'com.mycompany.myproject'
String mavenVersion = '1.0-SNAPSHOT'

sourceCompatibility = '1.8'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

repositories {
    mavenCentral();
    // You may define additional repositories, or even remove "mavenCentral()".
    // Read more about repositories here:
    //   http://www.gradle.org/docs/current/userguide/dependency_management.html#sec:repositories
}

dependencies {
    // Adding dependencies here will add the dependencies to each subproject.
    testCompile group: 'junit', name: 'junit', version: '4.10'
}

String mavenArtifactId = name

group = mavenGroupId
version = mavenVersion

task sourcesJar(type: Jar, dependsOn: classes, description: 'Creates a jar from the source files.') {
    classifier = 'sources'
    from sourceSets.main.allSource
}

artifacts {
    archives jar
    archives sourcesJar
}

configure(install.repositories.mavenInstaller) {
    pom.project {
        groupId = mavenGroupId
        artifactId = mavenArtifactId
        version = mavenVersion
    }
}

task createFolders(description: 'Creates the source folders if they do not exist.') doLast {
    sourceSets*.allSource*.srcDirs*.each { File srcDir ->
        if (!srcDir.isDirectory()) {
            println "Creating source folder: ${srcDir}"
            srcDir.mkdirs()
        }
    }
}

root/api/pom.xml

<?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.mycompany.myproject</groupId>
    <artifactId>api</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/de.dev-eth0.dummycreator/dummy-creator -->
        <dependency>
            <groupId>de.dev-eth0.dummycreator</groupId>
            <artifactId>dummy-creator</artifactId>
            <version>1.3</version>
        </dependency>
    </dependencies>
</project>

root/project/build.gradle

if (!hasProperty('mainClass')) {
    ext.mainClass = 'com.mycompany.myproject.HelloWorld'
}

dependencies {
    compile project(":api")
}

root/api/src/main/java/com/mycompany/myproject/api/Api.java

package com.mycompany.myproject.api;

import org.dummycreator.DummyCreator;

public class Api {

    public static void sayHello() {
        System.out.println("Hello from API!");

        DummyCreator dc = new DummyCreator();
        Integer integer = dc.create(Integer.class);

        System.out.println("Integer: " + integer);
    }
}

When building "project", I get the following output:

Executing: gradle build
Arguments: [-c, C:\Users\birger\Desktop\test\root\settings.gradle]

C:\Users\birger\Desktop\test\root\api\src\main\java\com\mycompany\myproject\api\Api.java:3: error: package org.dummycreator does not exist
import org.dummycreator.DummyCreator;
                       ^
C:\Users\birger\Desktop\test\root\api\src\main\java\com\mycompany\myproject\api\Api.java:10: error: cannot find symbol
        DummyCreator dc = new DummyCreator();
        ^
  symbol:   class DummyCreator
  location: class Api
C:\Users\birger\Desktop\test\root\api\src\main\java\com\mycompany\myproject\api\Api.java:10: error: cannot find symbol
        DummyCreator dc = new DummyCreator();
                              ^
  symbol:   class DummyCreator
  location: class Api
3 errors
:api:compileJava FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':api:compileJava'.
> Compilation failed; see the compiler error output for details.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 0.106 secs



Build failure (see the Notifications window for stacktrace): gradle build

So, what's the easiest way to make the Maven subproject "build as normal", as a subproject of the Gradle root project, without actually having to convert it to a Gradle project?

Upvotes: 1

Views: 1083

Answers (1)

lance-java
lance-java

Reputation: 27994

If you called mvn install on the maven project, you could then use

repositories { 
    mavenLocal()
}

in the gradle project to depend on the jar via group/artifact/version. With gradle's maven dependency integration you would then get all of the transitive dependencies from the pom

Upvotes: 0

Related Questions