从JBoss AS7开始,Classloader这块开始使用全新的JBoss Modules。本文简单介绍说明JBoss Modules的设计思路,以及给出一个例子说明这一设计思路。
我们都知道,Java一直使用classpath的方式来加载各种class和jar的资源。这样的方式会造成许多问题,比如下面这些经常会遇到的问题:
JBoss Modules 是一个适用于Java的模块化(非分层)类加载以及执行环境的实现。换句话说,不同于Java传统的使用单个类加载器载入classpath中的所有JAR文件,每一个库(library,可以理解为完成某一个功能的一系列jar的组合)成为一个module,该module仅链接其依赖的其他module,而不再依赖其它任何资源。JBoss Module实现了一个线程安全的,快速的,高并发的类加载器委派(delegating)模型,再加上一个可扩展的模块解析引擎,形成一个独特的,简单的,强大的应用程序执行和分布系统。
JBoss Modules被设计为能够和现有的library或者application一起工作而不需要任何的修改,这是因为它简单命名和解析策略。不像OSGi,JBoss Modules并没有实现一个容器;而是一个瘦的启动包装器,在一个模块化环境执行一个应用。这时,你的应用接管控制权,模块化则准备好在需要时装载和连接各模块。此外,只有当一个模块被依赖的时候,它才会被装载(并不会为了解析目的而装载),这意味着,模块化应用程序的性能仅依赖于实际使用的模块数(并在模块被使用的时候),而不是系统中的模块总数目。并且,模块可以在任何时候由用户卸载。
一个模块化程序使用以下命令启动:
java -jar jboss-modules.jar -mp path/to/modules my.main.module.name
一个模块使用简单的XML描述符进行定义,如:
<module xmlns="urn:jboss:module:1.0" name="org.jboss.msc">
<main-class name="org.jboss.msc.Version"/>
<resources>
<resource-root path="jboss-msc-1.0.0.Beta3.jar"/>
</resources>
<dependencies>
<module name="org.jboss.logging"/>
<!-- Optional deps -->
<module name="javax.inject.api" optional="true"/>
<module name="org.jboss.threads" optional="true"/>
<module name="org.jboss.vfs" optional="true"/>
</dependencies>
</module>
JBoss Modules 与 OSGI 相比:
本示例代码位于 https://github.com/kylinsoong/wildfly-architecture/tree/master/modules/quickstart。
根据前面软件安装及资料下载中gituhb安装部分获取示例代码通过如下命令编译运行:
cd wildfly-architecture/modules/quickstart/
mvn clean dependency:copy-dependencies install
ant
会生成build目录,进入到build/QuickStart/bin,执行示例启动脚本:
[kylin@localhost bin]$ ./quickstart.sh
会有如下输出:
Welcome to Modular Class Loading QuickStart 1.0.0
quickstart.sh中指定了启动模块为org.jboss.modules.quickstart:
if [ "x$LAUNCH_DEMO_IN_BACKGROUND" = "x" ]; then
# Execute the JVM in the foreground
eval \"$JAVA\" $JAVA_OPTS \
-Ddemo.home.dir=\"$DEMO_HOME\" \
-jar \"$DEMO_HOME/jboss-modules-1.3.0.Beta3.jar\" \
-mp \"$DEMO_HOME/modules\" \
org.jboss.modules.quickstart \
"$@"
DEMO_STATUS=$?
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="org.jboss.modules.quickstart">
<main-class name="org.jboss.modules.quickstart.Main"/>
<resources>
<resource-root path="modules-quickstart.jar"/>
</resources>
<dependencies>
</dependencies>
</module>
java -jar -mp modules/ org.jboss.modules.quickstart