简体   繁体   English

Maven多模块项目结构问题

[英]Maven Multi Module Project Structuring Issues

Well here is an interesting experience i had since last couple of weeks structuring my maven multi module project. 这是一个有趣的经历,我在过去几周构建我的maven多模块项目。

When i decided to use maven for my build life cycle management i had couple of reason that i wished to choose maven. 当我决定使用maven进行构建生命周期管理时,我有几个理由想要选择maven。

a. 一个。 Mostly development teams are divided so that each team can work on separate Module within the project like Team-A to work on User Management System, Team-B to work on Authorization System, Team-C to work on Document Management System...and so on. 大多数开发团队都是分开的,这样每个团队都可以在项目中的单独模块上工作,比如Team-A来处理用户管理系统,Team-B来处理授权系统,Team-C来处理文档管理系统......以及等等。 Each team has java developers, testers, UI experts etc. 每个团队都有java开发人员,测试人员,UI专家等。

So the maven Project structure should be such that each team can independently work on their respective modules. 因此,maven项目结构应该是每个团队可以独立地在各自的模块上工作。 They must be able to code, compile, build, test, deploy their module without having to compile, test modules belonging to other teams. 他们必须能够编写,编译,构建,测试,部署他们的模块,而无需编译,测试属于其他团队的模块。

And thus i came to conclusion that each development module of the maven multi-module project must represent a Functional Module 因此我得出结论,maven多模块项目的每个开发模块都必须代表一个功能模块

项目结构1

After some discussions on forums i found people suggesting me to follow layered approach were child modules must be layers like controller-layer,service-layer,dao-layer etc. I did not pay heed to this advice because this not solving my purpose of teams working on individual module. 在论坛上进行了一些讨论之后,我发现人们建议我遵循分层方法,子模块必须是层次,如控制器层,服务层,dao层等。我没有注意这个建议,因为这不能解决我的团队目的致力于个人模块。 This way for large project the build and deployment time for each team during development increases which does impact the project time-lines. 对于大型项目,这种方式在开发期间每个团队的构建和部署时间增加,这确实影响了项目时间线。 sometimes the build and deploy time is upto 30 minutes say if there are 10 to 11 modules in the project. 有时,如果项目中有10到11个模块,则构建和部署时间最多为30分钟。

But i did pay heed to a suggestion that keeping DAO layer separate for each module is not a good idea as DAO is highly granular and reused by other modules. 但我确实注意到为每个模块保持DAO层分离的建议并不是一个好主意,因为DAO非常精细并且被其他模块重用。 and so the dependency of one module on other would would any how become greater. 因此,一个模块对其他模块的依赖性将会变得更大。

I found a solution to this problem by creating a common module and moving DAOs and DOMAIN to the common module which will be inherited as a dependency by each module. 我通过创建一个公共模块并将DAO和DOMAIN移动到公共模块找到了解决这个问题的方法,公共模块将作为每个模块的依赖继承。 And this seems to be a more viable option. 这似乎是一个更可行的选择。 Now the Project Structure looks like this. 现在项目结构看起来像这样。

项目结构2

Now when i build the project and run the webapp on server, It complains 404, Resource Not Found. 现在,当我构建项目并在服务器上运行webapp时,它会抱怨404,资源未找到。 I found that this is because the WEB-INF/classes folder is missing, src/main/java is missing in web-app module. 我发现这是因为缺少WEB-INF / classes文件夹,web-app模块中缺少src / main / java。 I searched and found couple of links that suggested it is Deployment Assembly issue in Eclipse. 我搜索并发现了一些链接,表明它是Eclipse中的部署程序集问题。 So i need to manually create these folders and add in the deployment assembly because maven does not do it. 所以我需要手动创建这些文件夹并添加部署程序集,因为maven没有这样做。

But the bigger questions are 但更大的问题是

  1. do i need to move the Controller classes like com.mycompany.usermgmtsys.controller.UserMgmtController etc.. to src/main/java Or maven should find the controllers from the module jars included as dependency in WEB-INF/lib. 我需要将控制器类(如com.mycompany.usermgmtsys.controller.UserMgmtController等)移动到src / main / java或者maven应该从WEB-INF / lib中作为依赖项包含的模块jar中找到控制器。

I dont want to do this ie putting java file in web-app. 我不想这样做,即将java文件放在web-app中。 i want all the controllers should be available to the web-app as dependency for example WEB-INF/lib/usermgmtsystem.jar. 我希望所有控制器都可以作为依赖项用于web-app,例如WEB-INF / lib / usermgmtsystem.jar。 But then wouldnt the Tomcat be looking for controllers in classes folder. 但那么Tomcat不会在类文件夹中寻找控制器。

I dont know what should i do ? 我不知道该怎么办? Any suggestions would be appreciated. 任何建议,将不胜感激。

Its the way the eclipse render maven based project. 它是eclipse渲染基于maven的项目的方式。 It generally creates two structure. 它通常创建两个结构。 One based on master pom (parent project) and others based on individual module pom. 一个基于主pom(父项目)和其他基于单个模块pom。 however doing changes in any structure will reflect in the other one. 但是,任何结构的变化都会反映在另一个结构中。 As a practice I do changes in individual module folder structures and is more easy to read too. 作为一种练习,我在单个模块文件夹结构中进行了更改,并且更易于阅读。

