9.2. ClassLoading
Instead of using the
ClassLoader
abstraction directly, you can create ClassLoading
modules which contain declarations of ClassLoader
dependencies. Once the dependencies are specified the ClassLoaderPolicy
s are constructed and wired together accordingly.
To facilitate defining the
ClassLoaders
before they actually exist, the abstraction includes a ClassLoadingMetaData
model.
The
ClassLoadingMetaData
can be exposed as a Managed Object within the new JBoss EAP profile service. This helps system administrators to deal with more abstract policy details rather than the implementation details.
Example 9.4. ClassLoadingMetaData Exposed as a Managed Object
public class ClassLoadingMetaData extends NameAndVersionSupport { /** The serialVersionUID */ private static final long serialVersionUID = -2782951093046585620L; /** The classloading domain */ private String domain; /** The parent domain */ private String parentDomain; /** Whether to make a subdeployment classloader a top-level classloader */ private boolean topLevelClassLoader = false; /** Whether to enforce j2se classloading compliance */ private boolean j2seClassLoadingCompliance = true; /** Whether we are cacheable */ private boolean cacheable = true; /** Whether we are blacklistable */ private boolean blackListable = true; /** Whether to export all */ private ExportAll exportAll; /** Whether to import all */ private boolean importAll; /** The included packages */ private String includedPackages; /** The excluded packages */ private String excludedPackages; /** The excluded for export */ private String excludedExportPackages; /** The included packages */ private ClassFilter included; /** The excluded packages */ private ClassFilter excluded; /** The excluded for export */ private ClassFilter excludedExport; /** The requirements */ private RequirementsMetaData requirements = new RequirementsMetaData(); /** The capabilities */ private CapabilitiesMetaData capabilities = new CapabilitiesMetaData(); ... setters & getters
Example 9.5, “ClassLoading API Defined in XML” and Example 9.6, “ClassLoading API Defined in Java” show the ClassLoading API defined in XML and Java, respectively.
Example 9.5. ClassLoading API Defined in XML
<classloading xmlns="urn:jboss:classloading:1.0" name="ptd-jsf-1.0.war" domain="ptd-jsf-1.0.war" parent-domain="ptd-ear-1.0.ear" export-all="NON_EMPTY" import-all="true" parent-first="true"/>
Example 9.6. ClassLoading API Defined in Java
ClassLoadingMetaData clmd = new ClassLoadingMetaData(); if (name != null) clmd.setDomain(name + "_Domain"); clmd.setParentDomain(parentDomain); clmd.setImportAll(true); clmd.setExportAll(ExportAll.NON_EMPTY); clmd.setVersion(Version.DEFAULT_VERSION);
You can add ClassLoadingMetaData to your deployment either programmatically, or declaratively, via
jboss-classloading.xml
.
Example 9.7. Adding ClassLoadingMetaData Using jboss-classloading.xml
<classloading xmlns="urn:jboss:classloading:1.0" domain="DefaultDomain" top-level-classloader="true" export-all="NON_EMPTY" import-all="true"> </classloading>
The DefaultDomain is shared among all the applications that do not define their own domains.
Example 9.8. Typical Domain-Level Isolation
<classloading xmlns="urn:jboss:classloading:1.0" domain="IsolatedDomain" export-all="NON_EMPTY" import-all="true"> </classloading>
Example 9.9. Isolation with a Specific Parent
<classloading xmlns="urn:jboss:classloading:1.0" domain="IsolatedWithParentDomain" parent-domain="DefaultDomain" export-all="NON_EMPTY" import-all="true"> </classloading>
Example 9.10. Non-Compliance with j2seClassLoadingCompliance
<classloading xmlns="urn:jboss:classloading:1.0" parent-first="false"> </classloading>
.war
deployments use this method by default. Instead of doing default parent-first lookups, you first check your own resources.
Example 9.11. Typical OSGi Implementation
<classloading xmlns="urn:jboss:classloading:1.0"> <requirements> <package name="org.jboss.dependency.spi"/> </requirements> <capabilities> <package name="org.jboss.cache.api"/> <package name="org.jboss.kernel.spi"/> </capabilities> </classloading>
Example 9.12. Importing and Exporting Whole Modules and Libraries, Rather than Fine-Grained Packages
<classloading xmlns="urn:jboss:classloading:1.0"> <requirements> <module name="jboss-reflect.jar"/> </requirements> <capabilities> <module name="jboss-cache.jar"/> </capabilities> </classloading>
<classloading xmlns="urn:jboss:classloading:1.0"> <requirements> <package name="si.acme.foobar"/> <module name="jboss-reflect.jar"/> </requirements> <capabilities> <package name="org.alesj.cl"/> <module name="jboss-cache.jar"/> </capabilities> </classloading>
You can also mix the requirements and capabilities types, using packages and modules.
The classloading sub-project uses a very small resource-visitor-pattern implementation.
In the
ClassLoader
project, the connection between deployment and classloading is done through the Module
class, which holds all of the required information to properly apply restrictions on the visitor pattern, such as filtering.
Example 9.13. The ResourceVisitor
and ResourceContext
Interfaces
public interface ResourceVisitor { ResourceFilter getFilter(); void visit(ResourceContext resource); } public interface ResourceContext { URL getUrl(); ClassLoader getClassLoader(); String getResourceName(); String getClassName(); boolean isClass(); Class<?> loadClass(); InputStream getInputStream() throws IOException; byte[] getBytes() throws IOException; }
To use the module, instantiate your ResourceVisitor instance and pass it to
Module::visit
method. This feature is used in the deployment framework to index annotations usage in deployments.