Class Loading for Web Services
In most scenarios, Web Services which are deployed in production environments depend on external, third-party libraries for different functionalities. The Web Services deployed in WSO2 Application Server can load classes from different locations. Therefore, it is important to understand how you can place your external dependencies within WSO2 Application Server in the manner most suitable to your requirements.
There are different kinds of services that you can deploy in WSO2 Application Server through the management console. See Service Development and Deployment for more information. These deployed service archives are written to the relevant folder in the following location of the file system: <AS_HOME>/repository/deployment/server
.
In this folder, there are separate sub folders for different types of services. Those are called deployment folders for different service types. For example,
- Axis2 Services -
<AS_HOME>/repository/deployment/server/axis2services
. - JAX-WS Services -
<AS_HOME>/repository/deployment/server/servicejars
.
See the following topics for information on how classes are loaded to your web services and about the possible class loading configurations:
Classes for Web Services
The web services deployed in your Application Server can load classes from four different locations as explained below:
CARBON_HOME/repository/components/lib
When a .jar file is copied to this location, it will be converted to an OSGi bundle and injected to the Carbon OSGi runtime. Any other OSGi bundle can import packages provided by the copied .jar file. We recommend users to copy external libraries to this location when it is necessary to make the dependency available within the OSGi environment. For example, consider a situation where you have installed mediation features in the WSO2 Application Server and want to share the same library between a mediator and an AAR service.
If your external dependency is already an OSGi bundle, you can directly copy that bundle to <AS_HOME>/repository/components/dropins
folder and the behavior will be the same as above.
CARBON_HOME/repository/deployment/server/lib
As mentioned above, all sub folders relevant to different service types exist in the "server" folder. So the 'lib' folder is the place to copy libraries which should be shared across different services of different service types. For example, in a situation where you have an Axis2 service and a JAX-WS service sharing the same dependency, you can copy to this location.
CARBON_HOME/repository/deployment/server/<deployment_folder>/lib
The <deployment_folder>
here is the relevant folder for the service type (For example, <axis2services>
). This 'lib' folder is the place to copy libraries which should be shared across different services of the same service type. For example, if you have two different Axis2 services that share the same dependency, you can copy it to the axis2services/lib
folder.
The 'lib' folder inside the service archive file
You can include your external libraries to the service archive file itself. Create a 'lib' folder on the top level of your archive file and include the dependency inside that folder. This is recommended when the external library is used only by the particular service. For example, if your .aar service depends on a .jar, embed the .jar file inside the .aar file as shown below.
StudentMarks.aar META-INF services.xml lib foo.jar org wso2 sample marks.class
Child-first class loading
The WSO2 Application Server follows child-first class loading by default. You can see that by opening the <AS_HOME>/repository/conf/axis2.xml
file and checking the following parameter.
<parameter name="EnableChildFirstClassLoading">true</parameter>
This means that the priority of class-loading options mentioned above reduces in the following order: 4 > 3 > 2 > 1. When loading classes, highest priority is given to location 4 above and the least to location 1. For example, if you have two different versions of the same library in 1 and 3 above and your .aar service depends on that library, classes will be loaded from the library in location 3.
Parent-first class loading
If you want to enable parent-first class loading, you can do that by opening the <AS_HOME>/repository/conf/axis2.xml
file and setting the value of the following parameter to 'false'.
<parameter name="EnableChildFirstClassLoading">false</parameter>
This means that the priority of class-loading options mentioned above reduces in the following order: 1 > 2 > 3 > 4. When loading classes, the highest priority is given to location 1 above and the least to location 4. For example, if you have two different versions of the same library in 1 and 3 above and your .aar service depends on that library, classes will be loaded from the library in location 1.
Change class loading for a particular service
If you want a particular Axis2 service to have a different setting for the "EnableChildFirstClassLoading"
parameter, you can add the above parameter to the META-INF/services.xml
file of the .aar file.
<parameter name="EnableChildFirstClassLoading">false</parameter>
For example, consider that child-first class loading is enabled at server level (default setting), and therefore the priority of class-loading options reduces in the following order: 4 > 3 > 2 > 1. In this scenario, if you have two different versions of the same library in locations 1 and 4, and your service depends on the library in location 4, the classes will be loaded for the service from the library in location 4 as specified in the META-INF/services.xml
file.
You can only control the behavior of location 4 using this method. Therefore, use this method only when you've embedded your libraries inside the service archive.