Build Multi Java Projects

Hello,

I’m with a problem to compile a java legacy project with a very complicated structure. I can not chage this scructure.
The system is divided in 2 java project, one with the active code that need to generated a EAR file and other with the unit test classes that need to be compiled and run.

  JAVA_PROJECT
           src1
           src2
           src3
           app
                javaproject.ear
                         javaproject1.war
                         javaproject2.war 
                         META-INF
                               application.xml
                         lib
                               *.jar

  JAVA_PROJECT_TEST
            src1_test
            src2_test 
            src3_test

I thought to use gradle because many people said that is more flexible that maven. I don´t know if the problem is with me or gradle is not so flexible as I thought. I have been looking in the internet but do not find a way to build my project.

I tried to declare the test project in the file settings.gradle of the JAVA_PROJECT:

project(':JAVA_PROJECT_TEST').projectDir = new File(settingsDir, '../JAVA_PROJECT_TEST')

But it never find this project: Project with path ‘:JAVA_PROJECT_TEST’ could not be found.

The support a multi projects is not working the multi java projects. When you declare a project in the build file:

 project(':JAVA_PROJECT_TEST') {
   
   }

The follow error appears: Project with path ‘:JAVA_PROJECT_TEST’ could not be found.

What I need is compile the JAVA_PROJECT, compile the JAVA_PROJECT_TEST, execute the unit tests in JAVA_PROJECT_TEST, generated the JAVA_PROJECT.ear with the JAVA_PROJECT.jar, 2 JAVA_PROJECT.war and
a “lib” directory with all *jar dependences. All this inside the JAVA_PROJECT.ear file.

1st - build JAVA_PROJECT generating the JAVA_PROJECT.jar
2nd - build JAVA_PROJECT_TEST with JAVA_PROJECT.jar as dependence
3rd - run JAVA_PROJECT_TEST tests
4th - build JAVA_PROJECT1.war and build JAVA_PROJECT2.war
5th - create e JAVA_PROJECT.EAR with the JAVA_PROJECT.jar, JAVA_PROJECT1.war, JAVA_PROJECT2.war
and “lib” directory inside it.

Can someone give a help? Please

Unfortunately, I think the the root project of a multi-project build must be ‘above’ all subprojects.
In other terms, the subprojects must be in child directories of the root project.

When your project doesn’t follow the directory layout convention defined by Gradle you need to define your layout with source sets. In your case something like this may help:

sourceSets {
	main {
		java { srcDirs = ['src1', 'src2', 'src3'] }
	}
	
	test {
		java { srcDirs = ['src1_test', 'src2_test', 'src3_test'] }
		runtimeClasspath = sourceSets.main.output + files(output.resourcesDir) + files(output.classesDir) + configurations.testRuntime
	}
}

I don’t work with ear or war, so you will have to look elsewhere on how to setup the source sets for your application. Also take a look at the jar and war tasks.

Hello aacirino,

I know that you can define a structure like this:

sourceSets {
    main {
        java {
            srcDir 'src1'
            srcDir 'src2'
            srcDir 'src3'
        }
   }
}

But this just work to one, and just one, Java Project where the build.gradle file is localized.

I would like to call a build.gradle scritp in another Java Project to run the unit tests and than come back
to my project and generate the EAR file, with two WAR files inside.

To run the unit test inside de project JAVA_PROJECT_TEST I need to add the JAVA_PROJECT as the dependence of the JAVA_PROJECT_TEST. I have a Ant build that make this tasks, but I am migrating to gradle now. Like I said:

1st - build JAVA_PROJECT generating the JAVA_PROJECT.jar (OK)
2nd - build JAVA_PROJECT_TEST with JAVA_PROJECT.jar as dependence
3rd - run JAVA_PROJECT_TEST tests
4th - build JAVA_PROJECT1.war and build JAVA_PROJECT2.war
5th - create e JAVA_PROJECT.EAR with the JAVA_PROJECT.jar, JAVA_PROJECT1.war, JAVA_PROJECT2.war
and “lib” directory inside it.

One thing you could do is write a script that wraps your gradle calls.
First you compile the first project (and maybe publish it in a flatDir local repository?)
Then you call gradle again to compile your second project, and so on.

Again I don’t think this is possible to reference projects as you want, without having a root gradle project on top of all of them

Hi Jadson, a regular multi project gradle build has a root project with no sources and the sub-directories contain the sub-projects directory tree. Each sub-project can have its own source set, you can either define the sub-projects settings and configurations in the root project build script or in each of the sub-projects build script.

Then you can set projects dependencies. For instance in project2 build script you would set

dependencies {
	compile project(':project1')
}

And then call gradle in the root project, as long as you have defined the projects to build in settings.gradle in the root project dir, side by side with the root build script. Then gradle will take care for you of all the dependencies of the tasks, like unit tests and jar packaging.

All the five steps you mentioned you intend to have as outcomes of your build are automatically performed by gradle when you setup you build scripts properly. A multi project layout should be like this, following gradle’s convention:

├── rootProject
	|── build.gradle
	|── settings.gradle
	|── project1
	|	|── build.gradle
	|	|── settings.gradle
	|	└── src
	|		└── main
	|		|	└── java
	|		|		└── com
	|		|			└── yourcompany
	|		|				└── apackage
	|		|					└── MyClass.java
	|		└── test
	|			└── java
	|				└── com
	|					└── yourcompany
	|						└── apackage
	|							└── MyClassTest.java
	└── project2
		|── build.gradle
		|── settings.gradle
		└── src
			└── main
			|	└── java
			|		└── com
			|			└── yourcompany
			|				└── anotherpackage
			|					└── OtherClass.java
			└── test
				└── java
					└── com
						└── yourcompany
							└── anotherpackage
								└── OtherClassTest.java

Angelo, do Brasil

Wow wow wow
Did you declare the settings.gradle like that?

include(“foo”)
project(":foo") {
projectDir = new File("$settingsDir/…/…/bar")
}

I found this old thread Reference external project as dependancy?
This is close to what you wrote initially, except the missing ‘include’

My solution was call an ANT script that make what I want from the Gradle script. Now Gradle will be used just to resolve the project dependences. But generated another problem:

All this problem is beacuse I have a very complex legacy build scenario. Totaly out of Gradle or Maven build patterns. How Gradle is more flexible thant Maven, I chose Gradle instead of Maven to make this build.