Problems during build when referencing static lib directory gradle - gradle

I use a build.gradle file which needs to reference some jar files which are neither available on a public nor an internal repository.
Because of that I put the jar files into a lib directory which is below my Eclipse project:
dependencies {
...
compile files('lib/*.jar')
}
This works fine as long as I run or export my program from within Eclipse. But when I try gradle build gradle fails with this error:
Could not normalize path for file
'C:\Workspaces\MyProject\project\lib\*.jar'.
I changed the path to lib\*.jar, added a leading ./, removed the \*.jar but to no avail.
When I remove the compile files line from the dependencies and add this to repositories instead
repositories {
...
flatDir { dirs './lib' }
}
the compiler complains about error: cannot find symbol, and all these symbols are in the jars referenced from the lib directory.
When I run gradle --debug I can see from the log that the directory referenced by flatDir is being searched in:
10:02:20.587 [DEBUG] [org.gradle.api.internal.artifacts.repositories.resolver.ResourceVersionLister] using org.gradle.internal.resource.transport.file.FileResourceConnector#48499739 to list all in /C:/...../lib/
10:02:20.592 [DEBUG] [org.gradle.api.internal.artifacts.repositories.resolver.ResourceVersionLister] found 7 urls
7 is the count of files in the lib directory.
Why does this work in Eclipse (STS 3.7 with gradle tooling) and not from the command line ? I tried both gradle 2.2.1 and 2.5.

You need to use a FileTree instead of a FileCollection:
compile fileTree(dir:'lib', include:'*.jar')
The reason why eclipse behaved differently than your gradle is most likely because you didn't run gradle eclipse (a task added by the eclipse plugin).
Eclipse does not interact with you build.gradle at all naturally. The eclipse task updates your eclipse to be in snyc with gradle.

I had a hard time finding this, so I will keep my own question and write down what solved the problem.
Obviously there is some kind of different behavior which makes the command line gradle hickup when combining path and wildcards.
This is the correct syntax, which works for Eclipse and gradle on the command line:
dependencies {
compile fileTree(dir: 'lib', include: ['*.jar'])
}
I took this from another post here on stackoverflow which I didn't find during my initial research.

Related

What is supposed to happen to dependencies after gradle build?

I am trying out Gradle, and am wondering, what is supposed to happen to a project's dependencies after you run gradle build? For example, my sample projects don't run on the command line after they are built, because they are missing dependencies. They seem to compile fine, as gradle doesn't give me errors or warnings about finding the dependencies.
Gradle projects I've made in IntelliJ Idea have the same problem. They compile and run inside the IDE, but are missing dependencies and can't run on the command line.
So what is supposed to happen to the dependencies I declare in the build.gradle file? Shouldn't they be output somewhere together with my .class files? Otherwise, what is the point of gradle when I could manage this by editing my classpath?
Edit: Here is my build.gradle file:
apply plugin: 'java'
jar {
manifest {
attributes('Main-Class': 'Animals')
}
}
repositories {
flatDir{
dirs "D:\\libs\\gradleRepo"
}
}
dependencies {
compile name: "AnimalTypes-1.0-SNAPSHOT"
}
sourceSets{
main{
java {
srcDirs=['src']
}
}
}
Your Gradle build only takes care of the compile time and allows you to use the specified dependencies in your code (it adds them to the compile classpath). But it does not take care of the runtime. Once the JAR is build, you need to specify the runtime classpath and provide all required dependencies.
You may think, that this is bad or a disadvantage, but actually it is totally fine and intended, because if you build a Java library, you won't need to execute it, you just want to specify it as a dependency for another project. If you would distribute your library to a Maven repository, all dependencies from Maven repositories (module dependencies) would end up in a POM descriptor as transitive dependencies.
Now, if you want to build a runnable Java application, simply use the Gradle Application Plugin (apply plugin: 'application'), which will create a ZIP file containing the dependencies and start scripts providing your runtime classpath for execution.
Third-party plugins can also produce so-called fat JARs, which are JAR files with all dependencies included. It depends on your use case if you should use them, because often dependency management via repositories is the better way to go.

Gradle include jar produced by another project in war

