Like in most spring+hibernate enterprise cases, I want to separate Dao, Service, Web layers into different modules, so that I can reuse Dao layer simultaneously in front-end and admin web site. The issue is I found m2eclipse does not support this multi-module project very well, any solutions?
I'm using eclipse 3.7 and Sonatype m2eclipse, I have a typical multiple-module structure project, one abstract parent, 2 children modules(A and B). I can run "package" from the parent, but I can not get hint when I input a "dot" after any object like system.out, and it says "This compilation unit is not on the build path of a Java project." Moreover, I can not invoke methods in A from B after I set dependencies in A's pom.xml.
I found a very similar issue here Issues with maven project running in eclipse, not recognized as Java project, but which does not solve my problem. I heard m2eclipse has removed this support for multiple-module project, but the need is so common that I'm 100% sure that there must be some kind of solution.
Thanks.
I got it working by importing the whole project and sub-module as individual projects as well. I find in individual projects I can get prompt hint methods and debug, but I'm using the whole project's pom to build.
Multi-module is still supported in m2e, I don't know where you heard that was removed but that's utterly wrong.
You simply need to import your sub modules as existing maven projects.
Also take a look at http://www.sonatype.com/books/m2eclipse-book/reference/creating-sect-importing-projects.html#fig-creating-import-multi
Related
We have a setup of Maven module like this:
Parent
common
webapp
Where webapp has declared a dependency to common.
In our Eclipse environment, using m2e, we made a change in common. Then ran maven package on webapp, deployed and tested the webservice. There was now a fault that indicated that the package we had done did not include the latest changes in common.
We are trying to figure out the best way to use Maven in our day-to-day development. So whats the best practice to handle situations like this?
The way to solve this issue would have been to; Make changes in common, save them, run maven install, make changes in webapp, run maven package, and use the war file for tests. But this contains a lot manual steps.
I guess another way would be to run maven package on the parent, but as the parent grows with more modules this will take longer.
How do you expect changes to common to be available unless you package and deploy it separately? Maven is not magic and it cannot make magic things happen. The solution in this case is to either manually deploy common or do as you suggest package and deploy the parent.
Parent 1.0-SNAPSHOT
+common 1.0-SNAPSHOT
+webapp 1.0-SNAPSHOT
You must use a snapshot version in the parent and reuse the same version in both module.
You must import every module in eclipse
You must run mvn clean install from the parent
If you do all this, Eclipse will recognize when there's a dependency 'webapp' project to 'common' project. Eclipse takes the 'common' project in the build-path of the 'webapp' project. Any change in 'common' is seen by 'webapp'.
Well here is an interesting experience i had since last couple of weeks structuring my maven multi module project.
When i decided to use maven for my build life cycle management i had couple of reason that i wished to choose 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. Each team has java developers, testers, UI experts etc.
So the maven Project structure should be such that each team can independently work on their respective modules. 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
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. 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.
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. 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. And this seems to be a more viable option. Now the Project Structure looks like this.
Now when i build the project and run the webapp on server, It complains 404, Resource Not Found. I found that this is because the WEB-INF/classes folder is missing, src/main/java is missing in web-app module. I searched and found couple of links that suggested it is Deployment Assembly issue in Eclipse. So i need to manually create these folders and add in the deployment assembly because maven does not do it.
But the bigger questions are
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.
I dont want to do this i.e. putting java file in web-app. i want all the controllers should be available to the web-app as dependency for example WEB-INF/lib/usermgmtsystem.jar. But then wouldnt the Tomcat be looking for controllers in classes folder.
I dont know what should i do ? Any suggestions would be appreciated.
Its the way the eclipse render maven based project. It generally creates two structure. One based on master pom (parent project) and others based on individual module 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.
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.
So, go with independent modules but, and this is the important bit, create a common 'dependency' pom used by each.
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). 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.
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).
In our app, we have several maven modules per functional area. 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. The api module contains those classes we want to expose to customers for their customizations. 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.
We have other modules (internal-api, web, adapter) but they don't really add to this topic.
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. I am not sure if this is valid only for maven based structuring in eclipse. So finally these are the changes i have made
a. Created a src/main/java source folder in web-app. It is not generated by default in web-app module.
b. Add packages and respective controllers in the src/main/java folder.
So the final structure that i have (i am not pasting exact eclipse snapshot, this is generalized view)
I am sorry i don't know maven good enough for the complex environment i am currently working in (1k+ applications, most of them are Java EE). I still give it a try to describe what i want to archive:
0.) There is a company framework that abstracts the Java EE World a bit and is used in all the Java EE components
1.) I checked out the maven project of the Java EE component i am working with
during the build it downloads the dependencys of other components out of the companys repository and stores it inside my local repo for compilation. So i can see the jar-files of the companys framework inside my local repo.
2.) I now want to change some of the frameworks functionality for a local test so i checked out their sources from another SVN repository. I made the changes and build that framework component with maven "clean install".
3.) I rebuild the component i am working with as well.
Inside eclipse i can now click on one of a frameworks classes method and it opens the according source. But this only happens because the local repo is meant to contain source-jars for any dependency as well. So in my editor i can see this source is from the jar of the framework in my local repo and i cant change anything.
Could someone please give me a hint how i can archive the following:
I can make changes to the framework (and build the frameworks jars with "clean install")
I can build my component and it uses the above compiled framework jars rather than the "old" ones from the local repo.
I will right now start to read the entire maven documentation and each and every section (i try to understand that dependency management since 1 year and still don't get it) but i would really appreciate if you could help me out a bit here.
I don't know how Eclipse manages maven dependencies, but
In IntelliJ IDEA this is simple - if maven dependency is in project then IDEA uses it instead of dependency from local repo.
So if u want to edit framework source code and use this changes immidiately - i think that framework should be in your Eclipse Workspace. And your module in Eclipse should reference framework artifacts directly - not over Maven dependency mechanism.
I think that this is a Eclipse Maven plugin responsibility. Do u have any installed Maven plugin for Eclipse? (M2Eclipse for example)
We are using maven for manage multi-module projects and Eclipse with m2e for development.
Unfortunately Eclipse by itself does not understand the way Maven works, and even if m2e does a lot of work to make the "a parent pom with modules" Maven way look like the "several logically independent projects" Eclipse way it breaks when I e.g. add a new module to the parent pom. If Maven was a first class citizen I would expect Eclipse to pick up the new module immediately as a new Maven project.
Is there another IDE which has better Maven support, or should I instead lobby the m2e folks?
Didn't work alot with it, but for my knowledge, Netbeans IDE seems to have a quite good maven integration.
Just give it a try on a short example project!
1st of all lobbying the m2e folks is always good - better support for maven is always a good thing.
having said that i work on a ~200-modules maven project using intellij idea. its maven support (which is available in their community edition) is simply great - you dont even need the maven idea plugin to create your project, you just import your pom directly.
it will also correctly handle changes you make to your pom - just add a new to a parent pom and idea will actually offer to create the corresponding directory and child pom for you. and after that it will add the new child module to the project. it also supports "conditional" child modules - modules defined under various profiles. when you enable/disable maven profiles (maven panel, right side of the IDE) it will correctly add/remove child modules to/from the idea project.
not that for larger projects you would want to turn this auto-import off and manually re-import your project (idea will prompt you, or worst-case there's a button for it on the maven panel) as automatically reimporting very large projects will be noticable.
idea will correctly map multi-module tree-like projects into idea multi-module project and will automatically pick up on your libraries, dependencies, maven profiles, etc. its also very easy to execute maven operations directly from it (maven panel on the right side of the IDE).
it doesnt pick on some of our more complicated build steps (we have some utility bound to he lifecycle that generates some of our source code using the maven exec plugin and if you just do a project-->build all from intellij its not picked up for example) but those things arent common. also, you can get around this by executing maven directly from the IDE instead of trying to build from the IDE.
not perfect, but the best i've seen.
I'm having some issues making the maven google app engine plugin work properly.
First of all, I'm not even sure if the archetype I'm using is the correct one, their examples show version 0.7.0 but it seems like never versions exist (i tried 0.9.1 and that works), where can I find a overview of what versions of the plugin is available?
Secondly, the archetype seems.. messy, I don't like the package structure and it doesn't seem to actually include the GAE and GWT dependencies. I have to manually add them to my project in Eclipse, which kind of defeats the purpose of using maven. And how come they are breaking the gwt maven plugin? I know that one includes the actual gwt jars as maven dependencies?
I'm fairly new to Maven, but I have been using the gwt maven plugin for a while, and I'm very happy with everything about it. Is there any way I could just their archetype to do the base project and add the gae plugin to it?
UPDATE
I suspect the problem I'm seeing with the GAE maven plug-in is in regards to undefined properties in the POM. I have no idea if its due to error these aren't set-up or if its due to me actually have to manually set them up. The documentation on this plugin is sparse.
Thanks for the answer below, but I really don't want to add another archetype into play. I think the best solution for me is to try and adapt a GWT maven project manually, to include support for GAE.
I've used the archetype like so :
http://code.google.com/p/gae-mvn-archetype/
to generate a GAE project template.Then manually added my other dependencies. This got me a usable project which I can deploy to GAE and everything.
Also, for Eclipse importing, once the template project was done, I've imported it into eclipse using the m2_eclipse plugin :
http://m2eclipse.sonatype.org/installing-m2eclipse.html
(note that i've imported it into Eclipse as a Maven project, NOT as an Eclipse whatever project)
This imported the thing into eclipse with all the necessary dependencies and without errors.