I want to reuse the dependencies defined in this pom.xml file It's quite a long list of dependices. I want to reuse it for convenience.
so I added a line in my build.gradle file like this.:
dependencies {
// unfortunately, Gradle seems just ignore this line.
compile("org.activiti:activiti-ui-root:6.0.0")
}
But it seems that gradle just ingore this line. What's the best way of reusing a pom file if I don't want to rewrite a long list of dependencies?
Please give me some advise, many thanks.
==============================
Thanks, all you guys. finally I find "io.spring.gradle:dependency-management-plugin" helps to solve my problem.
#madhead is right. pom.xml just provide the version of jars, but will not import any file into my project.
That pom.xml does not actually define any dependencies, it only defines versions of artifacts in dependencyManagement block. Thus, depending on this artifact in Gradle does not bring any transitive dependencies in your project (neither it will in Maven, btw).
but it's OK. the version information is enough.
This segment is what I use to solve my problem.
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath "io.spring.gradle:dependency-management-plugin:1.0.3.RELEASE"
} }
.......
project(':editor-image-generator') {
dependencyManagement {
imports {
// import the pom.xml from outside.
mavenBom "org.activiti:activiti-ui-root:6.0.0"
}
}
dependencies {
// It's good to see that, you don't need to specify the version here.
// with the mavenBom imported above, you can always get the right version.
compile("org.activiti:activiti-bpmn-model")
testCompile("org.activiti:activiti-bpmn-converter")
compile("org.activiti:activiti-image-generator")
compile("org.imgscalr:imgscalr-lib:4.2")
compile("org.slf4j:slf4j-api")
testCompile("commons-io:commons-io")
testCompile("junit:junit")
}
}
That pom.xml does not actually define any dependencies, it only defines versions of artifacts in dependencyManagement block. Thus, depending on this artifact in Gradle does not bring any transitive dependencies in your project (neither it will in Maven, btw).
What you can try in Spring's dependency management plugin for Gradle. It allows to reuse that dependencyManagement block definition for BOMs in Gradle.
Related
It's probably very simple, but only to people who know what they are doing.
I have a Java program that imports these two:
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
As an aside, I don't want to use the lang3 package but the lang package.
I do not have anything in my Gradle file about these. When I try to build the file, it gives me errors for these two, saying the packages do not exist.
My questions are:
Do I need to add them as "compile" or as "api"?
What is the exact syntax? I have lines that look like this:
api group: 'commons-httpclient', name: 'commons-httpclient', version: '3.1'
How do I find the right name (or should I just invent one)? and the version?
Anything your code needs (besides basic JRE classes) is a dependency for your code. Gradle manages these dependencies, usually downloading them from a repository.
First you need to find such a repository. You probably have repositories already configured in your build.gradle, like so:
buildscript {
repositories {
mavenCentral()
// maybe more repositories
}
}
That means Gradle will try to download dependencies from Maven Central. You can either do a web search for "gradle" and your dependency, or go to repository and search, or check the dependency's homepage.
You'll end up with a dependency name and version like 'org.apache.commons:commons-lang3:3.12.0'. This needs to go in your build.gradle.
Gradle has different dependencies:
buildscript dependencies provide code that Gradle needs to execute to build your project, e.g., a tool to pull in version control system information or generate code
implementation dependencies are dependencies your code needs to run, like a logging framework or JSON parser or PDF generator
test dependencies are dependencies needed to run your automated tests, like JUnit
Depending on where you need the dependency, you put it in the buildscript or the dependencies block.
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.tmatesoft.svnkit:svnkit:1.9.+'
}
}
dependencies {
implementation 'pdfbox:pdfbox:0.7.3'
testImplementation 'junit:junit:4.+'
}
You don't need to repeat the implementation dependencies for the testImplementation btw, as it inherits them automatically.
You can define your own configurations as need; see the Gradle manual on dependencies, for example if you have different test suites (unit, integration, performance, ...) that need different dependencies.
you'll have to go to their official website and get the implementations then add those to the dependencies(you'll find it at the bottom of the file) in the build.gradle(module) it would look something like -
the $lifecycle_version might be somethiing like 1.2.3 or some version number.
this is what I got (not exactly sure if this is right)-
implementation 'org.apache.commons:commons-lang3:3.12.0'
got from library website in the gradle short tab
in the build.gradle(project), look for maven repo.
Once done, you'll be able to import the respective libraries.
I have a gradle monolithic project with too many dependencies.
I'd like to explode it into many sub-projects and publish all sub-projects (build + sources + javadoc) + an extra project being the merge of all sub-projects.
This extra project should be like a virtual artifact with all my projects in a single jar like it is today because I don't want a too big change for my users.
The jar must not include dependencies (it is not an uber-jar) but the resulted pom.xml must contain the dependencies of all sub-projects (the generated pom.xml of the maven artifact must contain all dependencies).
The virtual artifact will include the merge of javadoc and sources too in order to respect Maven Central conventions.
Current state:
Project Main, generate
pom.xml
main.jar
main-sources.jar
main-javadoc.jar
Expected state:
Subproject A, generate
A-pom.xml
A.jar
A-sources.jar
A-javadoc.jar
Subproject B, generate
B-pom.xml
B.jar
B-sources.jar
B-javadoc.jar
virtal-Project Main, generate
pom.xml=A-pom.xml+B-pom.xml
main.jar=A.jar+B.jar
main-sources.jar=A-sources.jar+B-sources.jar
main-javadoc.jar=A-javadoc.jar+B-javadoc.jar
How can I manage it?
We have been in exactly the same situation for some time now. We want to publish a single artifact for our clients to depend on, although internally the product is developed through a few separate component projects. I got it done eventually (with compromises), and here is what I learned:
Merging jars is not as straightforward as it looks like because there could be things like resource files within a jar that are not
always namespace-ed. It is possible that two of your jars have a
resource file with the same name, in which case you will have to
merge the content of those files.
Javadoc is very hard to merge without accessing the original source
files because it has summary pages (index pages).
So my advice would be:
Think twice, maybe what you really want is NOT a single jar, but a single dependency for your clients? These are different. You can easily have a pom only artifact. Depending on this pom only artifact will simply translates transitively into depending on individual artifacts of your component sub projects. To your client, practically, nothing is changed. Spring Boot takes this approach. To do it, you can create an empty java-library project, make all your component projects its api dependency. You don't even need any source code in this project.
If you really want to merge into a single jar, you can try building a fat jar with customization. The customization is not to pull in 3rd party dependencies.
We use the Gradle Shadow plugin for merging jars. Its original purpose was to build a fat jar, which will include all the transitive dependencies. But it also has a special "shadow" configuration, to which you can add dependencies if you want the dependencies to be exported into POM rather than bundled. So what you need to do:
Define a non-transitive configuration (say bundler) to which you will add your sub-project as dependencies. This is going to be the target configuration for the Gradle Shadow plugin.
Define a transitive configuration (bundlerTransitive) that extends from your non-transitive one. This will be manually resolved in order to find the 3rd party dependencies
in your build.gradle, register an afterEvaluate closure, where you find the level two dependencies of the resolved transitive configuration, add them to the shadow configuration. The reason for level-two is that level one dependencies will be your sub-project artifacts.
After all the above, the artifact produced by shadowJar task is the one to be uploaded to maven. You will need to configure the shadowJar task to remove the classifier (which is shadow by default)
Here is a complete example (build.gradle) of bundling vertx-web and all its dependencies within the io.vertx group:
plugins {
id 'java'
id 'maven-publish'
id 'com.github.johnrengelman.shadow' version '5.2.0'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
configurations {
bundler {
transitive = false
}
bundlerTansitive {
extendsFrom bundler
transitive = true
}
}
dependencies {
bundler "io.vertx:vertx-web:4.0.0"
bundler "io.vertx:vertx-web-common:4.0.0"
bundler "io.vertx:vertx-core:4.0.0"
bundler "io.vertx:vertx-auth-common:4.0.0"
bundler "io.vertx:vertx-bridge-common:4.0.0"
}
shadowJar {
configurations = [project.configurations.bundler]
classifier ''
}
publishing {
publications {
shadow(MavenPublication) { publication ->
project.shadow.component(publication)
}
}
}
project.afterEvaluate {
// this is needed because your sub-projects might have inter-dependencies
def isBundled = { ResolvedDependency dep ->
return configurations.bundler.dependencies.any {
dep.moduleGroup == it.group && dep.moduleName == it.name
}
}
logger.lifecycle '\nBundled artifacts and their 1st level dependencies:'
// level one dependencies
configurations.bundlerTansitive.resolvedConfiguration.firstLevelModuleDependencies.forEach {
logger.lifecycle "+--- ${it.getName()}"
// level two dependencies
it.children.findAll({ ResolvedDependency dep -> !isBundled(dep) })
.forEach { ResolvedDependency dep ->
logger.lifecycle "| +--- ${dep.name}"
project.dependencies.add('shadow', [group: dep.moduleGroup, name: dep.moduleName, version: dep.moduleVersion])
}
}
logger.lifecycle '\nExported Dependencies:'
configurations.shadow.getResolvedConfiguration().getFirstLevelModuleDependencies().forEach {
project.logger.lifecycle "+--- ${it.getName()}"
}
}
For javadoc if you don't care about the index (compromise, as I said), then it is just a jar task with a copy spec:
configurations {
javadoc {
transitive = false
}
}
dependencies {
javadoc 'com.my:component-a:1.1.0:javadoc'
javadoc 'com.my:component-b:1.1.0:javadoc'
javadoc 'com.my:component-c:1.1.0:javadoc'
javadoc 'com.my:component-d:1.1.0:javadoc'
}
task javadocFatJar(type: Jar) {
archiveClassifier.set('javadoc')
from {
configurations.javadoc.collect { it.isDirectory() ? it : zipTree(it) }
}
with jar
}
This cannot be done with maven-publish directly, but one can add individual java-library modules and package each of them with sources and docs. With Gradle this would be a simple jar task, but when the artifacts are publicly available ...such transitive dependencies should better be provided by a meta package; nothing but Maven (Local/Central) dependencies, instead of embedded JARS. In this case, this would be just another module (which obviously would only build after having published the others).
And concerning the concept, that it would require any "merged" JavaDocs ...
https://central.sonatype.org/pages/requirements.html#supply-javadoc-and-sources
While they're referenced (Maven Central) in *.pom, Gradle will be able to find them.
Just use repository mavenLocal() instead of mavenCentral() for testing purposes.
I am unable to force a version of a dependency using Gradle. My goal is to use version 0.20.0.RELEASE of the Spring HATEOAS library, but despite all my efforts it keeps resolving to 0.19.0.RELEASE.
I have attempted a number of strategies, both in isolation and in combination with one another. These strategies include, but are possibly not limited to, the following (note that in all cases $springHateoasVersionis defined in the gradle.properties file that resides in the directory that is the parent of the directory for the module declaring the Spring HATEOAS dependency):
#1 (in the build.gradle file for the module that declares the dependency)
apply plugin: 'io.spring.dependency-management'
dependencyManagement {
dependencies {
dependency group:'org.springframework.hateoas', name:'spring-hateoas', version:"$springHateoasVersion"
}
}
#2 (in the build.gradle file for the module that declares the dependency)
compile ("org.springframework.hateoas:spring-hateoas:$springHateoasVersion") { force = true }
#3 (in the build.gradle file of the parent directory)
subprojects {
configurations.all {
resolutionStrategy {
force "org.springframework.hateoas:spring-hateoas:$springHateoasVersion"
}
}
}
I have done my best to research this problem:
This question has an accepted answer, but doesn't seem like an exact match for the problem that I'm experiencing: How can I force Gradle to set the same version for two dependencies?
Neither of these questions seem to have accepted answers: 1) Gradle is not honoring resolutionStrategy.force, 2) Forcing a module version has no effect on generated org.eclipse.wst.common.component.
In addition to the fact that my project is broken (because I'm using the wrong version of Spring HATEOAS), I can explicitly see that Gradle is "consciously" selecting the incorrect dependency version despite all my protestations. When I run ./gradlew dependencyInsight --dependency spring-hateoas, I see the following output:
org.springframework.hateoas:spring-hateoas:0.19.0.RELEASE (selected by rule)
org.springframework.hateoas:spring-hateoas:0.20.0.RELEASE -> 0.19.0.RELEASE
\--- project :Commons
\--- compile
Despite the name, the dependencyInsight task provides surprisingly little insight into which rule caused Gradle to select the inappropriate dependency version, let alone how I might go about circumventing said rule.
I found the solution to this problem here. Of course this was the one thing I didn't try because it "didn't seem material". :-/
In order to get things working, I added the following to the build.gradle file of the parent directory (relative to the directory for the module that declared the dependency on Spring HATEOAS).
subprojects {
apply plugin: 'io.spring.dependency-management'
dependencyManagement {
applyMavenExclusions false
}
ext['spring-hateoas.version'] = "$springHateoasVersion"
}
honored by e.g.
allprojects {
repositories {
exclusiveContent {
filter {
includeGroup "com.facebook.react"
}
forRepository {
maven {
url "$rootDir/../node_modules/react-native/android"
}
}
}
}
...
}
ref to https://github.com/facebook/react-native/issues/35204#issuecomment-1304740228
To specify a Maven dependency in my project, I provide a name, a group id, and a version. This has been enough for every dependency in my project, save one. Pig has multiple jars in the same artifact (not sure if I have the proper nomenclature; I'm still rather new to Maven), but I only need one.
Specifically, I need pig-0.13.0-h2.jar. However, when I provide the dependency
compile "org.apache.pig:pig:0.13.0"
in my build.gradle, only pig-0.13.0.jar, pig-0.13.0-sources.jar, and pig-0.13.0.pom are downloaded. I need the "*-h2.jar", because that's the correct one to work with my version of Hadoop.
Is there a way to tell Gradle (and, generally, Maven or whatever) that my compile dependency requires this exact jar, and that only this one should be included in the classpath?
What you need is to specify the classifier. The following script will do the job:
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
compile "org.apache.pig:pig:0.13.0:h2"
}
task copyDeps(type: Copy) {
from configurations.compile
into 'deps'
}
How do I configure build.gradle to depend on LWJGL?
I'm new to Gradle, and how to configure library dependencies is clear as mud to me.
It's my understanding is that one can specify library dependencies for Gradle to download rather than checking them in to source control, but any sort of help with configuring things would be appreciated.
(I don't know any Ivy or Maven.)
I think what you want is to have lwjgl in your build classpath and resolve it automatically right?
try this snippet:
plugins {
id "java"
}
repositories{
maven {
url = "http://adterrasperaspera.com/lwjgl"
}
}
dependencies{
implementation "org.lwjgl:lwjgl:2.6"
implementation "org.lwjgl:lwjgl-util:2.6"
}
This snippet above defines a maven repository which contains the lwjgl libs and defines two compile dependencies to your project.
regards,
René