gradle with maven submodule - maven

There is any way to build gradle project with maven submodule ? I created a project in gradle but at now I must add module (that module used a maven) I don't have any idea how to used this. There is any good way?
I will be very gratefull for any suggestions.

Either convert the Maven project to Gradle (gradle init is a good start) and turn the Gradle build into a multi-project build, or publish the Maven build's artifact to the local or a remote Maven repository, and configure the Gradle build to consume it from there (or the other way around).

Create a build.gradle(.kts) that wraps the Maven project in its root directory:
val build = task<Exec>("build") {
commandLine("mvn", "package")
}
val default by configurations.creating {
isCanBeConsumed = true
isCanBeResolved = false
}
artifacts {
add(default.name, File("$projectDir/target/<name of the jar>.jar")) {
builtBy(build)
}
}
You can then depend on it like this:
implementation(project(":<path to the module>", "default"))

Related

How to publish to Artifactory with Gradle without publishing dependent projects

I'm updating some build.gradle files to add Artifactory publishing. In some cases I want to publish the top level project's artifacts without publishing artifacts for its dependent projects. The dependent projects get published on their own or when built by a different project.
I've added basic publishing and artifactory tasks to the build.gradle files and they work, but for example if there's a project called "api" that has a dependent project called "db", when I run the build.gradle for "api", it publishes the artifacts for both "api" and "db". I want it to only publish the api artifacts.
I'm not having much luck finding what I want on Jfrog's site. The documentation mentions "Use the artifactoryPublish.skip flag to deactivate analysis and publication", but honestly I don't know what to do with that and if it would help in my case.
The gradle scripts are referencing dependencies like this:
implementation project(path: ':db', configuration: 'default')
I've run the builds in both Eclipse and Jenkins. We use Gradle 7.4. I'm calling the clean, build, and artifactoryPublish tasks. I suspect there's probably an easy way to do this, and I'm just not seeing it.
For reference, this is my publishing task:
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
And here's the publish part of the artifactory section:
publish {
repository {
repoKey = 'libs-release-local'
username = "${artifactory_user}"
password = "${artifactory_password}"
ivy {
ivyLayout = '[organization]/[module]/[revision]/ivy-[revision].xml'
artifactLayout = '[organization]/[module]/[revision]/[artifact]-[revision].[ext]'
mavenCompatible = true
}
}
defaults {
publications('mavenJava')
publishArtifacts = true
properties = ['qa.level': 'basic', 'dev.team' : 'core']
publishPom = true
publishIvy = true
}
}
I found an answer. For a project that has "db" as a dependency, after the dependencies section of my build.gradle file, I added the following:
gradle.startParameter.excludedTaskNames += "db:artifactoryPublish"
Now when I run the artifactoryPublish task for the api project, it does not execute for the db project, too.
For excluding the "db" project from publishing to Artifactory, you can add the following in your build.gradle file:
project('db') {
artifactoryPublish.skip = true
}

How to check where gradle is downloading its dependencies from?

I have a project using gradle from building and due to some recent jcenter issues, we want to move all our dependencies to our artifactory. Now i have all the configuration ready and declared inside the gradle build files. I have also removed all traces of other maven repositories.
repositories {
maven {
url "${artifactory_contextUrl}/repo_name-generic"
credentials {
username = "${artifactory_user}"
password = "${artifactory_password}"
}
}
}
After doing a gradle clean build, i expected a lot of errors as i have never added those dependencies to our artifactory repo, but none came. The project builds fine and i can see them being downloaded.
My question now is, why is it working?
Is there a way i can check from which source the dependencies are coming from?
Also in artifactories GUI i cannot locate the packages inside the specified repo
Thanks!
If you ant to print the repositories a project is using, the following task will do it for you:
task printRepos {
doFirst {
project.repositories { repositories ->
repositories.forEach { repo ->
println("${repo.name}: ${repo.url}")
}
}
}
}
If you add it to your gradle build and invoke it gradle printRepos, you should get the repositories printed out
For more information regarding the API, check: https://docs.gradle.org/current/javadoc/org/gradle/api/artifacts/dsl/RepositoryHandler.html
https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html
Also thanks to Bjorn for pointing out the doFirst/doLast problem.
rm -rf ~/.gradle/caches
./gradlew assembleDebug -i > ~/Desktop/dump
search dependency lib in dump file to check where it was downloaded from
For example, flexbox-2.0.1 was downloaded from jcenter:

Multi-project gradle build with Nexus artifact repository

