Repository layout for large Maven projects - java

I have a large application (~50 modules) using a structure similar to the following:
Application
Communication modules
Color communication module
SSN communication module
etc. communication module
Router module
Service modules
Voting service module
Web interface submodule for voting
Vote collector submodule for voting
etc. for voting
Quiz service module
etc. module
I would like to import the application to Maven and Subversion. After some research I found that two practical approaches exists for this.
One is using a tree structure just as the previous one. The drawback of this structure is that you need a ton of tweaking/hacks to get the multi-module reporting work well with Maven. Another downside is that in Subversion the standard trunk/tags/branches approach add even more complexity to the repository.
The other approach uses a flat structure, where there are only one parent project and all the modules, submodules and parts-of-the-submodules are a direct child of the parent project. This approach works well for reporting and is easier in Subversion, however I feel I lose a bit of the structure this way.
Which way would you choose in the long term and why?

We have a largish application (160+ OSGi bundles where each bundle is a Maven module) and the lesson we learned, and continue to learn, is that flat is better. The problem with encoding semantics in your hierarchy is that you lose flexibility. A module that is 100% say "communication" today may be partly "service" tomorrow and then you'll need to be moving things around in your repository and that will break all sorts of scripts, documentation, references, etc.
So I would recommend a flat structure and to encode the semantics in another place (say for example an IDE workspace or documentation).
I've answered a question about version control layout in some detail with examples at another question, it may be relevant to your situation.

I think you're better off flattening your directory structure. Perhaps you want to come up with a naming convention for the directories such that they sort nicely when viewing all of the projects, but ultimately I don't think all of that extra hierarchy is necessary.
Assuming you're using Eclipse as your IDE all of the projects are going to end up in a flat list once you import them anyway so you don't really gain anything from the additional sub directories. That in addition to the fact that the configuration is so much simpler without all the extra hierarchy makes the choice pretty clear in my mind.
You might also want to consider combining some of the modules. I know nothing about your app or domain, but it seems like a lot of those leaf level modules might be better suited as just packages or sets of packages inside another top level module. I'm all for keeping jars cohesive, but it can be taken too far sometimes.

Related

