12561

Maven: bundle specific dependency

Question:

Imagine you have environment-specific build which results into two bundles: Home and Office. Environment-specific artifact of your build depends on some common artifact, lets call it 'Core'. It is just a common functionality for Home and Office builds. Home artifact depends on Core, and Office artifact depends on Core. In fact, Home and Office can even be the same artifact which is just build under different Maven profiles: in case we call Maven with -pHomeBundle it builds artifact one way, in case with -pOfficeBundle - it builds it for office, both times taking Core as a dependency which is the same as for Home.

So far so good.

Now a question is: what can we do if Core artifact, which is common for Home and Office bundles has dependencies on other artifacts which are DIFFERENT for Home and Office bundles? I.e. Core artifact is not bundle-dependent, but its dependencies are.

How can we provide our Core with this dependencies?

How can we write Core POM for this?

UPDATE Two solutions were suggested for this problem: add two bundle-specific dependencies to Core project as provided (and then add one real in the bundle-specific module Home/Office which takes Core as a dependency), or add two real dependencies to Core module and then filter them in the bundle-specific module Home/Office. But I cannot get with which dependency Core will be build. No matter we provide it or not - it should be build with some dependency because it goes to repository. As far as I understand it will just take the first available class and use it. So I will have a Core artifact built using one of the dependencies.

Answer1:

I would prefer to have those bundle specific dependencies added in their respective pom.xml and exclude them under the core dependencies so that I am 100% sure of getting only those dependent libraries added for that project.

We have encountered a similar situation in our application when we had to build the same application for two different runtimes and some framework libraries had the runtime libraries bundled in them. So we ended up excluding them from the core dependency and included them as individual dependencies to the application POM.

Hope this makes sense and also helps. Curious to learn if legends have a better approach.

Answer2:

It sounds like things have gotten a little confused here. You should never really build an environment specific version of your app. You should build only one app, and it should work in any suitable environment, be it home or office. The things that are different should be provided by the environment.

Let's get concrete.

For example: you depended on an oracle database at work, and a mysql database at home. You build your software against a standard interface, say JPA. Your home and work containers (let's assume tomcat), should have a properties file containing the database connection string in a jar in its provided library folder. Then, when your app starts, it can pick up the environment's database. One app, multiple environments.

Another example: you depend on log4j while at home, but in the office auditing is more rigorous than that and you have to use a custom library. Your code is built against a standard logging interface, and your container at home has the log4j libraries in the provided folder, when your app is deployed at home it'll pick up the log4j implementation, but your provided folder at work has the custom logging library so that when your app is started there it picks that up instead.

Hopefully, you can see from these examples that the software we build should be given an environment with environment specific implementations of the services it expects. With modern java, osgi, and modern containers, this is always true. We can always build our software this way. We should not need nor never have environment specific builds.

If you have functionality that's different in each environment, then strip it out into a separate module and mark it as provided in the modules that use it. Usually this will result in at least three modules, one for the interface, and two for environment specific implementations. The interface is almost always a runtime dependency, and the implementations are almost always provided.

Answer3:

Re <em>"Home and Office can even be the same artifact"</em>

Do you mean building office and home (snapshot or release) with the same GAV <em>and</em> jar file name but with different profiles?

Since a picture is worth a thousand words is it that what you want to achieve:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - office-for-core:jar office:jar \ / office build \ / - - - - - - - - - - - (office-) - - - / - - - - - - - - - - - - - - - - core:jar core build - - - - - - - - - - - - (home-) - - - \ - - - - - - - - - - - - - - - - / \ / \ home build home-for-core:jar home:jar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Recommend

  • Variant from android-autofittextview library : scaling makes strange behaviour
  • Using multiple input pipelines in TensorFlow
  • How to resolve dependencies from one gradle project to another gradle project in my Eclipse workspac
  • EF 4.1 DBContext AutoDetectChangesEnabled
  • Single django queryset to get n adjacent items
  • Java : How to tint this PNG programmatically?
  • in batch how do i use taskkill properly
  • Local Development, Apache vs Developer - file permissions
  • Criterion causing memory consumption to explode, no CAFs in sight
  • ImportError: cannot import name Pubnub
  • jquery validation - waiting for remote check to complete
  • HttpListener.IsSupported is false on XP SP3
  • Azure webjobs output logs indexing taking very long
  • How do I display a dialog that asks the user multi-choice questıon using tkInter?
  • Adding elements to a huge XML file
  • ADO and msqli connections very slow
  • How to add git credentials to the build so it would be able to be used within a shell code?
  • jQuery ready not fired after rails link_to is clicked
  • Marklogic : Query response time is very high
  • Installing Apache MyFaces 2 on WildFly 8.2.0
  • How to define and use opencv mat of user type
  • How to use remove-erase idiom for removing empty vectors in a vector?
  • MailKit: The IMAP server replied to the 'EXAMINE' command with a 'BAD' response
  • Using jQuery closest() method with class selector
  • Spring security and special characters
  • Array.prototype.includes - not transformed with babel
  • How would I use PHP exceptions to define a redirect?
  • Cassandra Data Model
  • retrieve vertices with no linked edge in arangodb
  • Proper folder structure for lots of source files
  • log4net write single file for each call to log.info
  • Why can't I rebase on to an ancestor of source changesets if on a different branch?
  • Getting Messege Twice Using IMvxMessenger
  • Java static initializers and reflection
  • Linking SubReports Without LinkChild/LinkMaster
  • unknown Exception android
  • Observable and ngFor in Angular 2
  • Unable to use reactive element in my shiny app
  • Python/Django TangoWithDjango Models and Databases
  • Net Present Value in Excel for Grouped Recurring CF