Gradle: produced WAR file has two versions of JAR from child project - eclipse

I have a root project that builds WAR, and two child projects that build JARs. The root project references the child project in this way:
apply plugin: 'war'
jar.enabled = false
war {
dependencies {
runtime project(':application1')
runtime project(':application2')
}
}
application2 depends on application1:
dependencies {
compile '...:application1:1.+'
}
The WAR file includes two versions of application1.jar: one from repository, another just built.
EDIT: Application2 has to depend on application1 as a JAR because that simplifies debugging in Eclipse with embedded Jetty: Eclipse automatically adds application1.jar to classpath of Jetty server launch configuration.

You have specified dependency on application1 project differently for the root project and for the application2.
For your application2 it was made as dependency on a library within some repository, but your root project depends on it as on a subproject. Gradle can't determine, that some library in the repo is the same, as subproject's artifact.
If you don't want to get 2 versions of the same lib, you have to make it dependent from the same library: either as
compile '...:application1:1.+'
or as
runtime project(':application1')
Anyway, it seems to be prefferable, to make it depending on the same subproject in both cases, rather then on some project and on the library in repo.

Related

Gradle other project as dependency in eclipse

I have a web application which depends on another standalone project. Simply the web project requires a standalone project jar to be in classpath. I have built the standalone project jar with gradle and included that in web application's WEB-INF/lib folder. The project is running as expected. Now i want to make it automatic by adding that project as dependency. This is also achieved using the following code.
settings.gralde
include 'job-invoker'
project(':job-invoker').projectDir = new File(settingsDir, '../job-invoker')
build.gradle
dependencies {
compile project(':job-invoker')
.
.
}
I'm able to build the war file from command line using gradle and run it in tomcat. But i'm getting errors in eclipse. I'm not able to run the project in eclipse due to the compilation errors. Can some one please help me. Thanks in advance.
Finally i found a solution for this by installing the other project in maven local repository and adding this as a regular dependency in project. Reference code is given below.
Other project Gradle file
apply plugin: 'maven'
group = 'com.xxx.job'
version = '1.0'
Run gradle install command on this project. Then add mavenLocal() to your repositories in another project and add the dependency
compile 'com.xxx.job:job-invoker:1.0'

How can the source attachment, Javadoc location and native library location be specified for a Gradle project's local dependency, in Eclipse?

The Eclipse IDE for Java Developers (Neon) as well as the default Gradle plugin (Buildship?) are used.
A Gradle Git project was created using the Eclipse IDE. A local JAR is stored within the workspace/ProjectName/lib/nameOfJAR.jar directory. It was added to this project as a dependency, using the following build.gradle configuration.
...
repositories {
// Use 'jcenter' for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
flatDir {
dirs 'lib/'
}
}
dependencies {
// The production code uses the SLF4J logging API at compile time
compile 'org.slf4j:slf4j-api:1.7.21'
compile name: 'nameOfJAR'
// Declare the dependency for your favourite test framework you want to use in your tests.
// TestNG is also supported by the Gradle Test task. Just change the
// testCompile dependency to testCompile 'org.testng:testng:6.8.1' and add
// 'test.useTestNG()' to your build script.
testCompile 'junit:junit:4.12'
}
Then Project Explorer > Project A > Gradle > Refresh Gradle Project was used to update the Eclipse GUI, to display this new local dependency, via Project Explorer > Project A > Build Path > Configure Build Path > Libraries > Project and External Dependencies > [Name of JAR].
However, when expanding this section, source attachment, Javadoc location and native library location are shown as non modifiable. Can these be set from the Gradle configuration files?
How can these be set through Eclipse and Gradle?
You can place nameOfJar-sources.jar file next to the actual library in the same directory. Gradle will use that as a source attachment. I suppose the same would work for javadocs, that is nameOfJar-javadoc.jar would be picked up. I don't know how native libs are handled.
This is probably described somewhere in the Gradle docs, but I don't know where to find them.

Gradle and Eclipse project references