Java good practices of which class should go where (packages) [duplicate]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
The community reviewed whether to reopen this question last year and left it closed:
Original close reason(s) were not resolved
Improve this question
A little while ago, I saw a question answered here regarding the fine-grained organization of Java packages. For example, my.project.util, my.project.factory, my.project.service, etc.
Are there best practices with regards to the organization of packages in Java and what goes in them?
How do you organize your classes in your Java project?
For instance, a project I'm working on with a few people has a package called beans. It started out being a project containing simple beans, but it has ended up (through poor experience and lack of time) containing everything (almost). I've cleaned them up a little, by putting some factory classes in a factory package (classes with static methods that create beans), but we have other classes that do business logic and others that do simple processing (not with business logic) like retrieving a message for a code from a properties file.
I organize packages by feature, not by patterns or implementation roles. I think packages like:
beans
factories
collections
are wrong.
I prefer, for example:
orders
store
reports
so I can hide implementation details through package visibility. Factory of orders should be in the orders package so details about how to create an order are hidden.
Package organization or package structuring is usually a heated discussion. Below are some simple guidelines for package naming and structuring:
Follow Java package naming conventions
Structure your packages according to their functional role as well as their business role
Break down your packages according to their functionality or modules. e.g. com.company.product.modulea
Further break down could be based on layers in your software. But don't go overboard if you have only few classes in the package, then it makes sense to have everything in the package. e.g. com.company.product.module.web or com.company.product.module.util etc.
Avoid going overboard with structuring, IMO avoid separate packaging for exceptions, factories, etc. unless there's a pressing need.
If your project is small, keep it simple with few packages. e.g. com.company.product.model and com.company.product.util, etc.
Take a look at some of the popular open source projects out there on Apache projects. See how they use structuring, for various sized projects.
Also consider build and distribution when naming (allowing you to distribute your API or SDK in a different package, see the servlet API)
After a few experiments and trials, you should be able to come up with a structuring that you are comfortable with. Don't be fixated on one convention, be open to changes.
Short answer: One package per module/feature, possibly with sub-packages. Put closely related things together in the same package. Avoid circular dependencies between packages.
Long answer: I agree with most of this article
I prefer feature before layers, but I guess it depends on your project. Consider your forces:
Dependencies
Try minimize package dependencies, especially between features.
Extract APIs if necessary.
Team organization
In some organizations teams work on features and in others on layers.
This influence how code is organized, use it to formalize APIs or
encourage cooperation.
Deployment and versioning
Putting everything into a module make deployment and versioning
simpler, but bug fixing harder. Splitting things enable better
control, scalability and availability.
Respond to change
Well organized code is much simpler to change than a big ball of mud.
Size (people and lines of code)
The bigger the more formalized/standardized it needs to be.
Importance/quality
Some code is more important than other. APIs should be more stable then the implementation. Therefore it needs to be clearly separated.
Level of abstraction and entry point
It should be possible for an outsider to know what the code is about, and where to start reading from looking at the package tree.
Example:
com/company/module
+ feature1/
- MainClass // The entry point for exploring
+ api/ // Public interface, used by other features
+ domain/
- AggregateRoot
+ api/ // Internal API, complements the public, used by web
+ impl/
+ persistence/
+ web/ // Presentation layer
+ services/ // Rest or other remote API
+ support/
+ feature2/
+ support/ // Any support or utils used by more than on feature
+ io
+ config
+ persistence
+ web
This is just an example. It is quite formal. For example, it defines two interfaces for feature1. Normally that is not required, but it could be a good idea if used differently by different people. You may let the internal API extend the public.
I do not like the 'impl' or 'support' names, but they help separate the less important stuff from the important (domain and API). When it comes to naming, I like to be as concrete as possible. If you have a package called 'utils' with 20 classes, move StringUtils to support/string, HttpUtil to support/http and so on.
Are there best practices with regards to the organisation of packages in Java and what goes in them?
Not really, no. There are lots of ideas, and lots opinions, but real "best practice" is to use your common sense!
(Please read No best Practices for a perspective on "best practices" and the people who promote them.)
However, there is one principle that probably has broad acceptance. Your package structure should reflect your application's (informal) module structure, and you should aim to minimize (or ideally entirely avoid) any cyclic dependencies between modules.
(Cyclic dependencies between classes in a package / module are just fine, but inter-package cycles tend to make it hard understand your application's architecture, and can be a barrier to code reuse. In particular, if you use Maven you will find that cyclic inter-package / inter-module dependencies mean that the whole interconnected mess has to be one Maven artifact.)
I should also add that there is one widely accepted best practice for package names. And that is that your package names should start with your organization's domain name in reverse order. If you follow this rule, you reduce the likelihood of problems caused by your (full) class names clashing with other peoples'.
I've seen some people promote 'package by feature' over 'package by layer', but I've used quite a few approaches over many years and found 'package by layer' much better than 'package by feature'.
Further to that, I have found that a hybrid: the 'package by module, layer then feature' strategy works extremely well in practice as it has many advantages of 'package by feature':
Promotes creation of reusable frameworks (libraries with both model
and UI aspects)
Allows plug and play layer implementations - virtually impossible with 'package by feature', because it places layer implementations in the same package/directory as the model code.
Many more...
I explain in depth here: Java Package Name Structure and Organization, but my standard package structure is:
revdomain.moduleType.moduleName.layer.[layerImpl].feature.subfeatureN.subfeatureN+1...
Where:
revdomain Reverse domain, e.g., com.mycompany
moduleType [app*|framework|util]
moduleName, e.g., myAppName if module type is an app or 'finance' if it’s an accounting framework
layer [model|ui|persistence|security etc.,]
layerImpl, e.g., wicket, jsp, jpa, jdo, hibernate (Note: not used if layer is model)
feature, e.g., finance
subfeatureN, e.g., accounting
subfeatureN+1, e.g., depreciation
*Sometimes 'app' is left out if moduleType is an application, but putting it in there makes the package structure consistent across all module types.
I'm not aware of standard practices for package organization. I generally create packages that cover some reasonably broad spectrum, but I can differentiate within a project. For example, a personal project I'm currently working on has a package devoted to my customized UI controls (full of classes subclassing swing classes). I've got a package devoted to my database management stuff, I've got a package for a set of listeners/events that I've created, and so on.
On the other hand I've had a coworker create a new package for almost everything he did. Each different MVC he wanted got its own package, and it seemed a MVC set was the only grouping of classes allowed to be in the same package. I recall at one point he had 5 different packages that each had a single class in them. I think his method is a little bit on the extreme (and the team forced him to reduce his package count when we simply couldn't handle it), but for a nontrivial application, so would putting everything in the same package. It's a balance point you and your teammates have to find for yourself.
One thing you can do is try to step back and think: if you were a new member introduced to the project, or your project was released as open source or an API, how easy/difficult would it be to find what you want? Because for me, that's what I really want out of packages: organization. Similar to how I store files in folder on my computer, I expect to be able to find them again without having to search my entire drive. I expect to be able to find the class I want without having to search the list of all classes in the package.

