Tuesday, May 31, 2011

Setting up Maven Enterprise Application Part II

Part II: Setting up individual modules of an EAR






If you've been following along, this is part 2 of two part series in setting up Maven Enterprise Application. Here is part I which shows you how to use maven to setup the overall project structure, configure build path, add module dependencies and libraries. In this second part, I will show you how to structure the individual modules, the JAR and WAR. Since I've assumed that you're using Eclipse/RAD or any other IDE for that matter, I've already discussed how to add WAR to the EAR in part I. From the IDE this is basically adding WAR module dependency to EAR.

Overall View
Before I begin, please see the image below from RAD to see the overall structure. For some of you, this should be enough. You can get this view from Enterprise Explorer in RAD or Project Explorer in Eclipse. Some of you may prefer to use Navigator window. But I am more comfortable with the former two.

[caption id="attachment_53" align="alignnone" width="211" caption="Module Structure"]module_structure[/caption]

JAR Module

The JAR Module will, as I mentioned in Part I, house your model and unit tests for the models. Your model will consist of domains, daos which are your db technology dependent interface and services which are your business interfaces and not underlying db specific. Additionally, you may have custom exception or helper classes.

Your source folder will be under src/main/java. Any resources like perhaps an applicationContext file will be added to src/main/resources. In part I, I mentioned that these locations are added to the classpath. So to read any resource from there you'd write something like classpath*:applicationContext.xml.
Your unit tests (unit tests for JAR module and integration tests for WAR module) will be housed under src/test/java and any resource like applicationContext file will be housed under src/test/resources.

Basically, if you use an ORM tool your domains or entities define relationships and constraints. These domains are package under com.yourComanpyName.applicationName.domain package. You don't write tests for domain objects. Your dao interfaces are packaged under com.yourComanpyName.applicationName.dao and the implementations are packaged under com.yourComanpyName.applicationName.dao.impl. If you're using spring for dependency injection, you'd annotate the implentations as @Repository or define a bean in the application_context.xml file. You would then be able to Autowire your daos to your service and service unit tests. Now daos will have to be unit tested. Therefore you'd create a new package for the tests as com.yourComanpyName.applicationName.dao.impl (same package) under src/test/java. I am not going into details of writing unit tests and daos or any code in this two part series. I will have articles on them later. Now your service methods will be structured similarly to your daos under com.yourComanpyName.applicationName.service and com.yourComanpyName.applicationName.service.impl. You'd want to use DI to initialize them via annotation or xml the same way you'd do for daos because these service methods will be called from WAR module. Your tests for service will go under com.yourComanpyName.applicationName.service.impl under src/test/java. For unit testing you'd want to use a mocking tool like EasyMock or Mockito. You want to mock out the service tests because you do not want to tie up your service to a specific dao implementation. For example, tomorrow you might change from hibernate to using iBatis or JDBC.

So this is basically it as far as your JAR module goes.

WAR Module

The war module will follow the same naming convention as the JAR module. Your sources will be housed under src/main/java and the resources (not web.xml) will be housed under src/main/resources. You can have a folder called WebContent (exists by default in RAD's dynamic application) under which you will have your WEB-INF folder for your web descriptor file (web.xml), static folder for your pages, scripts, css and images. Your tests for source files will be under src/main/test as usual.

Suppose you're using Struts 2, you would then have the action (controllers in Struts 2) classes under com.yourComanpyName.applicationName.web.action package. This is sticking to the naming convention. Your actions will call your injected service interfaces from the JAR module. Your applicationContext file will almost always be the same as what you defined in the JAR module.

Now you'd want to do integration tests in WAR module. The package to create would be the same as for your Action classes (or controllers) but under src/main/test. For integration testing, you'd use a tool to mock out the HttpServletRequest and Session. You can also mock out the db as you did in the service unit tests in the JAR module. That way you are not dependent on dao implementation.

The only thing remaining is to add JAR module as dependency to the WAR module. This I explained in part I. But it is pretty straightforward from the IDE.

You are now all set to start working on your EAR project.

Final Note: I have not covered unit testing or integration testing in any detail for you to be able to go ahead and start writing them. The purpose was only to show you how to setup an EAR using maven. I will have articles related to them later. But the good part is that I won't have to explain the folder structures then. I can always refer to these two articles :)

 

No comments:

Post a Comment