`
加菲学Java
  • 浏览: 132565 次
  • 性别: Icon_minigender_1
  • 来自: 扬州
社区版块
存档分类
最新评论

URLClassLoader中指定目录和jar的问题

 
阅读更多

测试用的是jdk1.6.0_16. 项目的结构图:

  
                                

src:源码

classes:编译后的文件

lib:junit

urlclassloaderpath:测试过程中要从这里加载类

编译和运行(都是在classloader目录下):

编译:javac -encoding utf-8 -d classes -cp lib\junit-4.7.jar src\urlclassloader\URLClassLoaderTest.java
运行:java -cp classes;lib\junit-4.7.jar org.junit.runner.JUnitCore urlclassloader.URLClassLoaderTest

 

 

问题的来源,先看下面的code:

 

try {
	System.out.println("==========test2=========");
	URL[] urls = new URL[] {
			new URL("file:/" + System.getProperty("user.dir") + "/urlclassloaderpath")
			// new URL("file:/" + System.getProperty("user.dir") + "/urlclassloaderpath/")
	};
	
	for(URL u : urls) {
		System.out.println(u.toString());	
											
	}
	
	URLClassLoader ul = new URLClassLoader(urls);

	Class<?> c = ul.loadClass("hello.HelloWorld");
	System.out.println(c);

	c = ul.loadClass("urlclassloader.test.Test");
	System.out.println(c);
	System.out.println("==========test2=========" + rt);
} catch (Exception e) {
	System.out.println("test2():" + e + rt);
}

上面的意思就是从urlclassloaderpath下加载hello.HelloWorld这个类, 目录下也的确存在hello包和HelloWorld类。如果使用的是:new URL("file:/" + System.getProperty("user.dir") + "/urlclassloaderpath"),那么运行的时候会出现异常:java.lang.ClassNotFoundException。如果使用的是:new URL("file:/" + System.getProperty("user.dir") + "/urlclassloaderpath/") 则是OK的。郁闷的地方来了,指定classes目录时,无论是否在最后加"/"都是没有问题的,换成urlclassloaderpath目录怎么就不行了?

 

可以先查看一下URLClassLoader类的API(中文的), 是这么说的:该类加载器用于从指向 JAR 文件和目录的 URL 的搜索路径加载类和资源。这里假定任何以 '/' 结束的 URL 都是指向目录的。如果不是以该字符结束,则认为该 URL 指向一个将根据需要打开的 JAR 文件。

不过从运行的结果来看,貌似不是很对。

 

再看刚刚那个程序, 下面还加载了:c = ul.loadClass("urlclassloader.test.Test"); 在URL中我们并没有指定classes目录, 但是加载urlclassloader.test.Test缺少没有任何问题的。其实这里可以这么思考下:运行的时候指定的classpath是classes,那么从这个目录下加载当然是没有问题的。这样的话就能够说的通了。

 

 

再来看下加载jar包中的类. 只是指定了目录,而没有指定具体的jar包。

		try {
			URL[] urls = new URL[] {
					new URL("file:" + System.getProperty("user.dir") + "/classes/")
			};
			
			for(URL u : urls) {
				System.out.println(u.toString());
			}	
			
			// 从jar文件中加载一个类
			URLClassLoader ul = new URLClassLoader(urls);
			Class<?> c = ul.loadClass("test.classpath.jar.ClasspathJarFile");
			
			System.out.println(c);	
			System.out.println("==========test=========" + rt);
		} catch (Exception e) {
			System.out.println("test() : " + e + rt);
		}

运行上面的程序,报的是java.lang.ClassNotFoundException。 如果改成:

new URL("file:" + System.getProperty("user.dir") + "/classes/classpath.jar")

   指定了具体的jar包,则是没有问题的。

其实这个和我们的命令行差不多,在我们指定-cp的时候必须要指定具体的jar包,而不能只指定目录。

完整的测试程序见附件或者https://github.com/yklovejava/yklovejava/tree/master/jvm/classloader

 

总结:测试完后就明白了

 

  • 大小: 3 KB
2
1
分享到:
评论
1 楼 supben 2012-11-29  
这里假定任何以 '/' 结束的 URL 都是指向目录的。如果不是以该字符结束,则认为该 URL 指向一个将根据需要打开的 JAR 文件。

如果以/结尾,表示 class文件的集合。
否则就表示是一个一个jar文件。

以/结尾,表示 class文件的集合。当然是一个文件夹。他就会递归找下面的所有子包。
否则就表示是一个jar文件,只按jar方式读取本文件。
按照这个约定来的话会更高效些。

相关推荐

    Java URLClassLoader动态加载jar包1

    Java URLClassLoader 是Java标准库中的一个类加载器,它允许我们动态地从指定的URL位置加载类和资源。这个功能在开发插件系统、热部署或者处理多种版本库的场景中非常有用。从JDK 1.2开始,`java.net.URLClassLoader...

    使用URLClassLoader加载本地文件夹c盘下的test.jar文件

    最后,关于`testproject`和`testInterface`这两个文件或目录,如果它们与test.jar有关联,可能是项目的源代码目录或者包含接口定义的文件。例如,`testproject`可能是存放源代码的项目目录,`testInterface`可能是一...

    Springboot + Hutool-db 使用 URLClassLoader 动态加载外部数据库和数据池 jar包实例

    在这个场景中,我们看到一个基于Springboot的应用程序结合了Hutool-db库,利用URLClassLoader来实现动态加载外部数据库驱动和数据池的jar包。这使得开发者可以在不重启应用的情况下更新或添加新的数据库连接和资源池...

    Eclipse打包成JAR包读取外部JAR包和外部配置文件

    Eclipse默认使用`URLClassLoader`,它可以处理这种目录结构。但如果你遇到类找不到的错误,可能需要自定义类加载器,或者使用像`Class-Path`属性这样的方法来指定JAR文件的位置。 总结来说,打包Eclipse项目为JAR并...

    Spring bean 动态注册,jar包热替换

    Spring bean 一般通过配置文件和注解进行加载,如果要实现jar或class文件,动态实现spring bean 的动态加载,并通过UrlClassLoader完成jar和class文件的加载。可以实现jar的热替换。spring的bean动态加载则需要对...

    解决classloader的jar包

    包括commons-logging commons-beanutils commons-lang ezmorph json-lib-2.4-jdk15 commons-collections-3.2.1的jar包,可以解决 org/apache/commons/lang/exception/NestableRuntimeException的问题

    URLClassLoader初体验

    在Java世界中,`URLClassLoader`是一个非常关键的类,它是`ClassLoader`的子类,主要用于从指定的URL(统一资源定位符)加载类和资源。这篇博客文章“URLClassLoader初体验”可能深入探讨了如何使用`URLClassLoader`...

    jar包隔离代码.zip

    2. 使用URLClassLoader:通过URL数组指定jar的路径,每个URL代表一个jar,可以控制不同版本的jar包加载顺序。 3. 配置管理:创建配置文件,记录各个模块所依赖的jar包版本,根据配置动态加载对应的jar包。 4. 使用...

    AXMLPrinter2、baksmali、smali、dex2jar

    解压xxx.apk,将classes.dex拷贝至baksmali-1.3.0.jar所在目录,通过cmd进入baksmali-1.3.0.jar所在目录, 使用如下命令,得到classout文件夹,即classes.dex的全部反编译文件,后缀名都为xxx.smali。 java -jar ...

    jar包、class文件读取工具

    总结,jar包和class文件是Java开发的基础,理解它们的结构和读取方式对于优化代码、调试问题和学习第三方库至关重要。JD-GUI作为一款强大的class文件查看工具,可以帮助开发者直观地查看和理解字节码,提升开发效率...

    Struct jar 包

    6. **版本管理和冲突解决**: 使用JAR包时,可能会遇到版本冲突问题。为了解决这个问题,可以使用依赖管理工具(如Maven或Gradle的版本冲突解决策略),确保所有依赖项的版本兼容。 7. **优化和部署**: 在生产环境中...

    Java 自动加载JAR文件并运行其中的类方法

    在实际应用中,可能还需要考虑类的版本冲突、安全性和性能优化等问题。例如,使用服务发现框架(如OSGi)来管理类加载和依赖,或者使用更高级的插件系统(如Spring Boot的起步依赖)来实现更加复杂的插件架构。 ...

    加载jar包中的spring配置文件

    `classpath*:`不仅会查找类路径下的指定资源,还会递归地查找所有jar包和目录下的匹配文件。这意味着如果你有多个相同命名的配置文件分别存在于不同的jar包中,`classpath*:`会找到所有这些文件。 4. **Spring的...

    java反序列化漏洞URLClassLoader利用1

    2. **使用安全的反序列化库**:如果必须反序列化,可以使用已经处理了安全性问题的库,比如Google的Protocol Buffers或Jackson的`ObjectMapper`,并配置它们以限制反序列化的类。 3. **限制类加载器的权限**:通过...

    springboot动态加载jar包到容器中,并映射为接口

    ### Spring Boot 动态加载 Jar 包到容器中并映射为接口的技术解析 ...需要注意的是,在实际开发中还需要考虑到安全性和性能问题,例如确保加载的 Jar 匼来自可信来源,并优化加载过程以减少对应用性能的影响。

    反射调用assets下的jar

    在Android开发中,有时我们...总之,通过将自定义JAR文件放在assets目录并使用反射调用,可以实现代码的封装和隐藏,但同时也需要注意性能和安全问题。在实际开发中,应根据项目需求和约束权衡利弊,合理利用这种技术。

    jar 包 内文件读取 文件内容

    - 如果需要频繁访问JAR内的文件,考虑使用`JarURLConnection`和`URLClassLoader`,它们提供了更高级的特性,如缓存和异步加载。 7. **开发工具支持**: - 开发环境中,像Eclipse和IntelliJ IDEA这样的IDE提供了...

    反射获取jar文件中的类

    这个方法使用了 JarFile 和 JarEntry 来获取 jar 文件中的所有类,然后使用 URLClassLoader.loadClass 方法加载类,并使用 getMethods 方法获取类中的方法。 反射的应用 反射机制有很多应用,例如: * 动态代理:...

    Java源文件读取JAR包文件.rar

    6. **优化性能**:如果你需要频繁地读取JAR中的文件,考虑使用`URLClassLoader`或`Class.getResourceAsStream()`方法,这可能会提供更好的性能。 通过以上步骤,你可以在Java源文件中成功地读取并处理JAR包文件中的...

Global site tag (gtag.js) - Google Analytics