Does Gradle flatDir enable jar builds? - java

I'm using Gradle flatDir local repository and I wonder if I would be able to use a compiled jar of my program, without needing to manually generate POM. Will Gradle still build and use the dependencies in this situation?
repositories {
flatDir {
dirs 'D:/path/to/local/directory'
}
}

Yes, Gradle can find jars in the local directory
if you have D:/path/to/local/directory/myjar-1.0.jar, you could use it like this...
repositories {
flatDir {
name 'localrepo'
dirs 'D:/path/to/local/directory'
}
}
...
implementation name:'myjar', version: '1.0'
I'd recommend using a local path to the project, like $rootDir/libs. Note, for a multi-module gradle project don't use
dirs "libs"
because it will look for libs in each module, not in the parent directory.
Instead it's probably better to put all the jars in $rootDir/libs and use this:
dirs new java.io.File(rootDir, "libs")

Related

How to make Gradle flatDir read nested folders?

I'm using the Gradle local flatDir repository in the following way:
repositories {
flatDir {
dirs 'D:/path/to/local/directory'
}
}
but it only searches for the first layer of files. I wonder if there is an option of telling Gradle to locate the dependencies all over the repository, so I would be able to organize my jars by groups and still make Gradle read them all without specifying the groups.
Have you considered using the Maven directory conventions instead of flatDir?
Eg store jars like
myLocalRepo/com/foo/bar/1.0/bar-1.0.jar
myLocalRepo/com/foo/baz/2.0/baz-2.0.jar
Then in build.gradle
repositories {
maven {
uri file('myLocalRepo')
}
}
dependencies {
compile 'com.foo:bar:1.0'
compile 'com.foo:baz:2.0'
}

Add gradle dependencies(build.gradle) in .aar file Android

I am having an android library project which is using third party libraries. I have created it's .aar file and imported the .aar file in a different project. Classes and resources are imported but the gradle libraries are not imported. I don't want to mention those dependencies again in the project.
Is there any way to import that project with .aar file or something else which include build.gradle or dependencies.
If you are including this library in dependencies block then try to use api instead of implementation.
AAR file does not include external dependencies which are mention in app/build.gradle so instead of adding it directly we upload to local maven and integrate it.
To upload it in your local maven you can add the following function in app/build.gradle
apply plugin: 'maven'
uploadArchives {
repositories {
mavenDeployer {
repository(url: "file://localhost" + System.getenv("HOME") + "/.m2/repository")
pom.version = '1.0-SNAPSHOT'
pom.groupId = 'your.package'
pom.artifactId = 'sdk-name'
}
}
}
You can change the pom version, groupId and artifactId according to how you want to use it.
If this process is completed you can integrate the library.
In the app/build.gradle of the project in which you want to add the
library specify the path.
implementation 'your.package:sdk-name:1.0-SNAPSHOT'
In the project/build.gradle add the following
allprojects{
...
mavenLocal()
}
This will search for the library in the local machine.
If still, you get some error try to invalidate caches and restart the android-studio from the File Menu.

How to install a compiled by Gradle jar into the local Gradle Repository files-2.1 instead of the Maven repository?

In my build.gradle, I added the plugin:
apply plugin: 'maven'
Then using gradle install I can copy the resulted jar into the maven repository : ~/.m2/repository
However, my Gradle repository resides in ~/.gradle/caches/modules-2/files-2.1. How can I install the jar into this repository?
What worked for me is gradle install -Dmaven.repo.local=the/path/of/the/folder.
I don't know which IDE you are using but in eclipse you can add a new Run Configuration, in Gradle taks add install and in program arguments -Dmaven.repo.local=the/path/of/the/folder.
If you insist on manipulating the cache, then your best bet is to write a shell script that will manually replace latest JAR in the cache.
The reason is that Gradle does not come with this functionality built-in, as Gradle uses notion of "local cache" in a strict sense, as opposed to "local repository" which is used by Maven.
The difference is that you are never supposed to save files to local cache manually.
To solve your problem the recommended way: Suppose that project A is a dependency of project B. Then you can call publishToMavenLocal command in project A to refresh the depedency. Add mavenLocal() repository in gradle.build of project B, so every time you build project B, Gradle will check the local repository when resolving the dependency A.
mavenLocal() is resolved like this:
In order to make use of a non-standard local maven repository, you can use the following configuration in your build.gradle:
repositories {
maven {
url '/Users/manuelj/apache/maven/repository'
}
}
A build.gradle sample to create a Jar file along with its logback dependencies. using mavenlocale()
apply plugin: 'java'
apply plugin: 'eclipse'
version = '1.0'
sourceCompatibility = 1.7
target Compatibility = 1.7
//create a single Jar with all dependencies
task fatJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'Gradle Jar File Example',
'Implementation-Version': version,
'Main-Class': 'com.mkyong.DateUtils'
}
baseName = project.name + '-all'
from { configurations.compile.collect { it.isDirectory() ? it :
zipTree(it)
}
}
with jar
}
//Get dependencies from Maven central repository
repositories {
mavenCentral()
}
//Project dependencies
dependencies {
compile 'ch.qos.logback:logback-classic:1.1.2'
}
Reference create a Jar file along with its logback dependencies.

Including Java library built with Gradle throws NoClassDefFoundError