Currently I have two projects with gradle build.gradle. The first is going to create a fat jar file, which I would like to include in a war file. I thought compiling it would be enough, but it doesn't seem to be ending up in the /lib directory of my war file. Anyone have thoughts I am quite new to gradle.
dependencies {
compile project(':JarProject')
providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
providedCompile 'org.apache.tomcat:tomcat-jsp-api:7.0.55'
}
war {
archiveName 'WarProject.war'
from 'JarProject/build/libs'
webXml = file('src/web.xml')
}
Does the second project war need to be in providedRuntime? Or should I publish the jar from the other project in the local maven repo and include it that way?
The War task essentially behaves like a CopyTask with regards to stuff it packs in the war, so the documentation on working with files is useful. In essence, I think you need something like (untested):
from fileTree('JarProject/build/libs') {
into("lib")
}
That being said, using mavenLocal() and publishing there also works, but it can lead to unexpected results when the war includes some old version from local, picking up the jar explicitly from the file system like above is better.
I think the elegant solution would be to use multi project builds and project level dependencies. You would have the two builds as separate projects of the same Gradle build and add the "jar project" as a regular compile dependency.
How have you declared the dependency? I assume you have a multi-project build with subprojects A and B, both using the War plugin. I made an experiment using Gradle 2.4 and if I declare B/build.gradle like this:
apply plugin: 'war'
dependencies {
compile project(':A')
}
then B.war contains WEB-INF/lib/A.jar. If you correctly follow conventions of Gradle War plugin (place web resources in A/src/main/webapp/ and code-related resources in A/src/main/resources/), then A.jar should contain what you want.
see this

How do I import an externally built dependency list into a gradle script

I have a build.gradle script that builds a project including a list of dependencies that are generated through an external process. The build works fine if I include the dependencies directly in the build.gradle file:
dependencies {
runtime 'commons-beanutils:commons-beanutils:1.8.0'
runtime 'commons-logging:commons-logging:1.1.1'
runtime 'commons-httpclient:commons-httpclient:3.1'
...
}
However, this list changes and is built by an external process.
I would like to import the dependency list from an external file built separately
dependencies {
import 'deps.gradle'
}
But I don't see how this is possible with anything I'm seeing in gradle.
Another option I've explored is building the dependency list dynamically within the gradle build using a plugin -- but I've not been able to make that work.
All you have to do is using the applycommand. Make sure the path to your file is good and you should be in business!
dependencies {
apply from: "deps.gradle"
}
For more information see point 21.3.1 on the gradle documentation

Load gradle plugin from sibling folder

I've started to create a Gradle plugin. The build is finishing and producing a valid plugin jar (I think), but the implementation is skeletal. I have a couple of unit tests, but I want to have a very simple way to "system test" the plugin.
The original plugin is in my Eclipse workspace. I want to create a second Eclipse standalone project with a build.gradle that references the jar produced by the other project, just using a relative path to the jar in the other project's "build" folder.
My first stab at this is:
buildscript {
repositories {
jcenter()
mavenCentral()
flatDir {
dirs "../GradleYangPlugin/build/libs"
}
}
dependencies {
classpath files("GradleYangPlugin-1.0.0-SNAPSHOT.jar")
}
}
apply plugin:"com.att.opnfv.yang.gradle"
I then just tried "gradle tasks" to see what it said. It fails with "Plugin with id 'com.att.opnfv.yang.gradle' not found."
You might ask whether I constructed the plugin jar correctly. That's a valid question, but I can show that's not even relevant yet. I ran a File IO monitor (SysInternals ProcessMonitor) while I ran the build, looking for any occurrences of "GradleYangPlugin-1.0.0-SNAPSHOT.jar". The only place it looked for it was in the current directory (the root directory of the second project). This shows that the syntax I used for my "flatDir" element isn't groked by Gradle, and it's also not complaining about it. It just ignores it, seemingly.

gradle combining multiple build script dependecies

gradle multiple build script dependencies
We am in the process from transacting my our build scripts from ant to gradle. The ant build is configured the old way without using ivy and getting the dependencies from a lib folder.
We have a number of custom ant tasks packaged in jar. To run the tasks in that jar we also need some other third parties dependencies from the same lib folder.
Being a complex build we cannot afford to move everything in one go and would rather move one bit at a time as we find some time to do it.
I was able to run those custom ant tasks from the gradle build but I am having problems accessing classes from or tasks jars in my gradle build scripts.
In the build script section we have a class path entry needed for artifactory plugin and I tried to add some more class path entries to make our local libs available.
buildscript {
….
dependencies {
// This dependency below is needed by artifactory plugin which we download
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:3.0.1"
}
….
}
I tried lots of combinations but I could not get it to work. What we want is to be able to do something like below:
buildscript {
…
dependencies {
classpath {
["org.jfrog.buildinfo:build-info-extractor-gradle:3.0.1",
fileset(dir: "${antBuildDir}/customTasks", includes: 'myTasks.jar'),
fileset(dir: "${antBuildDir}/lib", includes: '*.jar')]
}
}
…
}
Any idea about how can I address this or any other suggestions if you think I am on the wrong path.
Thank you in advance.
Julian

Resources