Friday Jul 28, 2006

ClassLoaders in GlassFish - a FAQ

Visual Complexity

We have had occasional queries in the forums and mailing lists about the GlassFish classloader hierarchy and/or how to limit visibility of custom library classes to certain components in GlassFish/Sun Java System Application Server. So here is an FAQ we came up with .. Let me know if this is useful and esp if you have a question that is not answered here.

Image on the left via MaisonBisson

Beware of bugs in the above code; I have only proved it correct, not tried it - Donald Knuth

Note: Sun Java System Application Server and GlassFish is referred to
as "application server" through-out this post. Except for some sections
where it is explicitly indicated as valid only for Standard Edition/Enterprise Edition,
the rest of the FAQ is valid for GlassFish v1/Sun Java System Application Server
Platform Edition 9.0

Where do I learn about ClassLoaders in general?
There are a lot of documents available off the web that could help you
understand about ClassLoaders.
ClassLoader JavaDoc
Understanding Network Class Loaders
Loading, Linking and Initialization of the The Java Virtual Machine Specification
Blogs by Sundar on ClassLoading: Part 1, Part 2
The definitive paper: Dynamic Class Loading in the Java Virtual Machine (1998) - well explained and yet readable!

Where could I learn more about working with ClassLoaders of GlassFish/Sun Java
System Application Server?
The ClassLoaders chapter in the application server developer's guide is a
good place to begin.

How do I use a different xml parser with my application?

The application server by default uses the XML parser that comes with
the JDK (Tiger). You could also use a different JAXP compatible
implementation for an application. An application can be configured to
use a different JAXP implementation than the one bundled with the JDK,
by using the --libraries attribute while deploying the application.
This works due to JAXP's use of the Jar Service Provider discovery
specified in the Jar File Specification to determine the
concrete class to instantiate. More on how this works in a future blog entry :)

How do I control visibility scope of my libraries? [ie how do I control my libraries/
library classes to be available

o only to an application
o only to a cluster/config
o for the whole domain
The --libraries deploy time attribute for an application [as explained
in the "Application specific Class Loading" section of the classloader
] can be used to specify runtime dependencies of an
application. There are two ways to refer to a library in the
--libraries list. When a relative path is specified [ie only the jar
name], the application server attempts to find the specified library
in domain-dir/lib/applibs.

For a library to be made available to the whole domain, you could
place the jar in domain-dir/lib or domain-dir/lib/classes, as
explained in the "Using the Common ClassLoader" section of the
classloader chapter. This is usally the case for JDBC drivers and
other utility libraries that are shared by all applicatins in the

For cluster wide use, copy the jars into the domains/domain1/config/xyz-config/lib directory.
Then add the jars in classpath-suffix or classpath-prefix element of xyz-config.
This will synchronize the jars for all server instances using xyz-config.

To summarize,
\* domains/domain1/lib - domain wide scope, common classloader add the jars automatically
\* domains/domain1/config/cluster1-config/lib - config wide, update classpath-prefix or classpath-suffix
\* domains/domain1/lib/applibs - application scope, added to application class loader automatically
\* domains/domain1/config/cluster1-config/lib/ext - adds to java.ext.dirs automatically

What is the preferred way to use a library jar with an
application (bundle with application vs. instance/lib/applibs,
instance/lib, install/lib, classpath-prefix, classpath-suffix,
instance/lib/ext, instance/lib/classes)?
Application Scoping
Use --libraries [domain-dir/lib/applibs] for the following usecases
+ The dependency needs to be resolved at deploy time
+ The dependency is specific to one or more applications alone in the
+ Sharing a dependency for reducing memory footprint/sharing static
state etc.

Please remember that this is non-portable and it's usage is
GlassFish/Sun application server specific

Bundling with the application is useful when the dependent library
needs to be scoped to the application and no sharing is required.

Global Sharing
Place libraries in domain-dir/lib and domain-dir/lib/classes to add
libraries to the common classloader. This is commonly used for
libraries like JDBC drivers that used by multiple applications.
Requires an AS restart.

Code Patches and bundled library overrides
Use classpath-prefix when you want your libraries to be placed ahead of
application server implementation classes in the shared chain. Again
this is ideally used for placing application server
development/diagnostic patches.

Use classpath-suffix when you want libraries to be placed after of
application server implementation classes in the shared chain.

Optional Packages
domain-dir/lib/ext is a java.ext.dirs directory and is the location
for installing optional packages.

How do I use different JDBC drivers? Where should I copy the jar(s)?
It is recommended to place JDBC drivers, that are used by all the
applications in the domain, in domain-dir/lib or
domain-dir/lib/classes. A restart of the application server instance
is required today so that the JDBC drivers are visible to applications
deployed in the domain.

How do I call an EJB in a stand alone module from another stand
alone web app?
Please refer to the section titled "Packaging the Client JAR for One
Application in Another Application
" in the classloaders glassfish

When do I need to restart the application server to use a library jar?
Adding new jars to the following directories require an application
server restart
- domain-dir/lib and domain-dir/lib/classes
- classpath-prefix, classpath-suffix elements in domain.xml
- domain-dir/lib/ext

I see an access control error message when I am trying to use my
library? Help! OR When do I need to grant permission to the library in the
server.policy file?
This usually indicates that the default permissions granted to
applications are not sufficient, and additional permissions are
required for an application. For additional information on
server.policy and granting permission to applications, please refer to
the "Changing Permissions for an Application" section under "Securing
in the AS developer guide.

How do I have my application use libraries bundled with it against an equivalent library bundled in the application server [or] How do I have delegation inversion for specific libraries
This can be done for web applications alone. You can make the Web Classloader follow the delegation inversion model in the Servlet specification by setting delegate="false" in the class-loader element of the sun-web.xml file. It's safe to do this only for a web module that does not interact with any other modules. The default value for the delegate flag is true. Look at "ClassLoader Delegation" in the "Developing Web Applications" chapter for more information.

Update: There are some bugs in the ClassLoader chapter documentation available in the GlassFish site. So until the GlassFish docs are updated, please refer the ClassLoader chapter in the Sun Java System Application Server 9.1 documentation where the bugs have been fixed and is up-to-date. Thanks Rama for pointing this.

Technorati: , ,


Sivakumar Thyagarajan-Oracle


« February 2017