Consider the following multi-project gradle build, where ProjectA depends on ProjectB, and ProjectB depends on ProjectC. Dependencies are specified in the form compile project(':ProjectX'). This requires that each project be checked out in order to build, say, ProjectA.
I want to use an artifact repo such as Sonatype Nexus, to make the build simpler for developers so that if they are only working on ProjectA, then they do not need to have the dependent projects checked out, and they can be retrieved from Nexus. Similarly, if you are working on the dependent projects and they are checked out locally, I want them to be build instead of being retrieved from Nexus.
In summary, the dependency resolution strategy is: If project dependency and checked out, build locally, else retrieve from Nexus
How can I achieve this in gradle?
I got this working by flipping my dependency definitions from compile project(':ProjectX') to compile "my-group:ProjectX:version", and use the following dependency substitution resolution strategy:
configurations.all {
resolutionStrategy.dependencySubstitution.all { DependencySubstitution dependency ->
if (dependency.requested instanceof ModuleComponentSelector && dependency.requested.group == "my-group") {
def proj = "${dependency.requested.module}"
if (new File(rootDir, '../' + proj).exists()) {
dependency.useTarget findProject(":${proj}")
}
}
}
}

maven project as dependency in gradle project

I have a project which is using Gradle as build tool and a second subproject which is using Maven's POM. I don't have the freedom of changing build tool on the subproject.
What I want to achieve is to add my project with Maven POM as dependency on my Gradle project.
Where root (current dir) is my project with Gradle and contains the build.gradle, the Maven project is under vendor/other-proj/ with POM file just under that directory.
I have tried these variations on my build.gradle file:
1st try:
include("vendor/other-proj/")
project(':other-proj') {
projectDir = new File("vendor/other-proj/pom.xml")
}
dependencies {
compile project(':other-proj')
}
2nd try:
dependencies {
compile project('vendor/other-proj/')
}
3rd try:
dependencies {
compile project('vendor/other-proj/pom.xml')
}
4th try:
dependencies {
compile files 'vendor/other-proj/pom.xml'
}
I can't find anything related on the web, it seems most Gradle/Maven use cases are affected by publishing to Maven or generating POM, but I dont want to do any of those.
Can anybody point me to right direction?
you can "fake" including a Maven project like this:
dependencies {
compile files("vendor/other-proj/target/classes") {
builtBy "compileMavenProject"
}
}
task compileMavenProject(type: Exec) {
workingDir "vendor/other-proj/"
commandLine "/usr/bin/mvn", "clean", "compile"
}
This way Gradle will execute a Maven build (compileMavenProject) before compiling. But be aware that it is not a Gradle "project" in the traditional sense and will not show up, e.g. if you run gradle dependencies. It is just a hack to include the compiled class files in your Gradle project.
Edit:
You can use a similar technique to also include the maven dependencies:
dependencies {
compile files("vendor/other-proj/target/classes") {
builtBy "compileMavenProject"
}
compile files("vendor/other-proj/target/libs") {
builtBy "downloadMavenDependencies"
}
}
task compileMavenProject(type: Exec) {
workingDir "vendor/other-proj/"
commandLine "/usr/bin/mvn", "clean", "compile"
}
task downloadMavenDependencies(type: Exec) {
workingDir "vendor/other-proj/"
commandLine "/usr/bin/mvn", "dependency:copy-dependencies", "-DoutputDirectory=target/libs"
}
You cannot "include" a maven project in gradle settings.gradle. The simplest way would be to build the maven project and install it to your local repo using mvn install(can be default .m2, or any other custom location) and then consume it from your gradle project using groupname:modulename:version
repositories{
mavenLocal()
}
dependencies{
implementation 'vendor:otherproj:version'
}
It is possible to depend directly on the jar of the maven project using compile files but this isn't ideal because it wont fetch transitive dependencies and you'll have to add those manually yourself.

How can integrate gradle project wih Eclipse (maven) based instrumentation tests

I have an android project in AndroidStudio, but we must outsource the Instrumentation test to Eclipse (simple Java projet which builded by maven). I don't would like to tell the whole development and QA story about why, I'm just kindly asking can anyone tell me, who can I integrate an maven independed instrumentation test project with my Android Studio based project ?
In gradle you can make a .jar from your project by building it, and then you can publish the .jar artifact to any maven repo (check this if your are not familiar with artifact publishing).
Something like this:
artifacts {
archives file("path/to/your/project_output.jar")
}
uploadArchives {
repositories {
mavenDeployer {
repository(url: "file://${System.env.HOME}/.m2/repository/")
pom.groupId = 'com.yourcompany'
pom.artifactId = 'yourartifactid'
pom.version = '0.1.0'
}
}
}
This will publish your project's compiled jar files to your local maven repository.
Look for the .jar file in the build/intermediates/... folder (classes.jar its default name I think)
Also, you should publish your .apk file too if your test project needs it.

Resources