I'm using Gradle with Eclipse and am trying to reference Project1 from Project2 (both under the same root directory), like so:
settings.gradle:
include ':Project1'
project(':Project1').projectDir = new File(settingsDir, '../Project1')
build.gradle
dependencies {
compile project(':Project1')
...}
Project1 is also referenced through the build path. But eclipse/gradle does not recompile and instead uses include the old jar classes. I've also tried to set the plugin to apply plugin: 'eclipse-wtp'.
Just out of curiosity, do you have a block like this somewhere in your build.gradle
eclipse.project {
referencedProjects 'Project1'
}
I ask because, if you don't tell Eclipse that this project references Project1, it won't be included in the build path.

Eclipse workspace setup and packaging an independent jar

I have 5 regular java projects inside an eclipse workspace that have inter-dependencies and external jar-dependencies both
on libraries that exists as maven repositories and libraries that don't.
Everything is working fine inside eclipse but I have two tasks that I need to perform:
1)
Package everything into a runnable jar that I can upload to another computer and run without having to setup
the same eclipse environment there. I've been looking at gradle/maven but don't know if I need something as "complex" as that
and it seems quite alot of my setup has to workspace setup has to change to use those tools, but I may be wrong.
2)
I soon want to host the code of two of the java projects on google code so the workspace should be structured in a way
that makes that task smooth.
I'm mentioning both tasks since I don't know if they interact in some manner.
How do I solve this in a good way?
Thanks in advance.
Your description sounds like a perfect fit for Gradle's multi-project support and it's eclipse and application plug-ins. Here's a quick example of how I would approach it.
Your projects might be in the same eclipse workspace but not necessarily under the same folder, so keep in mind the following directory structure assumes you are free to move them around.
|-- component1
|-- component2
`-- myRunnableApp
The first step is to create your top-level build.gradle file and settings.gradle.
|-- build.gradle
|-- settings.gradle
|-- component1
|-- component2
`-- myRunnableApp
Your settings.gradle will instruct gradle to treat the subdirectories as subprojects.
include ':component1', ':component2', ':myRunnableApp'
Your build.gradle will contain settings that are common to all your subprojects, in this particular case we want to apply the java and eclipse plugins:
subprojects {
apply plugin: 'eclipse'
apply plugin: 'java'
repositories {
mavenCentral()
}
}
This should be enough to get you to generate eclipse projects by issuing gradle eclipse. Next you'll want to declare the dependencies between the projects thusly:
component1/build.gradle
dependencies {
// declare your 3rd party jar dependencies as needed
compile 'group:artifact:version'
}
Now you can declare dependencies between projects - this will be reflected in your eclipse project files when you generate them.
component2/build.gradle
dependencies {
compile project(':component1')
}
And finally, you'll want to apply the applications plugin to your runnable project. It will generate your jar file along with wrapper sh / bat files for unix and windows.
myRunnableApp/build.gradle
apply plugin: 'application'
mainClassName = 'my.custom.app.Main'
dependencies {
// component 1 is a transitive dependency of component 2
compile project(':component2')
}
And that's it! I expect this should be a good starting point for rolling out your own build. Check out the gradle documentation for multi-project builds, the java plugin, the applications plugin and dependency management.
Hope that helps!

SBT exclude scala-library.jar from a war file packaged using xsbt-web-plugin

I have a project that only needs to take a proguard-constructed jar file, which is built in a separate SBT project and contains all classes needed to run as a servlet, and create a war file out of it.
The dependency is properly packaged into the war, and the transitive jars are excluded correctly using notTransitive(), but scala-library.jar continues to be placed into the war file as well. This is not desired, since the proguard-built jar contains those scala classes that are necessary for the servlet filter to run. The present project just needs to take that dependent jar, add a web.xml, and package it into a war file.
What is the simplest way (preferably using a build.sbt file) to get the war packaging mechanism from the xsbt-web-plugin to exclude the scala-library.jar?
This should work, it .sbt:
autoScalaLibrary := false