下午做spa安装程序的时候,由于在jar文件中包含了config.properties文件,导致花了近两个小时来解决"uri is not hierarchical"问题,真是郁闷。就因为一点小疏忽……
不过,对JVM ClassLoader加载体系有了更加清楚的理解。
JVM的类加载体系,相信读过《Inside JVM》的人可能比较熟悉一些。在1.2之后,类加载器体系就是双亲委派体系。依次从高到低级排序是:
启动类加载器, 标准类加载器, 系统类加载器(也就是类路径加载器,JVM实现的用户类加载器),用户自定义类加载器。
我们的资源一般都是通过系统类加载器来进行加载的,比如class文件,jar文件,以及其它资源。
在eclipse项目中,属性文件config.properties直接放在src根目录下即可,在程序中,直接:
java 代码
- URL url = this.getClass().getClassLoader().getSystemResource("config.properties");
- URI cfgUri = URI.create(url.toExternalForm());
- File cfgFile = new File(cfgUri);
这样就OK了。它自然会在classpath上找到这个config.properties。
那如果把这个文件放在JAR文件中,做为JAR的资源呢,其实也是没有关系,上面的代码也是可以找到JAR文件中的资源的,一点错误都没有。同时,也可以这么来加载:
java 代码
- URL url = Thread.currentThread().getContextClassLoader().getResource(fileName);
一样,都是从JAR文件中去加载文件。
但是,如果jar文件中包含了config.properties,并且jar文件外面也包含了config.properties文件,那么结果会怎么样呢?
注意,下面用====包围的解释是不正确的。我自己弄错了双亲委派,哈哈。详细说明:
http://java.sun.com/docs/books/tutorial/ext/basics/load.html
=============================================================================================
因为classloader加载是如果自己加载不了,才让它的双亲classLoader来加载。
这里,由于加载jar的classloader,暂且叫做jarloader可以在jar文件中找到config.properties文件,那么显然就不用去麻烦它的双亲去加载了。要达到加载外面config.properties文件的效果,必须在jar文件中将它去除,免得jarloader麻烦它的双亲classloader去加载它,因为jarloader是被系统类加载器加载的,因此,系统类加载器在classpath上继续查找,找到config.properties文件,这样就加载成功了。
=============================================================================================
应该是class path classloader加载资源顺序的问题。
分享到:
- 2007-05-14 17:46
- 浏览 3039
- 评论(6)
- 论坛回复 / 浏览 (6 / 6723)
- 查看更多
相关推荐
Tomcat作为一款广泛使用的Java应用服务器,其类加载机制有着独特的设计,特别是对Java的双亲委派模型有所突破。本篇文章将深入探讨Tomcat如何打破双亲委派模型,并通过源码分析和图表解析来帮助理解这一机制。 首先...
Loader的子类,名为CustomClassLoader,这次我们不仅重写findClass方法,还要重写loadClass方法,以便在加载类时不遵循双亲委派模型。在loadClass方法中,我们首先检查是否已经加载过该类,如果未加载,则调用自己的...
这里我们将深入探讨“双亲委派”模型,这是Java类加载的一个关键特性。 首先,我们要明白什么是双亲委派模型。在Java中,每个类都由一个特定的类加载器来负责加载。当一个类加载器收到加载类的请求时,它不会立即...
### 类加载器与双亲委派模型详解 #### 类的生命周期与加载过程 类的生命周期主要包括七个阶段:加载、验证、准备、解析、初始化、使用和卸载。在这七个阶段中,验证、准备和解析统称为连接阶段。类的加载过程主要...
双亲委派模型使得系统类(如java.*开头的类)由Bootstrap ClassLoader加载,而用户自定义类由应用程序类加载器(AppClassLoader)加载。这避免了类的冲突,保持了系统类库的稳定性。但有时我们可能需要打破这种模型...
在这个过程中,我们需要注意类的缓存,避免重复加载,以及处理好与双亲委派模型的关系。 在进行ClassLoader测试时,我们可能会涉及以下几个方面: 1. 源码分析:研究ClassLoader的源码,了解其内部实现,特别是加载...
- Java的类加载机制遵循“双亲委派模型”,即一个类加载请求会先由顶级的Bootstrap ClassLoader处理,如果没有找到,则交给Extension ClassLoader,再未找到则继续交给App ClassLoader,最后是用户自定义的...
在Java中,类加载过程遵循双亲委派模型(Parent Delegation Model)。这意味着当一个ClassLoader尝试加载某个类时,它首先会将任务委托给其父ClassLoader。如果父ClassLoader找不到该类,子ClassLoader才会尝试自己...
在Java中,类的加载通常遵循“双亲委派模型”。这个模型的工作原理是:当一个ClassLoader接收到类加载请求时,它首先不会自己去加载,而是委托给父ClassLoader去尝试加载,只有当父ClassLoader无法加载时,子...
本文将详细讲解类加载的流程、类加载器的层次结构以及双亲委派模型。 1. **类加载的生命周期** 类的生命周期包括7个阶段:加载、验证、准备、解析、初始化、使用和卸载。 - **加载**:从指定的位置(如类路径、...
Java的类加载机制遵循双亲委派模型,即当一个类加载器需要加载类时,它首先委托父类加载器尝试加载,只有当父类加载器无法加载时,才会尝试自己加载。这种设计避免了类的重复加载,并确保了核心类库的唯一性。 二、...
双亲委派机制在`ClassLoader`的`loadClass()`方法中体现,方法内部首先检查类是否已经加载,然后尝试将加载请求委托给父加载器,最后如果父加载器无法加载,才由当前加载器自行加载。通过这种方式,保证了像`java....
ClassLoader类的loadClass方法是实现双亲委派模型的核心方法,该方法的主要逻辑是:首先检查类是否已被加载,如果没有就判断是否已被父加载器加载,如果还没有再调用自己的findClass方法尝试加载。 知识点三:...
从Java 1.2版本开始,引入了双亲委派模型(Delegation Model)。在该模型下,当一个ClassLoader收到加载类的请求时,它首先会委托父加载器去尝试加载,只有当父加载器无法加载时,当前加载器才会尝试自己加载。这样...
同时,当遇到“双亲委派模型”(Parent Delegation Model)引发的问题,如类加载异常时,了解ClassLoader的运作方式可以更快定位和解决问题。 总的来说,Java ClassLoader机制是Java平台的核心特性之一,它使得程序...
在类加载过程中,遵循“双亲委派模型”:当一个类加载器需要加载某个类时,它首先会委托它的父加载器尝试加载,只有当父加载器无法加载时,当前加载器才会尝试自己加载。这种机制避免了类的重复加载,并确保了核心...
2. **双亲委派模型**:Java的类加载机制遵循双亲委派模型,即当一个类加载器接收到加载类的请求时,它会先委托给父类加载器去加载,只有当父类加载器无法加载时,当前类加载器才会尝试自己加载。这种设计有助于防止...