Gradle - configuration for sibling and interlinked projects - eclipse

I'm try to configure sibling projects with several dependencies (I'm talking about project dependencies, not artifact dependencies)
So the structure is something like:
A (needs B)
B (needs C)
C
I need to set correctly these dependencies. In particular, I'm using the Eclipse integration, so the goal is to get Gradle -> Refresh all set the correct dependencies among the relative Eclipse projects (however, I believe this question is independent of Eclipse).
Notice that there is only a logical hierarchical layout, not physical (and it will stay that way).
I have read about the use of includeFlat, but probably I'm still missing something.
If we look only at B and C, then I can have them work correctly, by:
In B/settings.gradle : includeFlat 'C'
In B/build.gradle : compile project(':C')
This works fine for B.
Now, A needs B. So what I thought was: I just need to do the same thing between A and B:
In A/settings.gradle : includeFlat 'B'
In A/build.gradle : compile project(':B')
I did expect that when refreshing A, the transitive dependency A -> B -> C would work, but somewhere it breaks and I get:
Project with path ':C' could not be found in project ':B'
What I'm guessing is that B/settings.gradle is not being read. Why is that?
Could someone tell me what I am not understanding?

In a Gradle multi-project build, only one settings.gradle file can be used at a time. Since project B depends on C and project B is part of the multi-project build, you need to include project C in any settings.gradle file that uses project B (assuming you're using project dependencies instead of artifact dependencies).
Note that you can tell Gradle which settings.gradle file to use for each build with the -c command line option, but the build for A is never going to work unless B and all of its project dependencies are included.
Also note that multi-project builds always define a single "root" project, which is defined by where the settings.gradle file is. So if project A contains settings.gradle, it is the "root" project. However, in a flat layout, you can create a special directory named master to represent this and Gradle will automatically find your settings.gradle file there. Read about this here. Note that all of your build commands should typically be run from the "root" project, so if you use the Gradle wrapper, it should live there.
Assuming a flat layout, I would suggest this structure:
A/
build.gradle
src/
main/
java/
B/
build.gradle
src/
main/
java/
C/
build.gradle
src/
main/
java/
master/
build.gradle
gradle/
wrapper/
gradle-wrapper.jar
gradle-wrapper.properties
gradlew
gradlew.bat
settings.gradle
And the contents of settings.gradle would be something like:
["A", "B", "C"].each {
includeFlat it
}

Related

Unittesting pomless aspectJ project

In a Tycho build I have a pomless plugin-project/bundle A with some aspectj classes in it (*.aj). The project builds fine and another project B can reference project A via its manifest.mf.
Now a separate unittest project C exists for testing project A. This unittest project C is intended to be build with standard pom.xml and maven-surefire (no manifest.mf exists in C).
The problem is that C cannot find the *.aj classes of project A. If I introduce a pom.xml in project A with maven-aspectj-plugin then A can be build and C finds anything it needs in A. But then project B cannot find bundle A. Are there any suggestions to resolve such a problem?
I'm relativly new to Tycho and i assume the problem belongs to the mix of the pom-less approach in project A and the pom-based approach in unittest project C. Is there any possibility to build the mentioned unitest project C pom-based or do i need to build it with tycho-surefire ?
I found this related question
Aspectj class is not found by test class when running test with maven
but it didn't help for me in this case.
Thanks in advance.
pom.xml should be used in project A, with packaging type eclipse-plugin, no dependencies set, and the usual plugin setup of aspectj-maven-plugin

Running gradle tasks from a subproject with unknown root

I have a multi-project setup in gradle with a somewhat-flat structure like so:
RootProject/
build.gradle
settings.gradle
SubProjectA/
build.gradle
anotherDirectory/
SubProjectB/
build.gradle
SubProjectC/
build.gradle
The root project is really just a root build. It's there to tie all of the other projects together. SubProjectB depends on SubProjectC, and C depends on A.
Running tasks from the root project works as expected. I can run gradle :SubProjectB:build and it will build SubProjectB and its dependencies without error.
My problem is that if I try to run a task from a sub-project's directory, it fails if that sub-project depends on any of the other sub-projects because it doesn't know where any of the others are without the root project's settings file. So running A's build from its directory would work, but running B's or C's would fail.
Is there anything I can do within this structure to define what the root project actually is, so that if I run gradle build from B, it would behave the same as running gradle :SubProjectB:build from the root project's directory?
The end goals are to make it easier to use gradle from the command line, and to get functional default tasks on the sub-projects. That way I should be able to double-click a project Eclipse's Gradle tasks list, and have it run the default tasks as though it were running the tasks from root.
In this case, you can use composite builds. Let say you are at SubProjectA and want to build against SubProjectB. The you can execute the command below:
gradle --include-build ../anotherDirectory/SubProjectB run
SubProjectB will build first and then SubProjectA.

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.

build paths eclipse java j2ee

I have imported a project (I am very new at this) and I get the following errors:
Project cannot be built until build path errors are resolved
Project FST is missing required library: 'C:program Files/Apache Group/Tomcat 4.1/common/lib/servlet.jar'
Project FST is missing required library: 'C:program Files/Apache Group/Tomcat 4.1/common/lib/struts.jar'
The project cannot be built until build path errors are resolved
Unbound classpath variable: 'TOMCAT_HOME/common/lib/jasper-runtime.jar' in project
Unbound classpath variable: 'TOMCAT_HOME' in project FST
I create a variable called TOMCAT_HOME and give it the proper directory ,but Also, we should change the project classpath to use TOMCAT_HOME rather than the absolute path.
i dont know how to do it (change the project classpath and the absolute path)
thanks !
To answer somewhat indirectly, if you configure your project build with something like Maven or Gradle, so that you can successfully build the project using the corresponding command-line tool, then it should be quite straightforward to import the project into eclipse using the Maven or Gradle eclipse plugin. I think doing so will be worth whatever trouble it causes you in the short run--just take care to make your project structure conform to the usual project structure that Maven expects or you'll be asking for trouble (it should be no problem to do so for greenfield work).

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!