I have a few separate application projects (EARs) with multiple EJBs that I want to deploy to the same JBoss server. Now, some of the projects may have the same EJBs, but different versions. In similar circumstances, some projects may use different versions of the same "ordinary" classes (i.e. classes loaded within VM, without JNDI lookup).
With OC4J, this seems not to have been a problem, but now with JBoss, I get the impression that everything resides in the same "name space" (or class loader perhaps). Am I correct in this assumption?
Basically, what I want to do (or ensure) are two things:
From a client that does a JNDI-lookup of an EJB, I want to be able to indicate which application it resides in, so that the correct version of the EJB is returned.
From within an EJB, when instantiating a class, I want to ensure that the class is the one deployed with the same application (EAR) as the EJB was.
I think I read that you could configure some "isolation" properties for EJBs, am I guessing correctly in that might would solve my second point?
JBoss's default behaviour is to use a flat classloader. This reduces the footprint, but as you've found, it makes deploying multiple applications troublesome.
Thankfully, the fix is easy. In the ear-deployer.xml file in the deploy directory, make sure the following parameter is set:
<attribute name="Isolated">true</attribute>
This will give each deployed EAR its own classloader space. It will still be able to access stuff from the JBoss lib directory, but the deployed EARs will be invisible to each other.
You're correct that classes from different EAR's reside in the same "space". JBoss uses by default a flat classloader hierarchy, meaning that all classes (except for WAR packaged ones) are loaded by the same classloader. With the introduction of JBoss 5 there's a new standard profile that strictly follows the Java EE rules and thus supports isolated classloading. Older JBoss versions also support this behavior through the callByValue and isolate properties in the deployer configuraion.
Related
I have a problem when deploying two ear files in Jboss 7 and would be thankful for your help.
Following scenario:
EAR 1 contains EJBs which are looked up by EAR 2 (also) at server startup. Thus, EAR 1 has to be deployed before EAR 2 (via jboss-deployment-structure.xml dependency settings).
Right after being deployed, EAR 1 also needs access to classes contained in EAR 2 because of Hibernate and JNDI related class loading (among others).
But as EAR 2 isn't deployed at that time, there's a need for EAR 1 to contain a client-jar file of EAR 2.
Now, the problem is that in the course of EAR 1 and EAR 2 configuration (at server startup) ClassCastExceptions occur because...
(non-EJB) Java object obj1, whose class C was loaded by the classloader of EAR 1, is bound in JNDI
and after being looked up, supposed to be cast to object obj2 whose class C was loaded by the classloader of EAR 2
Now I wonder, if there's a possibility that these common classes of EAR 1 and EAR 2 are being loaded with the same classloader in JBoss 7. I already tried to put them in a server module, which didn't work out.
Thanks a lot for your help in advance!
PS: I'm aware of the poor design declared above. But due to restrictions, I have to follow up on it.
To avoid class cast exceptions, the common libraries need to be put in a classloader that is common to all applications in the two EARs, and no other copies of those libraries should exist in each application.
If it's an option to use only one EAR instead of two, put all the WARs inside a single EAR, remove the common classes from the WARs and put them on the EAR library folder.
This will associate the common classes to the EAR classloader, which is common to all the applications running inside a EAR, so that would solve the problem.
If you must use two EARS, then the common classes need to be put in a classloader at the level of the server shared by all applications.
JBoss 7 is an OSGI based container that allows to create an isolated module with a few jars and link it to an application. So if you try this:
create a module with the common library AND it's dependencies, see instructions here
link the module to all applications
remove the copies of those libraries from all applications and leave them only at the module
It will work fine, but don't forget to put the dependencies of the common library in the module as well otherwise it will not work, the dependencies need to be visible at the level of the module, and there can be no duplicate jars between module and applications (otherwise class cast exceptions might happen).
Another way far less recommendable but it would also work, is to put the common classes at the level of the common classloader, see this diagram. The common classloader folder is located at $CATALINA_HOME/lib (Jboss is based internally on Tomcat).
Specially if there are other applications running in that server don't try the second option. It could help to have a look at a tool I built for these type of issues, JHades.
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/
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.
We have ".sar"(Service Archive file) used in jboss. Currently we are planning to migrate the code to Weblogic.
Is there a way to deploy .sar files into weblogic.
If not directly possible, is there a work around where we can deploy the services on web logic.
In order to get the custom mbeans that are in the .sar you will need to repackage the contents as an .ear as a .sar is not standard Java EE deployment mechanism - that is a JBoss proprietary archive.
Here are some instructions on how to create, package and deploy your own service MBeans (JMX Beans) along with an example of how to use it.
https://blogs.oracle.com/WebLogicServer/entry/developing_custom_mbeans_to_ma
One thing you could do is to "substitute" or "emulate" the SAR Deployer, by creating, configuring and registering MBeans. That, AFAIK, could be done in two ways:
1) Using Standard Java EE components: that means on web tier you can use the init() method of a servlet (make sure that it is preloaded on startup) or, better, a ServletContextListener
2) Using WebLogic specific components. I'm talking about Startup classes. Simply register a startup class that creates, configures and registers your MBeans.
If you are using a web module, the first approach has the obvious advantage that you are using pure Java EE components. Although you are not using that, you can add a "dummy" web module only for doing that
Concerning what you have to do in those classes, you can choose a "from scratch" approach, by parsing the xml files that describe services and therefore manually create, configure and register MBeans or, if I remember well, the XMBeans from JBoss is something that can be reused outside JBoss but you need to check because I'm not sure
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.