OFBiz by default works as a collections of small webapps each with its own front controller. OFBiz webapps typically depend on a lot of common modules. Typically, modules under specialpurpose or hot-deploy would end up depending on pretty much all of the modules under framework and applications... with the embedded container, all libraries go into the catalina shared library class loader but if ofbiz needs to be deployed in a different container, there is simply no easy way. the only options i believe are
package ofbiz as an EAR with a EAR/lib or EAR/APP-INF/lib so that all webapps have access to a common set of EAR level classpath resources.. typically each modules's config, lib and the all important ofbiz-$module.jar
each webapp packages each of the required jars into its own WEB-INF/lib.. too much duplication and also increases the filesystem footprint in a sense
use the application system classpath in lieu of catalina shared.lib folder - which means the JVM has to be dedicated to ofbiz as its jars would otherwise interfere with other sibling deployments and potentially even with the container itself, typically things such as XML, XSL, STAX apis etc..
given that ofbiz load most of the resources using the filesystem (ofbiz.home + component://) resulution. What the webapp really needs access to in a convential servlet context kind of way is the
controller.xml
classpath resources - across the various ofbiz-$module.jar in shared.lib. typically, each modules's config, lib and the all important ofbiz-$module.jar
imported (component://) webapp resources like other controller.xml for various modules. most importantly the framework/common/webcommon/WEB-INF/controller.xml that provides the boiler plate security implementation like checkLogin and autoLogin....
I was wondering if we could somehow package multiple webapps into a single monolithic webapp using front controller namespacing so that the war maps to a single root content like say / (ROOT on tomcat) and /content, /webtools, /catalog, /ecommerce etc. are mere URL namespaces/subcontexts rather than separate webapps. framework/common/webcommon/WEB-INF/controller.xml could become the root controller for / (ROOT in tomcat) and provide checkLogin, autoLogin etc to all webapps without each controller having to import that controller.xml
This would allow us to simply the deployment model when we would want to move to other containers like say weblogic, jboss et al where we would be better of building a single webapp with all of its dependencies neatly packaged into its WEB-INF/lib such that it could coexist with other deployments in the same container without interfering with their dependencices and their versions...
I believe struts had this kind of modular namespacing where there could be a root level struts.xml (our case controller.xml) and each module would be a folder with its own module/struts.xml or module/struts-module.xml etc...
i personally feel this would be helpful.. i have not thought enough about the downsides. there could be many? i honestly don't know. I have not given enough thought to themes either.. developers clearly would not like to see any change in the way code is laid out or organized.. so with some minor? :) changes in the core MVC code in the framework, we could potentially support this kind of deployment using a simple ant build script that stages candidate webapps into a merged monolithic webapp...
i was hoping to see a debate on the merits of this idea... i would even be willing to invest some time into making this work if i get some direction and inputs..
Have you considered using chef to deploy Ofbiz instead?
I wrote the following cookbook to demonstrate how it could work:
https://github.com/myspotontheweb/chef-ofbiz
This is a difficult part of how Apache OFBiz is architected. Using EAR files works okay, but shared classpath resources in an EAR file are app-server specific, and you have to deploy in a container that supports EAR files which limits choices.
One of the limitations is the flat namespace for requests in the controller.xml files, and what you describe would be the best way to handle that (use a different ControlServlet mount point for each OFBiz component app). Doing so may require some code changes for the URL writing (the #ofbizUrl FTL tag and the underlying code used elsewhere). It would also require a bit of work to write an ant target or something to build the WAR file, pulling in all the webapps from the various components (or just those desired), writing a combined web.xml file, etc, etc.
This is a recognized issue with OFBiz, and isn't a problem for most deployments, but does make it more difficult to scale down or host along with other applications. You can add other webapps through OFBiz components to host them on the embedded servlet container, but I don't imagine that is what you are looking for.
One of the issues with making this and many similar changes in OFBiz is the large code base, large user base, and the somewhat large committer group with diverse opinions on things like this. For these and other reasons a lot of the ideas for improving OFBiz can't be easily realized there, and that is why I started the Moqui Framework project in 2010.
Moqui deploys with a single WAR file, and can have an external or embedded runtime directory to make it easy to deploy on WAR hosting services such as AWS ElasticBeanstalk, as well as dropping in to servlet containers such as Apache Tomcat. The WAR file is also an executable JAR file using an embedded Winstone servlet container for easier development and automated testing. There are details about running and deploying Moqui here:
http://www.moqui.org/framework/docs/RunDeploy.html
BTW, this is one of hundreds of ideas for improvements to OFBiz that made it into Moqui Framework and the separate project with data model and services (Mantle Business Artifacts). There is general information about it here:
http://www.moqui.org/
Related
I need a advice for design purpose my structure of the application is as follows.
I have three module designed in ZK framework as a separate war application (web application) e.g finance-module , general-ledger and cash-account , all are separate war files can be deploy on tomcat as a separate war files,
Now I want to have a seperate war ZK application that has index or home page and have menu and from that menu I can able to call these three module or war application.
-------------------------- Main module -------------
Menu : general-ledger link , cash-account-link ,finance-module
1) This 4th Main module also has feature to user login and change user preference , means can also have code e.g view module as well as spring service.
Now the question is that how to call other war files zul pages and even if v call how to manage from 4th module and also how to share session across the four war files or applications.
Thanks
Vikas
I have worked in a similar scenario and this worked well for us:
When you create separate war's it means that they are independently running in it's own web context inside tomcat. Usually when you want to share resources like datasources, transactionManagers, or any other kind of jee resource you need to configure them at the tomcat instance level and they will be available in the JNDI directory of the tomcat server and any web application can pull any of them to use it.
https://tomcat.apache.org/tomcat-8.0-doc/config/context.html
https://tomcat.apache.org/tomcat-8.0-doc/jndi-resources-howto.html
There are several jee resources than you can share in the tomcat server but if you need more flexibility and robustness you might need a full stack java enterprise application server like wildfly http://wildfly.org/news/2014/11/20/WildFly82-Final-Released/ or any other commercial like WebSphere, Oracle Weblogic, etc
Now, if you want to share java classes, zul's or any other file, you may want to package them in separate common jars and use them in any war as a dependency and then reference them through the classpath of the web application.To organize and maintenance this modular projects Maven and Gradle are very good tools you can use.
From ZK you can call any other url of the other war's as simple as
<a href="htt://myserver/account/home.zul" label="Account"/>
<a href="htt://myserver/finnance/home.zul" label="Finance"/>
To share the session what you need is to implement a Single Sign On (there are other implementations like oracle opensso), you can configure it directly in tomcat but be aware of this Sharing security context between few web applications .
Spring Securityhas an extraordinary support for this kind of escenario.
I am developing a Java EE 6 bottom-up JAX-WS to expose an EJB3.1 stateless session bean. The web service in a WAR is failing to install on deployment because it references an external jar (or shared library) which one can assume is not loaded yet.
The common suggestion is to include the jars in the /lib folder, which does fix the issue, however the jars need to remain in this external shared library location and NOT in the ear file, because they amount to 30MB.
What are some techniques to get around this issue in a Websphere (WAS v.8) environment or any server environment.
Some suggestions I have found include:
1. define classpath in META-INF file.
2. define the resources in deployment.xml
3. alter class loading order
4. (from ibm) In the case where the jars are part of a Shared Library configured on WebSphere Application Server, then a User Library must be used to configure the project for development before generating the WebService.
However, I have been unsuccessful to find any help online in these areas. Is there another technique or does anyone know anything about accomplishing this? Thanks in advance.
EDIT: If I specify the libraries in the META-INF using class-path, they are loaded before extensions, shared libraries..etc, but they are still loaded after the WAR which is not good. Again, this isn't a runtime issue because the web services are created at deployment on the fly.
I submitted a ticket to IBM. The libraries referenced by the web service are needed during deployment and must be bundled into the Ear in some fashion. I threw them in the web-inf/lib folder. However, if the referenced libraries then depend on additional libraries, these can be placed in the Shared Libraries. Seems odd to me too, but let's all just admit "shared libraries" are a hack anyways.
If you still have issues, just make sure your class loading is set to parent_last.
At my company, we use Weblogic (depending upon the installation anywhere between versions 6.1 to 11g).
Right now, we embed environment specific variables into our ears, jars, and wars. This even includes the weblogic.xml file where we have something like this:
<working-dir>/opt/bea/wl61/server/domains/deploy/prod3/temp/work</working-dir>
That means we have to rebuild the same jars, ears, and wars for each and every environment. And, if there's a change in the environment, we have to rebuild and redeploy the wars, ears, and jars. You can imagine the issues and problems we have with build and release management (which is my job).
At my last position, we used JBoss, and somehow were able to create generic and deployable ears. I would have Hudson build an ear that the developers could use for their testing. This same ear could then be passed to our QA team in their environment, to UAT, staging, and into production.
We could do this amazing feat because we configured JBoss to look for properties files OUTSIDE or the ear itself. There was a config directory that was a sibling to the deploy directory that contained any needed properties files. Is it possible to setup Weblogic to do the same thing?
We need a way to do this with minimal code changes. I've already examined the source, and we don't specify the directory name when we specify loading the values in the properties files. Therefore, we might be able to do this with some sort of CLASSPATH idea.
I understand that these properties must live somewhere, but I would prefer if it could be configured in the environment, and maybe done by having the path relative to the deploy directory. I want to use the same ear, jar, and war files no matter what system you are on: Windows PC desktop, Linux, Mac, or Solaris server.
The toughest issue will be our weblogic.xml embedded path. Can that path be relative to the deploy directory and not from the root of the system?
As I stated before, I'm the build manager, so as far as everyone is concerned, this is my headache, and not their problem. If deployments don't go well, the Finger 'o Blame can point directly at me.
In order to get this to done I have to be able to find a solution that's simple for us to implement. We can't rewrite everything and change everything around. Otherwise, I can't get the other teams to do this. After all, it's my issue and not theirs. We need something with minimal coding changes (preferably none) and minimal changes in our Weblogic setup. I want something that in Version 3.4 of our software, we do it the old fashion environment specific way, but in Version 3.5, we can deploy in an environmentally neutral way and do that with minimal changes in our deployment environment.
I can feel your pain - I went through the same process at a couple of companies. You have a couple of options that would be a significant improvement from your current setup:
1) Modify the CLASSPATH to use an external directory / properties file that overrides everything that is in the ear file. This is easy to implement but can get out of hand without the proper standards/governance.
2) Use deployment plans to define environment specific variables. However, deployment plans were not introduced until the WebLogic 9.2.
3) Roll all of your environment specific files in to its own jar. All environments would be pointing to the same file but it would be building out different contents based on your build process. Advantages - Single file that contains all the props, easy to move, etc. Disadvantages - Cannot change properties on the fly and force a reload from the JVM.
There may be other options based on the repository. IMHO, all of these work more or less the same - It's the process and enforcing it that prevents issues.
If I have an dependency Jar for my application is it better to place it in the war files lib directory or to place it in the global application server (like Tomcat) lib directory? What do I gain by using one approach over another?
Diskspace springs to mind, but we live in a time when diskspace is cheap. Is there a memory usage difference? Can someone with more experience then me list the pros and cons of both options?
Generally speaking, it's much better to have WAR self-contained so you don't have to rely on the container configuration. It makes deployment much easier also. So try to put library in the WAR if you can.
However, I ran into cases when installing libraries to container makes sense. For example,
We have some internal libraries used by every webapp and they are huge. We install them to container so all the webapps use the same version and it saves on memory and diskspace too.
Libraries installed in WEB-INF/lib is not available to container. If you need to reference these in context.xml (like JDBC driver defined in Resources), you have to put them in server/lib.
If you want send log4j logs from all the webapps to the same file, you have to put log4j jar in the server/lib. Otherwise, each webapp uses its own logger.
If you want to use the container's resource management capabilities -- e.g. connecting to a SQL database and providing a JNDI lookup and connection pool for it -- then the container software itself will need access to the libraries and drivers to manage the resources.
Otherwise you probably don't want to install them in the server /lib directory and assume they are there and will work, as different web applications might have subtly different version requirements.
For a in-depth description of the class loader hierarchy implemented by Catalina, you should check Tomcat's Class Loaders HOW-TO. This will help you to understand when to make jars available to the container, to all webapps, to a single webapp only... and where to put them.
I am in the process of designing a build system and the directory structure for a large software system developed with Java EE 5. The build system will be implemented using ant.
We have multiple different services, which are grouped thematically. Each service offers either a web service or EJBs. Each service runs on a dedicated application server cluster. Thus, we have multiple clusters and some of these clusters can be grouped logically by topics.
I did read generic definitions and examples, but I am still confused about the Java EE terminology:
What is a Java EE application? And thus, what is the content of an EAR file?
What is a Java EE Project? (the term is used by Netbeans as well as in the Java Blueprints Guidelines Project Conventions for Enterprise Applications)
Do I have to put all EJB and WAR-module-package-files into one single EAR, so that this single EAR contains our complete system?
Or do I put each group of services into one EAR, despite the fact that these services are only grouped logically but not technically?
Or do I assemble a separate EAR for each service, i.e. most often only containing a single EJB jar file and sometimes and EJB and a WAR file?
Or do I dismiss the concept of applications and merely build EJB and WAR files, so that I have exactly one deployment file for each application server cluster?
I guess, my main question is: What are the advantages of packaging EAR files?
As I see it at the moment, there is only the need for EAR-EJB and WAR files and additionally the concept of nested subproject in the ant-build-system and the directory structure of our source?
Edit: Thanks a lot for the answers! It seems to me that an application packaged into an ear is a rather atomic subsystem. So I guess, that I will have a nested subproject-structure (only logical, visible only to the build system and in the directory structure of the source) and a rather large amount of EARs, each of those containing mostly only one ejb-jar and/or war module and implementing a single service (which is deployed on a single application server cluster).
I think what you decide to put in each EAR is governed by organizational and technical issues.
I think most important technical role of an EAR is a classloader root in a runtime environment. This normally means you can deploy different versions of libraries and your own classes in different EAR's. This means you should keep your container root classpath fairly empty (or as supplied by the container vendor), because it may allow one phsyical container to service multiple applications using possibly conflicting libraries. This is great news if you're developing a number of different applications using a common code-base. You can have a number of projects deploying to the same farm of servers without messing up for eachother.
You will normally never deploy a smaller unit of software than the EAR. Each EAR can be more or less fully self-contained. I would normally let the content of these refelect what the owning organization thinks of as applications or subsystems. You can usually package the same components in multiple EAR's.
Lots of questions here.
Java EE projects are either EAR or WAR deployments that use Java EE technology. If you have a WAR with JSPs and JDBC access of a relational database, that's a Java EE project. The original intent was that EAR files were "enterprise", and that meant EJBs. An EAR file an contain EJBs, WARs, JARs, the whole enchilada.
Thinking in terms of services are a little different. I think deployment deserves careful consideration, because components that are packaged together must be brought down and up together if any maintenance has to be done.
So think carefully about how you package your services. It's not an all or none blanket answer, IMO. You should look at what your services are doing and how they might be used together to decide how they should be packaged and deployed.
Both Logical and Organizational considerations come into play. Each EAR would contain all the pieces that are related for a particular capability. We can always assume that each EAR will be self contained and can be deployed on one or more containers. The typical approach that I have always followed is to have each EAR contain one or more jars and wars. Each war or jar contains some key component or set of related components. The EAR represents an Enterprise application that contains the components and web apps for the application.
An Example is a Payment processing system I was involved in.
The EAR contained everything required to run the Payment Processing system. This included half a dozen jars and 3 wars. Each jar represented some functionality or logical grouping of functionality. Each war represented a web app.
An example of the jar's composition:
a jar for core functionality
a jar for ejbs
a jar for our advanced financial math pieces
a jar for our security pieces
etc.
Having multiple jars was dictated by the fact that different people developed different pieces so they worked in different Eclipse projects and combined them all as needed.
There are no hard and fast rules, just whatever works for your team and situation.