Splitting Large GWT app into several modules

I have an app written with GWT and GAE where every supported city has its own app. Clearly this is not the best way to manage the map so I want to merge them all into one app. Currently my app is at the urls sub1.myapp.com, sub2.myapp.com, sub3.myapp.com, etc, and I want them to be at myapp.com/sub1 ,myapp.com/sub2, etc. All the supported cities share common code, so I'm going to put all the that code in one module, and have a different module for each piece of unique code block. Is this going about it the right way? How will the different modules interact?
Also, I currently have JSPs at sub1.myapp.com/listofsomesort and I would like to move these to myapp.com/sub1/listofsomesort. Is there a simple way to accomplish this?
By making a module with EntryPoint for each old application, in one and the same application. Each module has one 'welcome page' which you can put in different directories. All the shared code can go into another module. The shared code can be used by the inherit setting in other modules.
The only thing I bumped into was that when you deploy to GAE, ALL modules should have an entry point, also the library modules. I solved it by adding a dummy EntryPoint to them, that does nothing, but still searching for a better solution. See my question at How to deploy GWT Project containing GWT modules without entry points with Eclipse GAE plugin?.
This seems like the job for Code Splitting :) It might require some changes in the structure of your code, though - depends how tightly coupled your classes are. A compile report should tell you if your code splits up nicely, or if not, where the connections are.

