4

I'm facing a design problem with Spring's profile and Maven multimodule project from which i'm building a product, as a web as application that can be customized for differents clients. For this i need quite some organization of my code, this is why i'm seaking advises on how to organises my profiles around my code.

At the moment i'm only using 2 profiles : dev/prod for the whole application. Thoses profiles are both maven profiles and spring profiles. Spring profile is in the web.xml of my web archive which come from maven filtering.

Having only this is a bit annoying when i want to easily switch some classes from others module that rely on some external hardware. Of course i can just add a new profile out of nowhere just to fix this problem.

However i'm searching for a more generic way to handle that, I don't want to end in a profile's soup that are just created because "I need it at that time". Should i create a dev-xxx/prod-xxx profile for each module, or is there better best-practices about it ?


Here are some information about how my project is currently organized, this will give you an idea of what i have currently. But it's not necessary to take this in account in your answer

My full stack for the server : PostgreSQL, Hibernate, JPA, Spring+Spring-Security, CXF (provide JAX-RS implementation and many features as a FIQL search engine), WebSockets, Jackson (json serializer)

Here is how my modules are currently organized, i'm not necesseraly searching an answer that match precisely what i have, but it gives you an idea :

  • Core : contains at the moment all Entities, Business services and rights management. I don't use DTO Objects so all annotation from JPA/Jackson are on the entities (36 tables in database).
  • Rest-Common : Contains some default configurations (jackson mapper, jackson jax-rs provider).
  • RestCore : expose all services to the web world, provide a search service that relies on CXF JAX-RS Search module. URL are protected with spring-security according to the simple rights, further check are done in Business Service.
  • RestReader : expose a set of differents URL for synchronization with a mobile reader. Those are not made to be used by a browser.
  • 2 others independants modules that only implements their technical part.

Note : i know that i can have some intermediary profile of integration environment and so on, they're planned, but i'm doing run of 2-3 weeks for each functionnalities that aren't really specified or designed before hand, so i have currently very few time to clean my full build process, to go for a complete analysis and design and so on. So i may be interested in some answers for the future that i won't be able to implements at the moment.

  • Despite being familiar with every technology you've mentioned here I find I can't answer. I don't feel like I have a clear understanding of your goal. You speak of wanting to switch classes and avoiding a "profile soup" that will result if you just create what you need. Are you experiencing actual problems or just trying to fine tune? – candied_orange Jun 11 '16 at 3:12
1

If possible create a linked profile between both, allowing you the power to instantly edit/compare/control files on both dev and prod. That is my suggestion, but if anyone else comes along with better experience than me, I would take it from them.

  • In maven config file i have already a spring.profile variable which filter on the web.xml the spring.profile.default environment variable for spring. But at the moment it's only maven DEV = spring DEV and maven PROD = spring PROD – Walfrat Jun 9 '16 at 6:53
1
+100

I would not recommend to put multiple build targets in single Maven project and perform the app customization during build via Spring profiles. This solution is hard to support, because it has reduced visibility of the functionality belonging to specific application/execution context.

Plugin architecture would be better choice here, because it clearly separates the common code from the customer specifics. How can you do that?

Project structure

  project
    core
      pom.xml
    feature1
      pom.xml
    feature2
      pom.xml
    app1
      pom.xml
    app2
      pom.xml

Here you have common functionality in core module and two apps for different customers, that include the core and some of the features as dependencies. "mvn integration-test" of the root project compiles the core, the features and the source code of apps and runs tests, but does not assembly the apps. You can assembly the specific app by building its module.

Application architecture

The core module is an app that can run itself - it contains all necessary infrastructure and minimal functionality. It provides optional interfaces for plugins and configuration API, which allow customization per customer.

Every feature module from above example is a plugin, extending some of the core interfaces. You may use OSGi, but the simplest solution will be to use runtime discovery of Spring application context configurations (you can use web fragments from Servlet 3.0 or let your default configuration include all files from classpath located in, say, '/META-INF/my-spring-plugins'). There you can put all additional configuration and define plugin beans. Let's say for some customer you need a feature A, accessible via REST API as an action on some entity. You can define a component, that will collect list of actions from beans implementing IActionProvider interface. In feature A plugin you implement this interface and return the action definition for this feature.

The app module is a plugin too: it can extend the interfaces that control application branding, database configuration, enterprise integration configuration etc.

  • 'The core module is an app that can run itself'. Should i consider to include the default REST API in the core so ? Because my default runtime environement is a web rest server. – Walfrat Jun 13 '16 at 7:33
  • If it's common for all apps, yes, that should be part of the core. An example of such architecture is Eclipse: in it's minimally working distribution it's just a set of modules for OSGi framework (the launcher and plugin API) and basic UI (like basic REST endpoints in your case). It's big enough to have it's core split into multiple modules (you don't have to do that unless you see value in such separation), but the idea is still the same - all meaningful functions like Java or Python IDE are plugins and all distributions are in fact core + plugins + configuration. – Ivan Gammel Jun 13 '16 at 8:58
  • ok thanks, i'll have to think about it. I have currently a stack JAX-RS+CXF+SPRING MVC, so i though maybe i should keep CXF away. If i don't know i guess it's just easier to have them together and split after. – Walfrat Jun 13 '16 at 9:03
  • Agree, if you don't see how this architecture will evolve, defer the unclear decisions for later - just make sure you have recorded it somewhere as technical debt for review in future. – Ivan Gammel Jun 13 '16 at 9:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.