22

I've recently started using Gradle and replacing my existing Maven-based projects. I have had many issues in the past with handling multi-module builds with Maven. Gradle has been a breath of fresh air when handling multi-module buils, but it's not perfect yet.

I have the following folder layout for my projects:

-- Projects
---- EnterpriseApp1
------ EarProject
-------- build.gradle
------ EjbProject
-------- build.gradle
------ WarProject
-------- build.gradle
------ properties.gradle
------ build.gradle
---- CommonLib
------ build.gradle
---- ClientApplication
------ build.gradle

The problem I am having is that the "EnterpriseApp1" and "ClientApplication" both depend on the CommonLib project. I don't know how to configure my "EnterpriseApp1" build file to use the CommonLib project as dependency for the "EjbProject". I have come very close to getting this to work, but not quite working yet. I have had success by copying the CommonLib folder inside "EnterpriseApp1", but that's not a long term solution.

Here's my current properties.gradle file in "EnterpriseApp1":

include "EarProject", "EjbProject", "WarProject"
includeFlat "CommonLib"

According to the Gradle documentation the "includeFlat" command in the "settings.gradle" file will include projects on the same level as the folder where the "settings.gradle" file resides (desired behavior).

EnterpriseApp1/build.gradle file:

subprojects {
   apply plugin: 'java'

   sourceCompatibility  = 1.6
   group = 'org.example'
   version = '1.0-SNAPSHOT'

   repositories {
      mavenCentral()
      ...
   }

   dependencies {

   }    
}

EnterpriseApp1/EjbProject/build.gradle:

apply plugin: 'java'

sourceCompatibility  = 1.6

repositories {
   mavenCentral()
   ...
}

dependencies {
   compile project(':CommonLib')

   compile group: 'org.restlet.jee', name: 'org.restlet', version: '2.0.11'
   compile group: 'ma.glasnost.orika', name: 'orika-core', version: '1.0'
   ...
   compile group: 'javax.jmdns', name: 'jmdns', version: '3.4.1'
}

When I execute "gradle clean build" from the EnterpriseApp1 folder all the dependencies are downloaded as expected and the projects begin to compile (including the CommonLib project), but the EjbProject project fails during the build due to the fact it's missing the CommonLib jar reference. Gradle is not smart enough (or I'm completely clueless ;)) to configure my EjbProject to use the Jar generated from the CommonLib project build stage.

I apologize for the long and complicated setup. I have been working on trying to figure this out for some time now, but have nearly ran out of ideas. I would really appreciate any help for the community.

Thanks!

Werner Altewischer
  • 10,080
  • 4
  • 53
  • 60
juan.villa
  • 231
  • 1
  • 2
  • 5
  • Something's wrong with the indentation of the directory layout shown. Is this one build, where CommonLib and ClientApplication are on the same directory level as EnterpriseApp1, and the other projects are one level down? (That would be a very uncommon layout. Usually it's either or.) – Peter Niederwieser Jan 26 '12 at 03:54
  • Also, how should Gradle know that CommonLib is a dependency of EjbProject, given that you don't specify such a dependency in `EjbProject/build.gradle`? – Peter Niederwieser Jan 26 '12 at 03:59
  • Did you intend to say: Here's my current _settings.gradle_ file in "EnterpriseApp1" – Peter Niederwieser Jan 26 '12 at 04:01
  • Where does project `:angel-display-proxy` come from? – Peter Niederwieser Jan 26 '12 at 04:02
  • Is `ClientApplication` a separate build or part of the `EnterpriseApp1` build? – Peter Niederwieser Jan 26 '12 at 04:05
  • Peter, thanks for taking your time to comment on my problem! I appreciate your time. You are correct, I made a mistake in the directory layout. I have corrected the issue – juan.villa Jan 27 '12 at 02:38
  • I know that the structure is not common, but it's the only way I can think of doing it. The EnterpriseApp1 is an EAR that has an EJB that depends on DTO POJO declarations in the CommonLib project. I then have a SWING client application (JAR) that hosts a REST servlet (with Restlet) which uses the DTO POJO declarations in the CommonLib library (JAR) to serialize/deserialize data through REST. – juan.villa Jan 27 '12 at 02:41
  • When I wrote this I converted a lot of the names of the applications to a generic names. I accidentally forgot to convert "angel-display-proxy" to "CommonLib". I have made the edit. Thanks for catching that! My mistake for carelessness and writing it so late at night ;) – juan.villa Jan 27 '12 at 02:43
  • Yes, ClientApplication is a separate build from EnterpriseApp1. It's a SWING ClientApp that communicates with the EnterpriseApp1 (EAR). – juan.villa Jan 27 '12 at 02:44
  • Hi. Did you try copy dependencies? Probably this may help you as well as local maven repo. – user55993 Nov 07 '20 at 14:43

1 Answers1

7

The directory layout that you've chosen already hints at a good solution. I suggest to have three separate builds: EnterpriseApp1, CommonLib, and ClientApplication. I'd publish CommonLib to a Maven or Ivy repository so that the other two builds can consume it from there. For local development you can publish CommonLib to the local Maven repo (easiest) or a file-based Ivy repo.

Peter Niederwieser
  • 121,412
  • 21
  • 324
  • 259
  • Thank you Peter! That's what I was thinking I could do as last resort, but I didn't want to have to use a local/remote repo. Do you know if this is possible to accomplish via Gradle? or do you believe this is not a good practice in the first place? – juan.villa Jan 27 '12 at 14:27
  • 2
    If `EnterpriseApp1` and `ClientApplication` are different apps with a different development and release cycle, the build should reflect this. You can publish `CommonLib` as part of the `EnterpriseApp1` build, but this will still require a repository, and will complicate matters when `ClientApplication` needs a change in `CommonLib`. Alternatively, if all the code is in the same source repository, you could have two builds, both of which include `CommonLib`. Or, if the development/release cycles are the same, you could have one large build, in which case you won't need a repo. – Peter Niederwieser Jan 27 '12 at 17:13