In a crosswalk project I have the following dependency:
repositories {
maven {
url 'https://download.01.org/crosswalk/releases/crosswalk/android/maven2'
}
}
dependencies {
compile 'org.xwalk:xwalk_core_library:10.39.235.15'
}
This works, however I need version 13 which not available through the method above. I need to include:
https://download.01.org/crosswalk/releases/crosswalk/android/canary/13.41.313.0/crosswalk-13.41.313.0.aar
How would I set this up without downloading it locally first?
As suggested on this SO post, it's not supported so you have 2 options:
Write a gradle task that downloads it to a local lib directory
Manually add it to a maven repo that you have control of, and then depend on it as you would any other maven dependency.
Related
I want to use the sxcml-java library in my son's school's robotics code (currently a private repo).
The library uses Maven. I was able to successfully include the library in a test project using Maven.
However, I've just discovered that the existing robotics project code uses Gradle. I don't know either Maven or Gradle, and I haven't programmed in Java in almost 30 years.
How can I most easily use scxml-java - which itself has external 3rd party dependencies — in the robotics project?
This question is similar to this one, but the solution there was easy because both projects were using Gradle.
Provided the package is published in an artifactory, which is the case (See here), you can just include it as any other Gradle dependency (using groupId, artifactId and version), regardless of what build system was used to build it in the first place.
dependencies {
implementation 'com.nosolojava.fsm:scxml-java-implementation:1.0.1'
}
If you use IntelliJ IDEA, pasting the Maven dependency block into the build.gradle file will automatically convert it into the Gradle dependency format like the one above.
Please note however this does not apply to plugins, only to regular dependencies.
If You install your jar or third party jar into maven local repo like ~/.m2
you can add mavenLocal()
repositories {
mavenCentral()
// * Require by Use JAR install to Maven Local Repo your .m2
mavenLocal()
}
then add implementation to dependencies
dependencies {
implementation 'com.google.guava:guava:31.1-jre'
implementation 'yourGroupId:yourArtifactId:yourVersion'
}
Please mapping yourGroupId , yourArtifactId, yourVersion from your pom.xml
If You only download third party jar into foler like /home/yourName/your-libs
you can add configurations
configurations {
sxcml-java-lib
}
then add dependencies
dependencies {
implementation 'com.google.guava:guava:31.1-jre'
//sxcml-java-lib fileTree(dir: "${System.getProperty("user.home")}/libs", include: "*.jar")
sxcml-java-lib fileTree(dir: "/home/yourName/your-libs", include: "*.jar")
}
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'm working on a custom Gradle plugin. For some reason IntelliJ is unable to find the sources of the gradle-api artifact and only shows the decompiled .class file. I am already using the -all distribution of the Gradle Wrapper (which includes some sources, but apparently not the ones I need right here). Clicking Download... results in an error:
Sources not found: Sources for 'gradle-api-6.5.1.jar' not found
How do I correctly attach/choose sources for gradle-api in IntelliJ?
EDIT:
I have a minimal Gradle plugin with code like that (taken from the official samples):
plugins {
id 'java-gradle-plugin'
}
repositories {
jcenter()
}
dependencies {
testImplementation 'junit:junit:4.13'
}
gradlePlugin {
// ...
}
According to this excellent manual you should add gradleApi() as a runtimeOnly dependency:
dependencies {
//...
runtimeOnly(gradleApi())
I guess that, the default Intellij config use gradle from gradle-wrapper.properties file will use /gradle/wrapper/gradle-wrapper.jar, but it doesn't contain source code. what you need is a jar like gradle-wrapper-all.jar. But I don't know how to let Gradle redownload that. Just setting Wrapper.DistributionType.ALL is not working.
Solution
set Wrapper.DistributionType.ALL
wrapper {
jarFile = file(System.getProperty("user.dir") + '/gradle/wrapper/gradle-wrapper.jar')
gradleVersion = '6.7.1'
distributionType = Wrapper.DistributionType.ALL
}
I download Gradle, and use it. Set two things here and refresh it.
Here is the source code, the version is right and with all in the name (gradle-6.7.1-all):
delete gradle dir
run "gradle wrapper"
check the suffix "-all" in the file gradle/wrapper/gradle-wrapper.properties
sample:
distributionUrl=https://services.gradle.org/distributions/gradle-7.5-all.zip
Info: Using Gradle 2.14 on Windows 7 to build JAVA multi-projects.
When I'm building on my machine i want to use the libraries/subprojects on my machine.
When Jenkins is building the project, he shall use the libraries/subprojects from my repo.
So I made a "JenkinsTask" that just exist for my IF statement. This is already almost working the way I want it. Here the code from my root project gradle script:
task JenkinsTask() {
//doing nothing
}
def ProjectB_Version //defined on command line
gradle.taskGraph.whenReady {taskGraph ->
if (taskGraph.hasTask(JenkinsTask)) {
println "Archiva dependency"
dependencies {
compile group: 'Lib_ProjectB', name: 'ProjectB', version: ProjectB_Version
}
}
else {
println "Filesystem dependency"
dependencies {
compile fileTree(dir: 'ProjectB\\build\\libs', includes: ['*.jar'])
}
}
}
compileJava.dependsOn ":ProjectB:build"
On my machine I just run gradle build -PProjectB_Version=0.5
On Jenkins I run gradle :build jenkinstask -x :ProjectB:build -PProjectB_Version=0.5
Now the question is if there is a "gradle" way to do this? So I wouldn't need the if/else statement and maybe even could relinquish the "-x" paramater Jenkins command line. Especially the "Jenkinstask" feels like a hack.
Thank you in advance.
I'm not sure if it's considered as a gradle way, but I think you should declare dependencies in the same way regardless of who builds the project and where.
Instead I think you should:
define artifacts repositories depending on the build environment,
base decision on a command line argument instead of checking for a task in the task execution graph.
This way you will be able to have automatic pom generation for your project locally as well because for that gradle needs to know artifact group and name. And the build script would look cleaner in my opinion.
Just place something like this somewhere before all your tasks:
if (project.hasProperty('jenkins')) {
repositories {
maven {
url "${jenkinsRepoUrl}"
}
}
} else {
repositories {
mavenLocal()
mavenCentral()
}
}
dependencies {
compile (
['commons-lang:commons-lang:2.4'],
["Lib_ProjectB:ProjectB:${ProjectB_Version}"],
}
}
And run the build as gradle clean build -PProjectB_Version=0.5 locally and as gradle clean build -Pjenkins -PProjectB_Version=0.5 -PjenkinsRepoUrl=https://nexuscn.my-company.com/content/repositories/main on Jenkins.
P.S.: I would declare the ProjectB_Version property in project gradle.properties instead since your code is likely to depend on the actual version API.
I'm new to Android developpement and I tried to install the Facebook SDK in my Android Studio project.
Then, I have a bug in build.gradle :
Error:(111, 0) Cannot call getBootClasspath() before setTargetInfo() is called.
So I searched for a solution and I found this on the stack:
This is a known issue , which is fixed by updating gradle to :
dependencies {
classpath 'com.android.tools.build:gradle:1.1.2'
}
So I tried this but then I got the error:
Error:Could not find com.android.tools.build:gradle:1.1.2.
Searched in the following locations:
file:/home/roman/Documents/softs/android-studio/gradle/m2repository/com/android/tools/build/gradle/1.1.2/gradle-1.1.2.pom
file:/home/roman/Documents/softs/android-studio/gradle/m2repository/com/android/tools/build/gradle/1.1.2/gradle-1.1.2.jar
Required by:
Yoki:facebook:unspecified
So I moved into the specified directory and then there is only this:
$> ls
1.0.0 1.1.0
$> pwd
/home/roman/Documents/softs/android-studio/gradle/m2repository/com/android/tools/build/gradle
How can I update the gradle plugin?
Change your buildscript block. You have to specify also in this block the repositories.
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.1.2'
}
}
Also you can use the last version:
classpath 'com.android.tools.build:gradle:1.1.3'
There are three type of dependency in Android gradle file.
1. Module dependency: other local project.
2. Local dependency: in your sdk path extras folder.
3. Remote dependency: JCenter, MavenCenter or third party maven path.
'com.android.tools.build:gradle' is local dependency, so you have to check your sdk and update.
P.S. If you tired with the version issue, you can try andle.
It's an open source project to update your Android dependency version automatically.
See https://github.com/Jintin/andle for more information