Copyright © 2008-2009 OW2 Consortium
This work is licensed under the Creative Commons Attribution-ShareAlike License. To view a copy of this license,visit http://creativecommons.org/licenses/by-sa/2.0/deed.en or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
The target audience for this guide is the application component provider, i.e., the person in charge of developing the software components on the server side (the business tier).
JOnAS supports two types of Java EE application components: Enterprise Beans and Web components. In addition to providing guides for construction of application components, guides are supplied for application assembly, deployment, and administration.
The individual in charge of developing Enterprise Beans should consult the for instructions on how to perform the following tasks:
Write the source code for the beans.
Specify the deployment descriptor.
Bundle the compiled classes and the deployment descriptor into an EJB JAR file.
JOnAS 5 supports both versions 2 and 3 of the Enterprise Java Beans (EJB) specifications. Programming and configuration methods between these two versions have changed drastically, we therefore provide you with two different programmer's guides:
Web designers in charge of JSP pages and software developers providing servlets can consult the Web Application Programmer's Guide.
The Developing Web Components guide explains how to construct Web components, as well as how to access Enterprise Beans from within the Web Components.
Deployment descriptor specification is presented in the Defining the Web Deployment Descriptor chapter.
Web components can be used as Web application components or as Java EE application components. In both cases, a WAR file will be created, but the content of this file is different in the two situations. In the first case, the WAR contains the Web components and the Enterprise Beans. In the second case, the WAR does not contain the Enterprise Beans. The EJB JAR file containing the Enterprise Beans is packed together with the WAR file containing the Web components, into an EAR file. Principles and tools for providing WAR files are presented in WAR Packaging and the Deployment and Installation Guide.
JOnAS provides tools for the deployment and administration of Enterprise Beans (EJB JARs), Web applications (WARs), and Java EE applications (EARs).
The Deployment and Installation Guide covers issues related to the deployment of application components.
The Administration Guide presents information about how to manage the JOnAS server and the JOnAS services that allow deployment of the different types of application components: EJB Container service, Web Container service, and EAR service.
The application assembler in charge of assembling the application components already bundled in EJB JAR files and WAR files into a Java EE EAR file, can obtain useful information from the Java EE Application Assembler's Guide .
This section introduces the classloading architecture of JOnAS.
Obviously, a ClassLoader
is used to load
classes (and resources) that will then be usable from the application.
Most of the ClassLoaders are URLClassLoaders
, that
means that they are based on a set of URLs. Theses URLs will be the place
where the ClassLoader, when asked for a resource (using its fully
qualified name, ie including full package name), will try to find the
resource.
An URLClassLoader
always have a parent
ClassLoader. When loading a class, the first thing a ClassLoader do is to
ask its parent to load the class (this is recursive). If the parent return
the Class, it's returned to the caller. Otherwise, the URLs will be search
for the given class. this is the default Java delegation model (parent
first).
Let's roll with an example: you have a ClassLoader (let's call it A)
that can load the class Test
, A is the parent of B,
but B do not contains the Test
class, and B is the
parent of C, with C that contains also the Test
class. Clearly, there is a ClassLoader hierarchy here (C->B->A, with
"->" meaning "is child of"). If you ask C to load
Test
, the following steps will be performed:
C have B as parent, so asks B to try to load
Test
B have A as parent, so asks A to try to load
Test
A is the top level ClassLoader, no parent, it will try to load test by itself
As A contains the Test
class, it can be
loaded and returned
B see that A (its parent) have loaded the class, so it return it as is
C see that B (its parent) have loaded the class, so it return it as is
Note | |
---|---|
Using the Java delegation model, the loaded class is always
coming from the parent ClassLoader that is closer to the System class
loader (the well known |
Java EE makes an heavy use of ClassLoaders: the application server in itself may be composed of multiple ClassLoaders and the Java EE applications (EAR, Rar, War, EjbJar) themselves are using ClassLoaders.
An application is deployed by its own class loader. This means, for example, that if a Web Application and an EjbJar are deployed separately, the classes contained in the two archives are loaded with two separate classloaders with no hierarchy between them. Thus, the EJBs from within the JAR will not be visible to the Web components in the WAR. This is not acceptable in cases where the Web components of an application need to reference and use some of the EJBs (this concerns local references in the same JVM).
Note | |
---|---|
Class loaders are used to ensure class space isolation. |
For this reason, prior to EAR files, when a Web application had to
be deployed using EJBs, the EjbJar had to be located in the WEB-INF/lib
directory of the Web
application.
Currently, with the Java EE integration and the use of the EAR
packaging, that kind of class visibility problems no longer exist and the
EjbJar is no longer required in the WEB-INF/lib
directory.
The following sections describe the JOnAS class loaders and explain the mechanism used to locate the referenced classes.
JOnAS is basically an assembly of modules providing the features that makes JOnAS an application server. Each of the modules have an associated class loader. All theses loaders have visibility constraints, meaning that some of the internal classes or libraries used by JOnAS are hidden from the application class space. In clear, even if JOnAS may use a library also used by a deployed application, there will be no conflicts.
Note | |
---|---|
Having visibility constraints on class loaders reduce the risks of conflicting libraries. |
The loaders of JOnAS are not in a tree hierarchy. They all share the same parent class loader (the System classloader), so it's a flat hierarchy. Nevertheless, there are links (aka wires) between theses class loaders. A module can export some of its packages (and thus, all the classes from that package) to the system. Theses exported packages can then be imported by other modules. That creates a wire. As a module can be wired to multiple others modules, the class loaders of the application server forms an oriented graph of loaders.
Note | |
---|---|
The class loading rules are described in much more details in the OSGi™ specification. |
Note | |
---|---|
Only exported packages are available to the applications |
As JOnAS is build on a modular system (OSGi™), it's very natural to "extends" the application server's class space.
There are 2 way that can be used to augment the class space:
Place an OSGi™ bundle containing your
classes in the ${jonas.base}/deploy/
directory
It will be deployed as any normal bundle, and if it's resolved (ie all imported packages are found), all the packages exported by this bundle will be made available to the server (and applications).
Note | |
---|---|
This is the preferred way to augment the class space. |
Place a classic jar file in the ${jonas.base}/lib/ext/
(or ${jonas.root}/lib/ext/
). During JOnAS
startup, theses jar files will automatically be transformed into
bundle (using default creation rules) and installed like all other
bundles.
Note | |
---|---|
The default rule is: every required packages that is not in the jar file will be imported, and every packages of the jar will be exported. |
Warning | |
---|---|
This option, even if it is seducing, should be used with caution: it can break application server modularity (if they export a package required by some of the JOnAS modules, maybe that can cause weird classes exceptions), and, because of the default transformation rule (all is exported), it's highly possible that a jar file will export some internal packages that should not have been exposed to the world. So the right method to augment the class space is to provide a well constructed bundle (with imports and exports constrained with versions). |
In order to connect the applications to an external database (not HSQL which is embedded in JOnAS), the user must provide the jar file that contains the JDBC Driver's classes.
Providing theses jar files are just like extending JOnAS class loaders:
The driver's jar file is already an
OSGi™ bundle, so it can be placed in
${jonas.base}/deploy
and it
will be deployed automatically
The jar file is not a bundle, it could be placed in
${jonas.base}/lib/ext
and
will be (at startup only) transformed into a
bundle (see previous section for detailed information), or the
user takes the responsability of transformation (more fine control
on the bundle).
Java EE modules are following the classic, hierarchical, parent oriented graph of class loaders.
The class loader hierarchy for Java EE modules that allows the
deployment of EAR applications without placing the EJB JAR in the
WEB-INF/lib
directory consists of
the following:
Caution | |
---|---|
Work in progress |
This class loader, child of the OSGi™ class loader, contains only the libraries provided by the system level resource adapters (i.e. resource adapters not part of an EAR application).
This class loader is the parent of all the deployed Java EE modules:
Standalone Web Applications (.war
files)
Standalone EjbJars (.jar
files)
Java EE Applications (.ear
files)
This means that all the classes available from this loader are also made available for the child loaders.
A standalone EjbJar classloader contains the classes packaged inside of the ejbjar. The parent of this classloader is the Section 2.1.3.1, “Standalone resource adapters loader”. It can therefore see all the classes available from the system level resource adapters and its ancestors.
The classloading policy of this loader is to ask its parent first, and then (if the class was not found) try to search in itself. There is no way to invert the classloading policy of an EjbJar classloader.
The classloader for standalone web applications modules contains the classes and libraries packaged inside of the war.
It contains the WEB-INF/classes/
directory (that usually
matches the classes of the application) and all the jar files located
under the WEB-INF/lib/
directory.
Notice that only jars directly under the lib/
directory are available, jars in
WEB-INF/lib/subdirectory/
will
not be accessible from the classloader.
The parent of the standalone webapp classloader is the Section 2.1.3.1, “Standalone resource adapters loader”, meaning that all standalone web applications will be able to use system level resource adapters classes/libraries and the classes available from its ancestors.
A webapp loader also have a direct link with the system
classloader (classes of the JVM + what's available from the
CLASSPATH
environment variable). All class
loading actions are first directed to the system classloader
to avoid JVM class overloading from the web application (in short,
guards the developer from overloading primordial classes).
Then, if the system classlaoder did not find the required class, the loader will ask either the parent, or itself. Asking the parent or itself is configured by the delegation model choosed by the developer.
Note | |
---|---|
By default, java2 delegation model is turned on. |
The default classloading policy of a web application in an application server (in opposition of a webapp hosted in a standalone servlet container) is to ask the parent loader first, and then look inside itself (if the parent did not find the required class), this is the default java2 delegation model.
Nevertheless, a web application developer can configure the web classloader to use first itself, then ask the parent loader. That means that the web application classes will have more priority than classes from the parent loader, in other words it can be used to overload some classes provided by the application server.
The delegation model can be configured using the
WEB-INF/jonas-web.xml
specific deployment
descriptor, as shown below.
<?xml version="1.0" encoding="ISO-8859-1"?> <jonas-web-app xmlns="http://www.objectweb.org/jonas/ns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.objectweb.org/jonas/ns http://jonas.ow2.org/ns/jonas-web-app_4_0.xsd"> <!-- true : the context uses a classloader using the Java 2 delegation model (default) false : the class loader looks inside the web application first, before asking parent class loader --> <java2-delegation-model>false</java2-delegation-model> </jonas-web-app>
The EAR class loader is the common parent (directly or indirectly) of all the class loaders of the inner modules (ejbjars, rar, webapps). There is only one EAR class loader per EAR application. This class loader is the child class loader, thus making JOnAS classes visible to it. The parent of all the EAR class loaders is a JOnAS special class loader that is able to seek for classes/resources exported by all the other module's class loaders of JOnAS.
The EJB class loader is responsible for loading all the EJB JARs of the EAR application, thus all the EJBs of the same EAR application are loaded with the same EJB classloader. This class loader is the child of the EAR class loader.
The WEB class loader is responsible for loading the Web components. There is one WEB class loader per WAR file, and this class loader is the child of the EJB class loader. Using this class loader hierarchy (the EJB class loader is the parent of the WEB class loader) eliminates the problem of visibility between classes when a WEB component tries to reference EJBs; the classes loaded with the EJB class loader are definitely visible to the classes loaded by its child class loader (WEB class loader).
The compliance of the class loader of the web application to the
java 2 delegation model can be changed by using the
WEB-INF/jonas-web.xml
file. This is described in
the section Defining the
Web Deployment Descriptor.
If the java2-delegation-model element is set to false, the class loader of the web application looks for the class in its own repository before asking its parent class loader. See Section 2.1.3.3.1, “Java 2 delegation model” for more detailed explanations.
By default, all classes exported by the application server can be accessed within an application. Sometimes this may cause problems if there are different versions of the library (in the AS and in the application)
For example, JOnAS is using Apache Commons Digester. If an application wants to use an older version of this library, there is a problem as the default loading mechanism of classes is searching first in the parent classloaders. Then the library provided by JOnAS and not by the application will be used.
For web applications, this mechanism could be changed by using java2-delegation-model but this may raise problems for EAR case, etc.
There is an option for helping to solve these cases. This is by using a filtered classloader. A filtered classloader will hide to applications some packages/resources exported by the Application Server. Some default filters are existing by default in JOnAS. These default filters are located in the JONAS_BASE/conf/classloader-default-filtering.xml file.
<class-loader-filtering xmlns="http://org.ow2.jonas.lib.loader.mapping"> <!-- List of filters used to exclude packages/resources that are used internally by the Application Server but that will not be available to applications. An empty list will not hide any packages to the applications This list is used both to hide resources and classes to applications. --> <default-filters> <filter-name>org.apache.commons.digester.*</filter-name> </default-filters> </class-loader-filtering>
By modifying the set of filters, some packages will be hidden to the applications. Note that resources name can be specified. For example, when putting a resource in JONAS_BASE/conf folder, this resource can be obtained by using ClassLoader.getResource() method. By adding a filter on this resource, the resource won't be available to applications (This includes EAR, WAR and EJB-JAR modules)