Java domain objects shared between projects - java

I have two Java projects with same domain objects.First project is the administration of a webapp. And second project is the webapp.
I've chosen this approach in order to allow deployment of administration without downtime for my webapp.
So both projects use same database. I'm using spring-data and marking entities with #Entity.
My question is: is there any way to replicate domain objects in each project?
For example creating another maven module with the domain objects and mark as a dependency. (But in this case #Entity will still work?).

the way is just as you said it - create a maven module (usually called datamodel, infomodel or something along those lines) that contains all of your JPA classes (#Entity classes).
this model can either be a completely separate 3rd project (more work) or, more likely, pick one of the 2 projects as the "owner" of the module and the other project will simply list it as a dependency. in both cases you'll need to think about things like version compatibility (what happens when you update administration but not the webapp and the entities changed? who updates the database, how do you make sure the older code can still read/write it?)
as for working, JPA classes work just fine in their own jar.

Like you have raised is a good approximation, separating two different maven projects.
What you're trying to do is very similar to the structure of Broadleaf Commerce. It is a multi-module project using Maven and Spring, is open source, so you can look at how it is structured to see if it helps.
Here you have another guide of how to implement it step by step. Hope it helps.

It seams that you will need at least three modules.
1st - the domain module with the enitity annotated domain classes;
2nd - the application itself witch depends on the domain module;
3rd - the adm module witch also depends on the domain.
Now that you have a multi-module maven project you should have a 4th project formally listing the other three as its child modules.
P.s.: Resist to the temptation of creating separate git repositories and evolving the versions of the modules separately.(just an advice)

Related

How does Maven manage duplicate artifactIds when they belong to a different group?

I'm building some different web projects with Maven and thinking about how to name their artifacts. For the REST API layer, it's convenient to share some classes, so I want to create exchange-api.jar files which will be shared among different projects.
Let's suppose I've got a web application which has it's own exchange-api module. The groupId would be com.mycompany.app1 so the whole maven id for the artifact should be com.mycompany.app1:exchange-api:1.0. Now let's suppose I want to access other app's API from this application. I have to include the dependency com.mycompany.app2:exchange-api:1.0. artifactIds are the same, but the groupId is different. However, both should end up as exchange-api-1.0.jar in the classpath.
How does Maven take care of this? Should I use a unique artifactId for each of them?
Maven manages this problem allowing you to customize the file name mapping, this can be done both for WAR and EAR applications. However I think that your naming convention is poor. Suppose that your projects are publicly downloadable and people not using Maven download them manually and add them to their projects: do you think that a generic "exchange-api" would be clear enough? I think no. Good names are app1-exchange-api and app2-exchange-api. Or simply app1-api and app2-api. There are several examples of this rule: Spring, Hibernate and so on.

Eclipse project layout classpath issues

I have a large scale project I am working on at the moment using Eclipse. Normally, as a one man team, these problems would not be an issue, but as our team is not one person we need to be able to break up pieces of the project to be worked on by certain team members.
In simplicity, let's say I have two layers to be separated apart:
1. Each DAO is a separate Java project, to be worked upon individually
2. The web-tier service layer contains all of our service endpoints and must be able to reference all of the DAOs. This layer runs on Tomcat as a dynamic web project, and utilizes Adobe LiveCycle Data Services as the piece that handles creation and management of endpoints.
Now, the issue we are running into is that when we create a DAO and unit test it individually it runs great. But when we reference it into our service project and try to run it we begin to get all kinds of issues related to the fact that we have two different versions of certain jars referenced in and as such we begin to have errors when running the server.
As a result, we know we can solve the issue by pulling the problem jars and ensuring that this is not an issue again in the future, but as I said before this is a large scale project with multiple people working on it and we don't want to be spending our time weeding out dependency issues when under the gun.
We are looking for recommendations on where to proceed for alternative solutions? Our team is new to JavaEE and as such we don't have much of a bearing on what we can use to tie everything together in it, or if it is a viable solution. Should we be looking at turning our DAOs into EJBs and deploying them in an EAR library? If so, where would our service layer lie, and would the service layer be able to reference the DAO classes since the EJB maintains it's own classpath (from what we have read?) Are we looking down the wrong path, or are we completely wrong in our current understanding of JavaEE?
Any assistance is greatly appreciated. We are still in the framework stage of this project and we want to be sure that we will be able to maintain it in the long run.
I second the Maven recommendation. That can add all sorts of sanity to your project structure.
Maven can even generate Eclipse workspaces via mvn eclipse:eclipse
An important clarification on the EJBs note. As of ava EE 6 is you no longer need to separate EJBs from Servlets and can use them together in the very same jar in the war file.
So understand from that that using EJBs or not no longer has any impact on packaging or classloaders as it once did. These are now separate decisions. EARs and classloader separation should now be viewed as a feature you might want to use should you want classloader separation and the complexity it brings. Most applications simply do not need that and are more than fine with just a war file containing servlets, ejbs, jpa entities, cdi beans, jaxrs services and whatever else you need. You are free to decide how you want to separate them or if you want to bother separating them at all.
EJBs do make great DAOs due to transaction management, something you don't get from plain Tomcat but can be made available in Tomcat via TomEE and works fine in Eclipse. You should consider EJBs for that reason, not for dependency reasons.
Side note, as you're new to Java EE, you might find this helpful:
http://openejb.apache.org/examples-trunk/index.html
In order to have things organized when working with Java EE in teams of 1+ people I could suggest:
Use Maven to manage your build process and library dependencies.
Maven has a small learning curve, but once you grasp it you will be grateful. By using Maven you no longer depends on Eclipse to manage your classpath.
A thing about it that I think is really helpful when working in teams is the install feature. Suppose you are woking on the version 1.0 of an EJB module, say core-ejb-module-1.0, and you've got it to a stable state and want everyone working in the project to refer to it from now on.
You then run a maven command like this on it: mvn clean package install
Maven will clean this module, compile it, run tests, create the jar and then install it to a repository that you define. Could be any computer in your company.
Now you may tell the guys working on other projects to update this dependency version on their .pom file and in the next build they run, before compiling, maven will download this library and then use it. Really neat. No more classpath hell.
(There are other ways to always automatically refer to the latest library as stated in this post, but there are some caveats. Anyway it's just an example.)
Use JPA/EJB instead of DAO Pattern.
Some people say DAO meaning any sort of data access, others really mean that they use the DAO Pattern to access objects. If that is your case, you no longer need to use it when using JPA. (At least for most common scenarios).
In my case, I have a generic EntityService which is capable of doing CRUD operations on any Entity and has a centralized query management. Then every EJB's that should perform database related operations may inject this guy and do its job.
As a suggestion, with Maven, you project could be organized as such:
core project structure
core (The pom root)
core-ejb-module (Includes all generic EJB's, like the EntityService for instance.)
core-jpa-module (Includes all JPA generic definitions, like Interfaces, MappedSuperclasses and such.)
core-jsf-module (Includes all JSF generic definitions, like abstract controllers, generic converters and wrappers for FacesContext, etc..)
Now that you have a core generic module setup, you could create:
an application structure
app (The pom root)
app-ear-module (Includes all other modules in this application. Shared jars goes in the ear /lib folder, so all other modules could reference to them.)
app-ejb-module-a (Includes EJB's for the business layer of your application. It uses the core-ejb-module)
app-ejb-module-b (You may have lots of ejb modules. You may even have a project that contains only ejb modules. Other apps will declare their dependency on them via Maven.)
app-jpa-module (Contains definitions for JPA Entities that represents you database tables. Depends on the core-jpa-module)
app-web-module (Holds the pages, Controllers and Converters for this application.)
I think you got the idea. Things tend to be loosely coupled and you may organize your projects as you like.
This is just a simple example to illustrate. I didn't explained a lot about Maven but if you're interested I think it will help you indeed.
I hope it gives you some ideas and may help you in any way.
[]'s
If you can run all the sub-components using the same set of dependencies, you may find it helpful to migrate to a Maven build.
With Maven, you can define a top-level project that manages all the 3rd party dependency versions in one place, so all modules are built, tested and deployed against the same library versions. You are also likely to find Maven a good fit for the multi-module approach you have adopted, as it ensures that a project is rebuilt correctly if one of its dependencies changes.
You would still be able to use dynamic web projects as before; Eclipse will automatically deploy the DAOs as part of the service project (IIRC you need to characterise the DAOs as utility modules).
If you do go down the EJB root, you are correct that each EAR will get its own class-loader, and can therefore use a varying set of dependencies. However, in your position I would tend to look at improving your dependency management first - it'll probably be cheaper and easier.

Is there any benefit in using Maven Multimodule when working in a small application?

We are building a small application using different architectural layers such as domain, interface, infrastructure and application. This follows the Onion DDD model. Now I am wondering if there is any benefit in splitting the application into a multimodule maven project. As far as I can see now it seems to make things more difficult than needed. The entire application will be deployed as a single WAR file into a Tomcat container.
Splitting your application makes sense for the following:
When a certain part of the project needs to have new functionality or bug fixes, you can simply focus on that module and run just the tests for it. Compiling a fraction of all the code and running just the related tests speeds up your work.
You can re-use the code from the modules across different projects. Let's assume your project contains some well-written generic-enough code for mail sending. If you later have another project that need mail sending functionality, you can simply re-use your existing module or build upon it (in another module by adding it as a dependency).
Easier maintainability on the long run. Maybe now it seems like a small project. In a few months things might look different and then you'll need to do more refactoring to split things into logical units (modules).
Conceptual clarity (as added by Adriaan Koster).
Concerning the WAR: You can have an assembly module which puts things together and produces a final WAR file from all the related modules.
Initially, this may seem as more work, but in the long-run, modularized projects are easier to work with and to maintain. Most sane developers would prefer this approach.
Using multiple modules forces you to have a hierarchy of dependencies. You have one module which is standalone and doesn't depend on any other of your modules. You have another which only depends on that. It might appear harder than allowing anything to depend on anything else but this approach results in a mess of dependencies which is hard to fix later.
If you are trying to follow a layered model I suggest you place each layer in a different module. This will ensure you are not tempted to break the model.
Short answer: today it is small, tomorrow it will bigger and more complicated to maintain, reuse, extend, integrate with other system and so on
As far as I know, Maven do little help for WAR dependencies. As you are talking about single WAR, this should never be a problem.
You can separate java classes into several "jar" submodules, but if you split the WAR project into several smaller WARs, using some kind of "overlapped" packaging things get complicated.
Just information, one of our projects, it contains too many web pages, so we decided to split it into several WAR submodules, however, the session is not shared between different WARs deployed, and we are not going to use Kerberos stuff. At last, we modified a lot sources of Glassfish, Jetty, MyFaces, etc. To make them resolve web.xml stuff inside JARs. And converted the whole project to Facelets 2.0 (to avoid the dependency of JDK tools.jar and custom resource handler), the only reason is to change the WAR submodules to JAR submodules, and move all webapp/pages into class resources. So the conclusion, Maven does great job for JAR dependencies, but no WAR or single WAR.
EDIT You can put applicationContext.xml in one of the base submodule, and import it by classpath:com/example/applicationContext.xml. Also Spring 3.0 do have annotation supports, you can make spring auto scan them instead of declaring them all in the xml.
Spliting your project into multiple maven projects is useful if you want to reuse your classes in another project or if your projects are deployed in different configurations.
Maybe think of a webservice - if you are hosting the server, you could build a project for your domain classes (models) and your endpoint interfaces that could be used by server and client. The server would be another project that is build to a WAR.
To develop further clients the first project could be used, too.
Use a parent project for dependency management on common projects (like logging) and different profiles and build configurations.

Where in Maven should reusable domain and persistence classes go?

I have a Maven project that I want to break out into pieces such that my domain and persistence objects can be reused by other maven projects. What would be considered the best approach?
Move the domain and persistent objects into a separate project and have it be the parent POM of any other projects that need it
Put it in a separate project, but make it a jar to be used as a dependency via POM.xml in other projets
Other?
I wouldn't make it a parent project. Sounds like you need two separate projects; one for domain and one for persist.
If the other modules that need to reference your domain are part of the same releasable unit (they follow the same release cycle) then you can make them modules in a multi-module project. If they have different release cycles then you should treat them as separate projects and define the dependency via the normal Maven dependency mechanism.
If it can be broken down into a separate reusable module do so. I usually have a "-domain" project that deals only with domain objects. In the old days I also put in my Hibernate xml files in there.

Project to isolate entities in Seam

Is it possible to have a Seam project just for entities (src/main) and other projects access them ?
I have a situation that a organization has 6 projects accessing the same entities and i don't want to replicate them in each project. If it is possible, how can i do that ? where can i found documentation about it ?
thanks,
Cateno Viglio
Yes, it is very common way. Look at Richfaces photo album example where you have ejb module holding domain and used as dependency in web module. Of course you must remember adding empty file seam.properties to result jar file.
PS. This example is built by maven and uses ejb (entities and sessions beans). You can use seam-gen and POJO instead if you like.
Depends on what exactly you mean.
Yes, you can declare separate projects for your entity classes. I have about 50 projects roughly. Of those less than a handful are actually web applications packaged as WAR files. The rest are comprised up of utility projects, service projects, listeners, entities, and servlet filters.
Breaking the projects up this way has its advantages and disadvantages. Any time you make a change to a project, you have to propagate that change throughout the other projects. However, it isolates your code and allows you to write unit tests more easily as you can now focus on 5 classes instead of 500.
Another potential downside is, unfortunately PMD won't be able to detect if you duplicated code between your projects. At least I don't know how to do that yet.
I use this pattern (divide and conquer / refactor out replication) quite a bit to avoid duplicate code.

Categories