Are there best practices for (Java) package organization? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
The community reviewed whether to reopen this question last year and left it closed:
Original close reason(s) were not resolved
Improve this question
A little while ago, I saw a question answered here regarding the fine-grained organization of Java packages. For example, my.project.util, my.project.factory, my.project.service, etc.
Are there best practices with regards to the organization of packages in Java and what goes in them?
How do you organize your classes in your Java project?
For instance, a project I'm working on with a few people has a package called beans. It started out being a project containing simple beans, but it has ended up (through poor experience and lack of time) containing everything (almost). I've cleaned them up a little, by putting some factory classes in a factory package (classes with static methods that create beans), but we have other classes that do business logic and others that do simple processing (not with business logic) like retrieving a message for a code from a properties file.
I organize packages by feature, not by patterns or implementation roles. I think packages like:
beans
factories
collections
are wrong.
I prefer, for example:
orders
store
reports
so I can hide implementation details through package visibility. Factory of orders should be in the orders package so details about how to create an order are hidden.
Package organization or package structuring is usually a heated discussion. Below are some simple guidelines for package naming and structuring:
Follow Java package naming conventions
Structure your packages according to their functional role as well as their business role
Break down your packages according to their functionality or modules. e.g. com.company.product.modulea
Further break down could be based on layers in your software. But don't go overboard if you have only few classes in the package, then it makes sense to have everything in the package. e.g. com.company.product.module.web or com.company.product.module.util etc.
Avoid going overboard with structuring, IMO avoid separate packaging for exceptions, factories, etc. unless there's a pressing need.
If your project is small, keep it simple with few packages. e.g. com.company.product.model and com.company.product.util, etc.
Take a look at some of the popular open source projects out there on Apache projects. See how they use structuring, for various sized projects.
Also consider build and distribution when naming (allowing you to distribute your API or SDK in a different package, see the servlet API)
After a few experiments and trials, you should be able to come up with a structuring that you are comfortable with. Don't be fixated on one convention, be open to changes.
Short answer: One package per module/feature, possibly with sub-packages. Put closely related things together in the same package. Avoid circular dependencies between packages.
Long answer: I agree with most of this article
I prefer feature before layers, but I guess it depends on your project. Consider your forces:
Dependencies
Try minimize package dependencies, especially between features.
Extract APIs if necessary.
Team organization
In some organizations teams work on features and in others on layers.
This influence how code is organized, use it to formalize APIs or
encourage cooperation.
Deployment and versioning
Putting everything into a module make deployment and versioning
simpler, but bug fixing harder. Splitting things enable better
control, scalability and availability.
Respond to change
Well organized code is much simpler to change than a big ball of mud.
Size (people and lines of code)
The bigger the more formalized/standardized it needs to be.
Importance/quality
Some code is more important than other. APIs should be more stable then the implementation. Therefore it needs to be clearly separated.
Level of abstraction and entry point
It should be possible for an outsider to know what the code is about, and where to start reading from looking at the package tree.
Example:
com/company/module
+ feature1/
- MainClass // The entry point for exploring
+ api/ // Public interface, used by other features
+ domain/
- AggregateRoot
+ api/ // Internal API, complements the public, used by web
+ impl/
+ persistence/
+ web/ // Presentation layer
+ services/ // Rest or other remote API
+ support/
+ feature2/
+ support/ // Any support or utils used by more than on feature
+ io
+ config
+ persistence
+ web
This is just an example. It is quite formal. For example, it defines two interfaces for feature1. Normally that is not required, but it could be a good idea if used differently by different people. You may let the internal API extend the public.
I do not like the 'impl' or 'support' names, but they help separate the less important stuff from the important (domain and API). When it comes to naming, I like to be as concrete as possible. If you have a package called 'utils' with 20 classes, move StringUtils to support/string, HttpUtil to support/http and so on.
Are there best practices with regards to the organisation of packages in Java and what goes in them?
Not really, no. There are lots of ideas, and lots opinions, but real "best practice" is to use your common sense!
(Please read No best Practices for a perspective on "best practices" and the people who promote them.)
However, there is one principle that probably has broad acceptance. Your package structure should reflect your application's (informal) module structure, and you should aim to minimize (or ideally entirely avoid) any cyclic dependencies between modules.
(Cyclic dependencies between classes in a package / module are just fine, but inter-package cycles tend to make it hard understand your application's architecture, and can be a barrier to code reuse. In particular, if you use Maven you will find that cyclic inter-package / inter-module dependencies mean that the whole interconnected mess has to be one Maven artifact.)
I should also add that there is one widely accepted best practice for package names. And that is that your package names should start with your organization's domain name in reverse order. If you follow this rule, you reduce the likelihood of problems caused by your (full) class names clashing with other peoples'.
I've seen some people promote 'package by feature' over 'package by layer', but I've used quite a few approaches over many years and found 'package by layer' much better than 'package by feature'.
Further to that, I have found that a hybrid: the 'package by module, layer then feature' strategy works extremely well in practice as it has many advantages of 'package by feature':
Promotes creation of reusable frameworks (libraries with both model
and UI aspects)
Allows plug and play layer implementations - virtually impossible with 'package by feature', because it places layer implementations in the same package/directory as the model code.
Many more...
I explain in depth here: Java Package Name Structure and Organization, but my standard package structure is:
revdomain.moduleType.moduleName.layer.[layerImpl].feature.subfeatureN.subfeatureN+1...
Where:
revdomain Reverse domain, e.g., com.mycompany
moduleType [app*|framework|util]
moduleName, e.g., myAppName if module type is an app or 'finance' if it’s an accounting framework
layer [model|ui|persistence|security etc.,]
layerImpl, e.g., wicket, jsp, jpa, jdo, hibernate (Note: not used if layer is model)
feature, e.g., finance
subfeatureN, e.g., accounting
subfeatureN+1, e.g., depreciation
*Sometimes 'app' is left out if moduleType is an application, but putting it in there makes the package structure consistent across all module types.
I'm not aware of standard practices for package organization. I generally create packages that cover some reasonably broad spectrum, but I can differentiate within a project. For example, a personal project I'm currently working on has a package devoted to my customized UI controls (full of classes subclassing swing classes). I've got a package devoted to my database management stuff, I've got a package for a set of listeners/events that I've created, and so on.
On the other hand I've had a coworker create a new package for almost everything he did. Each different MVC he wanted got its own package, and it seemed a MVC set was the only grouping of classes allowed to be in the same package. I recall at one point he had 5 different packages that each had a single class in them. I think his method is a little bit on the extreme (and the team forced him to reduce his package count when we simply couldn't handle it), but for a nontrivial application, so would putting everything in the same package. It's a balance point you and your teammates have to find for yourself.
One thing you can do is try to step back and think: if you were a new member introduced to the project, or your project was released as open source or an API, how easy/difficult would it be to find what you want? Because for me, that's what I really want out of packages: organization. Similar to how I store files in folder on my computer, I expect to be able to find them again without having to search my entire drive. I expect to be able to find the class I want without having to search the list of all classes in the package.

