Project structure organization: how to make it better? - java

All -
we have several web applications, all based on some version of Spring developed over time by different team across organizations. They each produce their own WAR, have a different context to work within, and often gets deployed on the same machine, as their functionalities are closely knit together. So we end up with:
tomcat/webapps/{A, B, C ... }
upon deployment, each use a very similar set of tool chains, replicate all Spring jars and dependencies all around.
I am wondering if there is a way to make the project structure better, deploy as a SINGLE war, while allowing each webapp live in their own source repo and have its own pace of development??
Any pointer or references are much appreciated.
Oliver

Deploying in a single WAR will couple all the projects together. Modifying one will mean redeploying all, with the accompanying QA effort to validate and do regression. I wouldn't recommend that.
Multiple copies of Spring JARs can be addressed by putting them in the Tomcat /lib; they're loaded by the Tomcat class loader instead of the WAR class loader. That will mean that every app has to be on the same version of Spring; upgrading one means upgrading all. You'll have to regression test all at once.
What harm is separate WAR files doing you? What do you care if the Tomcat /webapps directory has lots of deployments? One advantage is that they CAN be on separate release schedules. That's a big one to give away. Be sure you have a good reason before doing it.

you would have to probably move to an app server like jboss, but couldn't you use an ear file and have maven build the modules for you? That way you could probably put them in separate repos if you want each with it's own pom and then have another project with a pom for the ear file:
here is the maven ear plugin:
http://maven.apache.org/plugins/maven-ear-plugin/
here is an older blog post about multiple spring app ear file (single applicationContext fo all wars to share if you need):
http://blog.springsource.com/2007/06/11/using-a-shared-parent-application-context-in-a-multi-war-spring-application/

Based on one of your comments to another response, it sounds like you might be more interested in maven's multi-module project feature. This will allow you to define a parent POM with consistent dependencies and project layouts managed across multiple projects.
You might benefit from combining each project into a single WAR, but I do think this is really one of those 'the grass is always greener' problems. One key thing I would keep in mind is figuring out how much longer (or shorter!) is redeployment going to take if the projects were combined.

Think about OSGi. You can deploy all the dependencies just once, build your separate but interrelated modules as OSGi bundles, and deploy and upgrade them all independently. You can also choose whether to deploy them all as WARs (web bundles) or to deploy them as JARs with one or many WARs importing them to tie everything up. Virgo Web Server, formerly Spring DM Server, is really nice and comes ready to do this kind of stuff right out of the box.

Related

What is the recommended way to develop wars for an embedded jetty server in eclipse?

I'm working on a set of independent applications that share some common endpoints. The way I have it setup is to have each application be an independent war, and to have an embedded jetty server which provides those common endpoints. The embedded jetty server sets up the endpoints and loads the wars upon start. Each of our customers will have different applications installed, but will always have the common part, hence the need to have independently installable application wars.
This basic architecture is working ok, but in the development cycle I need to build each of the applications war to then run the whole thing with the embedded jetty server. I would like for the whole thing just to auto deploy when changes are made to any of the application files.
Any thoughts on how to do this?
Use a DeploymentManager with a WebAppProvider to find the webapps and deploy them (it will auto-redeploy on change).
Then setup your deployment to use exploded webapp directories, not war files.
You can even opt to setup deployment XML's in a single place, pointing to the contents of each webapp project's target/${project.build.finalName} directory (if using maven).
This works for many things, but not ALL things.
If you change classes or libs then there's a category of issues around memory leaks, and pinned classloaders, that can result in your reloaded webapp not behaving as you expect.
See
https://www.eclipse.org/jetty/documentation/current/preventing-memory-leaks.html

How to maintain JBoss Modules

Recently, I have had to port an app from Tomcat to Wildfly and I'm currently working on setting up the modules directory for Wildfly.
It took a little bit of learning, but I figured out how to set up Spring, ActiveMQ RA, and several other libs as modules. This is working, but it has me worried about future maintenance of the modules directory. I have had to craft the entire directory by hand and I am worried about having to do this for every new dependency that every new app needs.
What are the best practices for maintaining JBoss Modules? Is the modules directory put into some version control system like SVN to detect and propagate changes?
Lets say I need a new framework in my app. From my understanding I would need to download the jars, create a modules directory for the jars, and then repeat this process for each environment in which I need Wildfly. What happens when needing to do this while other apps are running? This seems extremely time consuming in the long run.
I feel like there is a much better way to do this that I am either not realizing or too green with JBoss to understand.
With Maven and a pom, its so simple to hook up to a local or remote repo, and have the entire directory built out and available everywhere automatically. I feel like there must be something similar for JBoss Modules.
At the heart of my question: How are others using JBoss Modules and maintaining it within a production environment? What resources should I read or utilize?
Thanks for your time.
Kevin
I'm also looking for a solution for this.
I have previously been in projects where the JBoss CLI is being used. But I dont like that. It adds complexity as the JBoss CLI scripts are something new that developers need to understand. Changes in files are easier to understand.
I'm thinking of this:
Put a directory in a git-repo that has the exact directory structure as JBoss version used.
standalone-full.xml is put in git-repo/jboss-eap-6.4/standalone/configuration/standalone-full.xml
module.xml-files is put in git-repo/jboss-eap-6.4/modules/system/layers/.../module.xml
Also a setup.sh that will:
Copy the files from the git-repo to the installation directory of JBoss.
Download any jar-files, needed for the modules.xml, from a configured Nexus server. And put them into correct modules-directory.
The benefits are:
No binary files in git.
Changes to configuration of JBoss can be tracked.
The setup can be a part of a bigger scripted setup of for developers or docker images...

How can I reuse a library in multiple WAR/EAR files deployed on an application server?

I'm currently working on an ebanking platform, so out customers are banks. To extend this platform, we develop our own 'xDK' (development kit) for 3rd party developers (usually the banks themselves).
When xDK is used as a dependency (via maven or gradle), it brings along a lot of transitive dependencies in order to work (~25MB). I was trying to think of solutions to make the dependency a bit lighter to use (given that it needs all of its dependencies) which in turn will promote having smaller, more focused services (not exactly micro-services but at least a step closer).
The current situation's benefit is that every service/project can use its own version of xDK and it doesn't have to update until it needs to. The problem is that it doesn't scale. If we assume 100 WAR files having xDK as a dependency, we create a 2.5GB overhead on the application server (even if they all use the same version).
I'll list two options I was thinking of, but I'd like to know if there are better solutions for this problem. Feel free to ask for more info. Thanks in advance.
Similar to JavaEE components (JPA, JAX-RS, ...), we'll have an 'api' dependency and the implementation. The projects will only declare the 'api' as a provided dependency while the implementation will be provided like so:
JBoss module
I haven't worked with other application servers. We (and our customers) only use JBoss EAP, so this might be a JBoss specific solution. We can create a JBoss module for xDK and then make every deployment depend on it via the JBoss deployment descriptor. The benefit is that we get rid of the multiple copies of the library, but we lose on version flexibility. This would mean that there needs to be some kind of governance on which version of xDK you code against in your service. Also, every time there is a breaking change, we'd need to update all services if we want to update the JBoss module to the latest version.
Bundle in an EAR
EARs allow multiple WAR files in them and also jars as libs. xDK will be an EAR dependency. Again, we have the same pros and cons as the previous solution. This solution is JBoss independent. However, it needs an extra build step to collect all the projects and bundle them, which might be annoying for out customers if they need to bundle their own services.
How about using the maven dependency scope of provided to declare that for the individual war files the jar file is provided outside of the war file, and then have another mechanism to inject the shared jar file into the application server?
c.f. https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html

About Java EE deployment style, which is better?

I have a project, b/s architecture. and with EJB.
So, I can deploy it in two package: a war, and a ejb-jar.
and also, I could deploy it in ONE package: a EAR.
what's the advantage of deploy those two package to ONE ear ?
For me the following quotation (taken from the book "JBoss at work") explains it very well:
An EAR is like a carton of eggs—it keeps everything organized. While the carton doesn’t
add any direct value to your omelet, it makes getting the eggs home from the store so
easy that you wouldn’t think about transporting eggs any other way.
Each egg in your EAR carton is a specific piece of the J2EE puzzle (WAR, EJB, JAR).
edit as suggested by #DavidWallace find a refined answer below...
There is no such thing as an "advantage" of an EAR.
PRO: You can put everthing thing you need to deploy into a single archive.
CON: If you include a vendor specific deployment descriptor (for easy deployment) you might need to repackage the EAR if you want to deploy it into an application server from a different vendor.
At the end it's only a matter of assembling/packaging if you use an EAR or separate modules. Independent from that there is no extra coding needed.
Just my 2 cents to discussion here. If there is dependency between modules (e.g. war components are calling EJBs) I'd vote for single ear deployment, because:
easier management (single install/uninstall, start/stop) and a bit more logical (if you stop just ejb-jar, your web module wont work anyway.
can share some classes via util jars in ear/lib folder instead of duplication in each module or creating external shared lib
can use local interfaces and auto binding of #EJB references
Two separate modules would be better, if:
ejb-jar is shared by many independent applications (web modules) (kind of shared, service layer)
you would like to update web module without affecting ejb module.

I would like to get some suggestion regarding multiple ejb-jars in one ear

I would like to get some advise. I have an application which consist of modules. A module is sliced to 3 parts, so every module has:
- libraries (shared jars, DTOs, beans)
- swing stuffs
- ejb stuffs
The whole is packaged in one ear file and it may contains many ejb jars, currently 3. To handle separated the ejb jars of the particular modules of my application is, I think, the easiest way to manage the whole. Later I would like to use OSGi to handle the modules. But, this is the future.
Every ejb jar has own persistence.xml and it works. I can deploy it, the hibernate creates the tables and I can use my application. But I have that feeling this is not the best or proper solution to handle this "multiple ejb jars in one ear" situation. I would like to know what is the best or proper solution or what is your suggestion.
Thanks in advance!
The way you do it is actually the best OO-solution: you seperate your concerns.
Moreover you also have more flexibility in the current situation: you can leave out or change one of the ejb jar files and your application will still deploy and keep working.

Categories

Resources