转自:http://www.blogjava.net/jnbzwm/archive/2011/04/01/347491.html
在项目中实现了一个工具(独立运行的Java工程,打成jar包后 通过 java -jar **.jar 执行的。),该工具通过配置能够实现一些业务功能,
并且该工具提供了接口与抽象类,供其他人扩展它的功能。
这就涉及到一个问题:别人在扩展它的时候,需要引入一些jar或者配置文件,本来工具依赖的jar和配置文件都记录在manifest文件中了,
不可能别人加了jar包和配置文件就要修改manifest文件的。
所以我为工具提供了另外一个入口,通过 该通过的配置文件 进行配置 路径,由于考虑到扩展的人可能多人或者多组,所以配置文件如下定义:
以ext_classpath开头的,诸如 ext_classpath_biz1等对应的路径均被加入到classpath中。
以ext_resourcepath开头的,诸如 ext_resourcepath_biz1等对应的路径均被加入classpath中。
代码实现如下:
package com.bz.utils;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
/**
* 根据properties中配置的路径把jar和配置文件加载到classpath中。
* @author jnbzwm
*
*/
public final class ExtClasspathLoader {
/** URLClassLoader的addURL方法 */
private static Method addURL = initAddMethod();
private static URLClassLoader classloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
/**
* 初始化addUrl 方法.
* @return 可访问addUrl方法的Method对象
*/
private static Method initAddMethod() {
try {
Method add = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class });
add.setAccessible(true);
return add;
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 加载jar classpath。
*/
public static void loadClasspath() {
List<String> files = getJarFiles();
for (String f : files) {
loadClasspath(f);
}
List<String> resFiles = getResFiles();
for (String r : resFiles) {
loadResourceDir(r);
}
}
private static void loadClasspath(String filepath) {
File file = new File(filepath);
loopFiles(file);
}
private static void loadResourceDir(String filepath) {
File file = new File(filepath);
loopDirs(file);
}
/**
* 循环遍历目录,找出所有的资源路径。
* @param file 当前遍历文件
*/
private static void loopDirs(File file) {
// 资源文件只加载路径
if (file.isDirectory()) {
addURL(file);
File[] tmps = file.listFiles();
for (File tmp : tmps) {
loopDirs(tmp);
}
}
}
/**
* 循环遍历目录,找出所有的jar包。
* @param file 当前遍历文件
*/
private static void loopFiles(File file) {
if (file.isDirectory()) {
File[] tmps = file.listFiles();
for (File tmp : tmps) {
loopFiles(tmp);
}
}
else {
if (file.getAbsolutePath().endsWith(".jar") || file.getAbsolutePath().endsWith(".zip")) {
addURL(file);
}
}
}
/**
* 通过filepath加载文件到classpath。
* @param filePath 文件路径
* @return URL
* @throws Exception 异常
*/
private static void addURL(File file) {
try {
addURL.invoke(classloader, new Object[] { file.toURI().toURL() });
}
catch (Exception e) {
}
}
/**
* 从配置文件中得到配置的需要加载到classpath里的路径集合。
* @return
*/
private static List<String> getJarFiles() {
// TODO 从properties文件中读取配置信息略
return null;
}
/**
* 从配置文件中得到配置的需要加载classpath里的资源路径集合
* @return
*/
private static List<String> getResFiles() {
//TODO 从properties文件中读取配置信息略
return null;
}
public static void main(String[] args) {
ExtClasspathLoader.loadClasspath();
}
}
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
/**
* 根据properties中配置的路径把jar和配置文件加载到classpath中。
* @author jnbzwm
*
*/
public final class ExtClasspathLoader {
/** URLClassLoader的addURL方法 */
private static Method addURL = initAddMethod();
private static URLClassLoader classloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
/**
* 初始化addUrl 方法.
* @return 可访问addUrl方法的Method对象
*/
private static Method initAddMethod() {
try {
Method add = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class });
add.setAccessible(true);
return add;
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 加载jar classpath。
*/
public static void loadClasspath() {
List<String> files = getJarFiles();
for (String f : files) {
loadClasspath(f);
}
List<String> resFiles = getResFiles();
for (String r : resFiles) {
loadResourceDir(r);
}
}
private static void loadClasspath(String filepath) {
File file = new File(filepath);
loopFiles(file);
}
private static void loadResourceDir(String filepath) {
File file = new File(filepath);
loopDirs(file);
}
/**
* 循环遍历目录,找出所有的资源路径。
* @param file 当前遍历文件
*/
private static void loopDirs(File file) {
// 资源文件只加载路径
if (file.isDirectory()) {
addURL(file);
File[] tmps = file.listFiles();
for (File tmp : tmps) {
loopDirs(tmp);
}
}
}
/**
* 循环遍历目录,找出所有的jar包。
* @param file 当前遍历文件
*/
private static void loopFiles(File file) {
if (file.isDirectory()) {
File[] tmps = file.listFiles();
for (File tmp : tmps) {
loopFiles(tmp);
}
}
else {
if (file.getAbsolutePath().endsWith(".jar") || file.getAbsolutePath().endsWith(".zip")) {
addURL(file);
}
}
}
/**
* 通过filepath加载文件到classpath。
* @param filePath 文件路径
* @return URL
* @throws Exception 异常
*/
private static void addURL(File file) {
try {
addURL.invoke(classloader, new Object[] { file.toURI().toURL() });
}
catch (Exception e) {
}
}
/**
* 从配置文件中得到配置的需要加载到classpath里的路径集合。
* @return
*/
private static List<String> getJarFiles() {
// TODO 从properties文件中读取配置信息略
return null;
}
/**
* 从配置文件中得到配置的需要加载classpath里的资源路径集合
* @return
*/
private static List<String> getResFiles() {
//TODO 从properties文件中读取配置信息略
return null;
}
public static void main(String[] args) {
ExtClasspathLoader.loadClasspath();
}
}
相关推荐
- 当配置文件被打包在conf.jar文件内时,上述代码将加载jar文件内conf目录下的`application-context.xml`文件。 - 如果同时存在目录和jar包,且没有使用classpath*前缀,Spring默认只会加载目录下的配置文件。 2...
然而,如果类是由不同的ClassLoader加载的,即使它们在相同的包内,也可能彼此不可见。这就是所谓的“类隔离”。 在一些高级应用中,如插件系统或动态加载,开发者可能需要自定义ClassLoader来加载特定的类或资源。...
Java深度历险是一本专注于Java技术深度探索的书籍,涵盖了JVM(Java虚拟机)、Classpath、ClassLoader以及import等核心概念。在这个Java编程的世界里,深入理解这些知识点是提升编程能力的关键。 首先,我们来探讨...
在Java中,通过`Class.forName()` 或者 `ClassLoader.loadClass()` 方法可以加载这些类,进而调用其中的方法实现打印功能。 `.settings` 文件夹则可能包含Eclipse等IDE的项目配置信息,这些信息用于管理项目的构建...
或 -Xbootclasspath选项指定的jar包等 虚拟机识别的类库 加载到内存中。 由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用, 所以 不允许直接通过引用进行操作...
* classpath:用于加载类路径(包括jar包)中的一个且仅一个资源。对于多个匹配的也只返回一个,所以如果需要多个匹配的请考虑使用classpath*:前缀。 * classpath*:用于加载类路径(包括jar包)中的所有匹配的资源...
- **CLASSPATH**: 设置此类路径以支持 Java 编译和运行过程中类的查找,通常包含当前路径、`log4j.jar` 和 `lib` 目录等。 #### 二、Java 编译与运行 ##### 2.1 编译过程 - Java 源代码通过 `javac` 编译器转换为...
1. **Bootstrap ClassLoader**: 这是 Java 系统的核心类加载器,负责加载 Java 核心库,如 `$JDK/jre/lib/rt.jar` 中的类库。 2. **Extensible ClassLoader**: 用于加载扩展 API 的类库,这些类库通常位于 `$JDK/...
这通常发生在我们想要在运行时加载非代码的资源,而这些资源在编译后被包含在类路径(classpath)中。本文将详细介绍如何在Java Web环境中读取`classes`目录下的文件。 首先,了解Java Web项目的基本结构是关键。一...
3. 应用类加载器(AppClassLoader)或称为系统类加载器:负责加载CLASSPATH中的类,通过ClassLoader.getSystemClassLoader()方法可以获取到它。 需要注意的是,类加载器之间的关系并不是垂直的继承关系,而是组合...