Do you follow any guidelines (java) in packaging?

Do you follow any design guidelines in java packaging?
is proper packaging is part of the design skill? are there any document about it?
Edit : How packages has to depend on each other?, is cyclic packages unavoidable?, not about jar or war files.
My approach that I try to follow normally looks like this:
Have packages of reasonable size. Less then 3 classes is strange. Less then 10 is good. More then 30 is not acceptable. I'm normally not very strict about this.
Don't have dependency cycles between packages. This one is tough since many developers have a hard time figuring out any way to keep the dependencies cycle free. BUT doing so teases out a lot of hidden structure in the code. It becomes easier to think about the structure of the code and easier to evolve it.
Define layer and modules and how they are represented in the code. Often I end up with something like <domain>.<application>.<module>.<layer>.<arbitrary substructure as needed> as the template for package names
No cycles between layers; no cycles between modules.
In order to avoid cycles one has to have checks. Many tools do that (JDepend, Sonar ...). Unfortunatly they don't help much with finding ways to fix cycles. That's why I started to work on Degraph which should help with that by visualizing dependencies between classes, packages, modules and layer.
Packaging is normally about release management, and the general guidelines are:
consistency: when you are releasing into integration, pre-production or production environment several deliveries, you want them organized (or "packaged") exactly the same way
small number of files: when you have to copy a set of files from one environment to another, you want to copy as many as possible, if their number is reasonable (10-20 max per component to deliver), you can just copy them (even if those files are important in size)
So you want to define a common structure for each delivery like:
aDelivery/
lib // all jar, ear, war, ...
bin // all scripts used to launch your application: sh, bat, ant files, ...
config // all properties files, config files
src // all sources zipped into jars
docs // javadoc zipped
...
Plus, all those common directory structures should be stored into one common repository (a VCS, or a maven repo, or...), in order to be queried, without having to rebuilt them every time you need them (you do not need that if you have only one or two delivery components, but when you have 40 to 60 of them... a full rebuilt is out of the question).
You can find a lot of information here:
What strategy do you use for package naming in Java projects and why?
The problem with packaging in Java is that it has very little relation to what you would like to do. For example, I like following the Eclipse convention of having packages marked internal, but then I can't define their classes with a "package" protection level.

Package structure for a Java project?

Whats the best practice for setting up package structures in a Java Web Application?
How would you setup your src, unit test code, etc?
You could follow maven's standard project layout. You don't have to actually use maven, but it would make the transition easier in the future (if necessary). Plus, other developers will be used to seeing that layout, since many open source projects are layed out this way,
There are a few existing resources you might check:
Properly Package Your Java Classes
Spring 2.5 Architecture
Java Tutorial - Naming a Package
SUN Naming Conventions
For what it's worth, my own personal guidelines that I tend to use are as follows:
Start with reverse domain, e.g. "com.mycompany".
Use product name, e.g. "myproduct". In some cases I tend to have common packages that do not belong to a particular product. These would end up categorized according to the functionality of these common classes, e.g. "io", "util", "ui", etc.
After this it becomes more free-form. Usually I group according to project, area of functionality, deployment, etc. For example I might have "project1", "project2", "ui", "client", etc.
A couple of other points:
It's quite common in projects I've worked on for package names to flow from the design documentation. Usually products are separated into areas of functionality or purpose already.
Don't stress too much about pushing common functionality into higher packages right away. Wait for there to be a need across projects, products, etc., and then refactor.
Watch inter-package dependencies. They're not all bad, but it can signify tight coupling between what might be separate units. There are tools that can help you keep track of this.
I would suggest creating your package structure by feature, and not by the implementation layer. A good write up on this is Java practices: Package by feature, not layer
The way I usually organise is
- src
- main
- java
- groovy
- resources
- test
- java
- groovy
- lib
- build
- test
- reports
- classes
- doc
I usually like to have the following:
bin (Binaries)
doc (Documents)
inf (Information)
lib (Libraries)
res (Resources)
src (Source)
tst (Test)
These may be considered unconventional, but I find it to be a very nice way to organize things.
The way i usually have my hierarchy of folder-
Project Name
src
bin
tests
libs
docs
One another way is to separate out the APIs, services, and entities into different packages.

Categories

Resources