Personally I try to avoid multi-module projects as, if you're using the Maven Release Plugin, you are locked into releasing all your modules together. 我个人试图避免多模块项目,因为如果您使用的是Maven Release Plugin,您将无法一起发布所有模块。

While this may sound like a convenience the problem arises when you need to do bug fix release to one of the modules - you end up releasing all the modules, not just the module with the bug fix, incrementing their version even though they haven't changed. 虽然这可能听起来很方便,当你需要对其中一个模块进行错误修复发布时,问题就出现了 - 你最终发布了所有模块,而不仅仅是带有错误修复的模块,即使它们还没有,也会增加它们的版本改变。

You also take a hit if you're running CI with multi-module projects - you're build typically runs over all modules from you root pom but if you're working in a particular module, you end up taking the hit of building those that haven't changed, in effect losing some of the benefits that the modularization was meant to provide. 如果您正在使用多模块项目运行CI,那么您也会受到欢迎 - 您构建的通常会运行在您的根pom上的所有模块上,但如果您在特定模块中工作,那么您最终会成功构建这些模块没有改变,实际上失去了模块化意味着提供的一些好处。

So, go with independent modules but, and this is the important bit, create a common 'dependency' pom used by each. 因此,使用独立模块,但这是重要的一点,创建一个共同的'依赖'pom使用每个。

A 'dependency' pom is a pom that standardizes all the dependencies across your projects and is different in that those dependencies are specified in the dependencyManagement section rather than the dependencies section (it also sets up standard plugin config, etc). “依赖”pom是一个标准化项目中所有依赖项的pom,不同之处在于依赖项是在dependencyManagement部分而不是依赖项部分中指定的(它还设置了标准的插件配置等)。 This allows your project poms to specify the dependency pom as their parent and then declare the dependencies they need minus the versions, which are picked up from the 'dependency' pom and thus standardized across your projects. 这允许您的项目poms将依赖项pom指定为其父项,然后声明它们所需的依赖项减去版本,这些版本从“依赖项”pom中获取并因此在您的项目中标准化。

If you are still concerned about being able to built everything, this can be achieved with a simple batch-file. 如果您仍然担心能够构建所有内容,可以使用简单的批处理文件来实现。

This is a good question. 这是一个很好的问题。 There are many aspects that must be considered for a useful project layout. 对于有用的项目布局,必须考虑许多方面。 I'd like to try to answer one which you didn't mention. 我想尝试回答你没有提及的问题。 Is your app extensible by users? 您的应用是否可由用户扩展? If it is, then consider creating a separate module for your public API layer (service interfaces, DTOs used by those services, and Exceptions thrown by the services). 如果是,则考虑为您的公共API层创建一个单独的模块(服务接口,这些服务使用的DTO以及服务抛出的异常)。

In our app, we have several maven modules per functional area. 在我们的应用程序中,每个功能区域都有几个maven模块。 The idea is that a group worked on a feature within just one functional area and this isolation kept them messing with sources being modified by another group. 我们的想法是,一个小组只在一个功能区域内处理一个功能,而这种隔离让他们弄乱了被另一个组修改的源。 Each functional area is broken down further in maven sub-modules we call "api", "domain", and "service" - we don't lump services/controllers, domain, and exceptions into a single module. 每个功能区域在我们称为“api”,“域”和“服务”的maven子模块中进一步细分 - 我们不会将服务/控制器,域和异常集中到单个模块中。 The api module contains those classes we want to expose to customers for their customizations. api模块包含我们希望向客户公开其自定义的类。 Our service layer is the implementation of those interfaces. 我们的服务层是这些接口的实现。 Further, we do not allow one module's service to call another module's service as this would bypass our service orchestration layer where customer can attach extensions to our services. 此外,我们不允许一个模块的服务调用另一个模块的服务,因为这会绕过我们的服务编排层,客户可以在其中附加我们服务的扩展。 Using separate maven modules per functional area helps enforce this. 每个功能区使用单独的maven模块有助于实现这一点。

We have other modules (internal-api, web, adapter) but they don't really add to this topic. 我们有其他模块(internal-api,web,adapter),但它们并没有真正添加到这个主题。

I figured out the issue. 我想出了这个问题。 Controllers are presentation-layer components. 控制器是表示层组件。 The dispatcher expects the presentation layer components in the WEB-INF/classes folder in the target rather than looking for it in the lib. 调度程序期望目标中的WEB-INF / classes文件夹中的表示层组件,而不是在lib中查找它。 I am not sure if this is valid only for maven based structuring in eclipse. 我不确定这是否仅适用于eclipse中基于maven的结构化。 So finally these are the changes i have made 所以最后这些是我所做的改变

a. 一个。 Created a src/main/java source folder in web-app. 在web-app中创建了一个src / main / java源文件夹。 It is not generated by default in web-app module. 默认情况下,它不会在Web应用程序模块中生成。 b. Add packages and respective controllers in the src/main/java folder. 在src / main / java文件夹中添加包和相应的控制器。

So the final structure that i have (i am not pasting exact eclipse snapshot, this is generalized view) 所以我拥有的最终结构(我没有粘贴精确的eclipse快照,这是一般化的视图)

最终结构

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM