We all know what EARs(Enteprise Archive) are. When talking about enterprise software this is a common term used where we bundle up our application with all the required JAR(Java Archive) files needed by our application at runtime. This has been done for many years and people have adapted to it. Bundling up WARs(Web Archive) inside EARs is a common practice too.
In the initial stage even our current application was structured in such a way that in the end an EAR is deployment to our Application server along with the configs needed. Note that i am talking with respective to JBoss Application Server 4.2.3 ( Refereed as Jboss from here onwards). Our application is hosted within a Jboss A/S and hence it goes into the server/default folder in development.
The problem we faced was when we were doing a production release. Our servers were remotely hosted at a local internet service provider's(ISP) data warehouse. And our typical EAR came to about 40MB in size which took about 45min - 1 hr to copy to the remote servers. This posed a problem and a probable bottleneck in the overall process of pushing a build as i saw it. So i was looking at any other way we can achieve some efficiency in this regard.
The solution i came up with was influenced by Julius Ceasar many years ago when He devised the Divide and Conquer Mechanism. Our problem as i saw was that our application code was only a mere 5-8MB where as the dependent JAR files amounted around 30MB in size.
So what i did was i took our the EAR building(Note that we are using Maven as our build tool) out of the process and bundled up our application as shown in the diagram below. Note that the diagram below depicts my approach to the problem at hand.
Note that now as we have separated the thirdparty JARs into a separate JAR file we only deploy this once and whenever a new dependency adds up (which is rare because the project is matured into a stable position). Now we only have to deploy the Other JAR files including the WAR which is only around 8-10MB of size overall. So overall our deployment time is now reduced to 10-15 mins which took almost an hour before with the EAR approach. I wrote a separate assembly descriptor to bundle up the required JAR files in our project into a single JAR file. If any of you guys want this i can share the assembly descriptor file i wrote.
One downside i have to note with this approach is that we cannot use JPA as JPA requires you to have a persistence.xml inside your EARs/WARs META-INF directory. But still it might work if we put the persistence.xml inside the domain/dto jar file but i have not tested this. But this was not an issue for us because we initially decided to go with Hibernate using Spring's Hibernate Template as the abstraction layer.
With the advent of jee6 now you can have your EJBs running inside your WAR. But the application server i have talked about here does not support jee6 and hence this is the only viable solution i could come up with.
That's about it. I do not know how this will scale with other application servers as i can only guarantee this working in JBoss. But for me its time to say good by to EARs which is too bloated as per my experience.
I think you can find standard tools that compute the diff between 2 files and save it as a patch.
ReplyDeleteYou then only need to send the patch to the server as the old EAR is already there. This may take even less time.
could you just build the ear on the remote server instead? that way all of those extra jars would sit on the remote server's maven repo or wherever.
ReplyDelete@Steven - we are unable to do this because our prod is a secured environment and we are unable to access our source repo from within this environment.
ReplyDelete@anon - thx for the tip, i will def look into such tools as you mentioned.
You can still use an EAR to assemble your application components. Instead of bundling all your dependent JARs into your EAR, you can put them in JBOSS_HOME/server/default/lib. You can also put JARs in a separate directory and reference the directory in JBOSS_HOME/server/default/conf/jboss-service.xml.
ReplyDelete@Robert - Thx for your valuable feedback.. Appreciate it. What you say works too.. the first idea of putting it in the default/lib will work but not an ideal solution as i see because its messing with your original jboss configuration. Putting in a separate directory sounds like it will work too.But again it needs changes to your original jboss conf files.But Will give it a try and see. Thx for leaving by a comment Robert.
ReplyDeleteCheers