Thursday, March 28, 2013

Changes to webapp Classloading in WSO2 AS 5.1.0


WSO2 Application Server 5.1.0 has introduced a major changes to the Webapp classloading mechanism with a new concept called configurable Runtime Environments. This provides solutions to classloading issues that was present is previous releases. Now, the users will be able to manipulate the webapp dependencies in a fine-grained manner. The current webapps will work just fine with this release, and will also provide an extension of support via a  newly introduced webapp-classloading.xml file.

Starting from Carbon 4.0.0, WSO2 Application Server has gained a lot of momentum. There was special focus on it, and have added lot of major features. We have seen the introduction of CXF for providing full specification support for JAX-WS 2.2, and JAX-RS 2.0, inclusion of Jaggery with WSO2 AS, and a lot of cool features. See the AS 5.0.0 release notes to get a glimpse of those.

With the introduction of the Runtime Environments, now users can control the classloading per-server or per-application. Users can define own runtimes for advanced usages but default runtimes are sufficient for most of the cases. You can control the classloader hierarchy using these Runtimes.
There are 3 default runtimes on AS - Tomcat env, Carbon env, and CXF env.

  1. Tomcat Environment – This is the minimal runtime and is identical to pure Tomcat runtime. Only Tomcat, Servlet, JSP, EL, JSTL are available on server level Classpath. If a user wants additional Jars they need to be packaged with web application or should be placed on Tomcat Environment extension directory. 
  2. Carbon Environment - Tomcat Environment + Carbon Environment. This does not provide CXF or Spring dependencies. If a user wants additional Jars they need to be packaged with web application or should be placed on Carbon Environment extension directory.
  3. CXF Environment - Tomcat Environment + CXF + Spring - CARBON. This does not provide top access Carbon runtime. If a user wants additional Jars they need to be packaged with web application or should be placed on CXF Environment lib directory.


How to Configure

There is a new configuration file called webapp-classloading.xml which was introduced to configure webapp Classloading behavior per-server/per-application basis. This file need to be placed inside META-INF directory of a web application.

ie. {webapp}/META-INF/webapp-classloading.xml

This is quite a simple file containing only one parameter. It would look like the following. 

webapp-classloading.xml


<Classloading xmlns="http://wso2.org/projects/as/classloading">
   <Environments>{Runtime-Environment-Names}</Environments>
</Classloading>

Possible values that you can set for {Runtime-Environment-Names} include,
  • Tomcat
  • Carbon
  • CXF
  • CXF,Carbon
  • {Custom-Exclusive-Env}
  • {Custom-Exclusive-Env},Carbon
e.g – To specify CXF as the runtime environment users should have the following configuration.

<?xml version="1.0" encoding="UTF-8"?>
<Classloading xmlns="http://wso2.org/projects/as/classloading">
   <Environments>CXF</Environments>
</Classloading>

Note:
  • It is possible to specify a combination of environments.
    • E.g – To access some Carbon features on a CXF applications it is possible to specify environment as 'CXF,Carbon'. Order is not important which means 'CXF,Carbon' and 'Carbon,CXF' have the same effect.

Runtime Environment extensions

It is a common requirement to share dependencies among number of applications without packaging with each and every application. In such cases following extensions directories can be used to place common dependencies.
  1. Tomcat Environment - ${carbon.home}/lib/runtimes/ext/
  2. Carbon Environment - ${carbon.home}/repository/components/lib
  3. CXF or any Custom Environment – Environment's lib directory. I will explain how to add a custom environment in the next section.
    1. e.g - ${carbon.home}/lib/runtimes/cxf 
    2. e.g - ${carbon.home}/lib/runtimes/ABC
Note :-
Dependencies placed on Tomcat Environment extension directory are visible to all the environments and it is required to identify the impact before placing dependencies on above environments. As an example placing incompatible Spring Dependencies on ${carbon.home}/lib/runtimes/ext/ can cause issues on CXF runtime environment (CXF environment also contains Spring dependencies). In such cases those incompatible dependencies should be packaged inside the web application and should deploy with Tomcat Environment configuration, then other application won't be effected.

Adding custom Runtime Environments


By adding new <ExclusiveEnvironments> entry to the {carbon.home}/repository/conf/tomcat/webapp-classloading-environments.xml file users can define custom runtimes. But this is recommended for advanced usages only. You will not need this in most common use-cases.
e.g – Define a custom Runtime Environment for Spring
  • Add following entry to {carbon.home}/repository/conf/tomcat/webapp-classloading-environments.xml file.

<ExclusiveEnvironments>
    <ExclusiveEnvironment>
        <Name>Spring</Name>
        <Classpath>${carbon.home}/lib/runtimes/spring/*.jar;${carbon.home}/lib/runtimes/spring/</Classpath>
    </ExclusiveEnvironment>
</ExclusiveEnvironments> 
  • Create and copy related Spring dependencies to the {carbon.home}/lib/runtimes/spring/ directory. As you see, the directory name is derived from the Classpath attribute we just set above.

Miscellaneous

  • AS 5.1.0 ships core CXF 2.7.3 dependencies and core Spring 3.0.7 dependencies under CXF runtime environment. If users want to upgrade to different CXF versions they are two options available.
    • Upgrade CXF runtime environment – Users can remove existing CXF/Spring and dependent Jars from “{carbon.home}/lib/runtimes/cxf” directory and can place new CXF/Spring Jars. 
    • Instead of upgrading server level CXF dependencies, users can package all the required Jars with in the Web-INF/lib directory of the application and deploy it with "Tomcat" runtime environment.
  • If the user want to add optional CXF/Spring jars, they can copy them into "{carbon.home}/lib/runtimes/cxf" directory but need to ensure those new dependencies are compatible with existing CXF/Spring Jars.

2 comments:

  1. Which schemaLocation is to be used within webapp-classloading.xml?

    ReplyDelete
    Replies
    1. There is no schema available for the webapp-classloading.xml yet. Currently, it's just a small xml file with two child elements.

      But if you do need a schema, you can process the default webapp-classloading.xml via a xsd generator.

      Delete