I am writing a Java library and I would like to build the library with Gradle and then test it from a local test project.
I would prefer using Gradle 3.3 for my objective.
The library should be built for Java5 and higher.
So far my build.gradle looks like this:
plugins {
id 'jvm-component'
id 'java-lang'
}
repositories {
mavenCentral()
}
model {
components {
main(JvmLibrarySpec) {
sources {
java {
dependencies {
module 'commons-codec:commons-codec:1.10'
module 'org.apache.httpcomponents:httpcore:4.4.6'
module 'org.apache.httpcomponents:httpclient:4.5.3'
}
}
}
api {
exports 'io.simplepush'
}
targetPlatform 'java5'
}
}
}
The source code of the library is located in src/main/java/io/simplepush/Notification.java and depends on the dependencies stated in the build.gradle file.
Building the library with ./gradlew build works fine and generates build/jars/main/jar/main.jar.
However when I run a test project from IntelliJ (after including main.jar into the test project), I get the following runtime error:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/HttpEntity.
It seems like the test project does not know about the runtime dependencies needed by my library.
I am not sure on what is the correct way to tell the test project about the dependencies of my library.
I do not want a fat jar which includes all dependencies.
Listing all dependencies in the test project itself is also not an option.
Preferably I want the library itself to tell the test project about which dependencies it needs.
The library jar which you have created does not contain any dependency information which the IDE/Gradle can then resolve to be able to compile/run the test project. I see that you are using the maven central repository so what you need to do is to publish your library to your local maven repository and in the test project just add a dependency information (no just plain jar file).
So in both library and test project build.gradle add a maven local repository config.
repositories {
mavenLocal()
mavenCentral()
}
And now you need to publish the library to local repository. As you are using the gradle 3.3 you can use the Maven Publishing.
So in the library build.gradle add a maven publishing information.
publishing {
publications {
maven(MavenPublication) {
groupId 'io.simplepush'
artifactId 'project1-sample'
version '1.1'
from components.java
}
}
}
Gradle “maven-publish” plugin makes this easy to publish to local repository automatically creating a PublishToMavenLocal task.
So you can just run
gradle publishToMavenLocal
Which will publish your library with all the dependency information into local maven repository.
And then you just need to add a library information to you test projects build.gradle
dependencies {
// other dependencies .....
module 'io.simplepush:project1-sample:1.1'
}
I solved it by changing several things.
Thanks to #Babl for pointing me in the right direction.
My new library build.gradle looks like this:
plugins {
id 'java'
id 'maven-publish'
}
sourceCompatibility = 1.5
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile 'commons-codec:commons-codec:1.10'
compile 'org.apache.httpcomponents:httpcore:4.4.6'
compile 'org.apache.httpcomponents:httpclient:4.5.3'
}
publishing {
publications {
maven(MavenPublication) {
groupId 'io.simplepush'
artifactId 'project1-sample'
version '1.1'
from components.java
}
}
}
Now I can push the library to the local maven repository with ./gradlew publishToMavenLocal.
The build.gradle of the test project uses the application plugin and defines a main class (which is Hello in my case). Then I can run ./gradlew installDist to generate an executable file (see Application plugin docs) which puts all dependencies in the classpath and runs just fine.
group 'com.test'
version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'application'
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile 'io.simplepush:project1-sample:1.1'
}
mainClassName = "Hello"
This specify what repositories to check to fetch the dependencies from
repositories {
mavenCentral()
}
Therefore, anything that is in the dependecies{} will be fetched from those above.
If the test project is not coupled with the library project, (#RaGe example) new test project needs to know where to take the dependency from - you need to publish it, using preferred method.
After that, your new test project needs to specify the library with the preferred configuration (compile...runtime etc) in the build.gradle dependencies{}
After that depending on IDE you need to refresh the classpath and download the dependency from the specified before repository, the transitive dependencies specified in the library dependency (in this case) will get fetched from test projects repositories{}
Library build.gradle
repositories {
mavenCentral()
}
dependencies {
module 'commons-codec:commons-codec:1.10'
module 'org.apache.httpcomponents:httpcore:4.4.6'
module 'org.apache.httpcomponents:httpclient:4.5.3'
}
test project build.gradle
repositories {
mavenCentral() repository to fetch transitives
mavenLocal() or any other repo that you published the library to
}
dependencies {
pref-conf librarygroup:name:version
}
You can use idea or eclipse plugin in gradle for gradle idea or gradle eclipseClasspath tasks to refresh it with your freshly added dependencies.
With this solution, you should not need to pack the transitive dependencies within the library,
PS. I am just confused after you said you want executable jar.

Make Gradle use Maven local repository for downloading artifacts

I know I can configure Gradle to use local Maven repository
repositories {
mavenLocal()
mavenCentral()
}
Can I configure Gradle to download into Local (maven) repository? (So that Maven would also be able to use those jars)
ref Gradle configuration to use maven local repository
A solution was given in the gradle forums:
https://discuss.gradle.org/t/need-a-gradle-task-to-copy-all-dependencies-to-a-local-maven-repo/13397/2
using this gradle plugin: https://github.com/ysb33r/ivypot-gradle-plugin
you can call a new tasg
gradle syncRemoteRepositories
which will download all dependencies to a local Ivy repository (which is the same library Maven uses). The folder you point to with
syncRemoteRepositories {
repoRoot '/path/to/repo'
}
will contain the dependencies. I would suggest first trying out with a different local path than your M2_HOME, because I saw some warning about the Ivy repository structure having changed between Maven versions.
It should be as simple as
apply plugin: 'maven'
apply plugin: 'java'
dependencies {
mavenLocal()
}
And
gradle install
More info here

Categories