在我的Java项目中我使用的是H2的内存数据库,对此我有,当我初始化我的应用程序加载的JDBC驱动程序。 我想/需要加载H2的.jar文件的动态,所以我做到以下几点:
String classname = "org.h2.Driver";
URL u = new URL("jar:file:libs/h2.jar!/");
URLClassLoader ucl = new URLClassLoader(new URL[] { u });
Driver d = (Driver) Class.forName(classname, true, ucl).newInstance();
DriverManager.registerDriver(new DriverShim(d));
当我把H2 .jar文件到“库”文件夹之外我的Java源代码文件夹(也就是,在Eclipse中,这个“库”目录是在同一水平上的“SRC”文件夹),那么这种方法工作得很好。 然而,不幸的是我不得不把这个H2 .jar文件到源代码文件夹树中的文件夹,但低于主类的文件夹。
例如,我的Java包结构看起来像这样在Eclipse:
<project>/src/my/app/MyApp.java // main class of my application
<project>/src/my/app/sub/package/h2.jar // how to access this?
<project>/libs/h2.jar // loading from here works
我知道这是愚蠢的,但不幸的是我有这种奇怪的设置工作。 但我不知道:我怎么能以这种设置工作编辑我的Java代码(上面列出)?
编辑:这有可能在Eclipse外部工作一样,所以添加的JAR文件在Eclipse Java构建路径是对我别无选择。
EDIT2:我已经试图加载“JAR:文件:!我的/应用/子/包/ h2.jar /”,但这并没有为我工作。
在此先感谢所有帮助的想法!
亲切的问候,马蒂亚斯
在一些框架参照文件内部的JAR文件可以用做classpath:
前缀。 我怀疑URLClassLoader的支持它本身,但它是值得一试(如classpath:/my/app/sub/package/h2.jar
)。 但由于不与URLClassLoader的工作,这里有其他的方法:
做到这一点的方法之一是写自己的ClassLoader其内容从类路径(使用的getResourceAsStream)JAR文件,解压缩它(使用ZipInputStream)到存储器(例如图的字节数组),并从那里加载的类。
另外,稍微更简单的方法,就是从文件读取类路径中的JAR文件,并将其写入到一个临时文件。 然后你可以使用普通的URLClassLoader从中加载类。 这有该文件必须写入到一个文件,该文件可能无法被删除,直到退出JVM的缺点( 除非使用Java 7或更高版本)。
我使用的是第二种方法(复制到一个临时文件) 中的一个项目 ,虽然我用它来启动一个外部进程 。 为什么你有这样的要求,我会好奇地听到。 如果它只是一个具有一个JAR整个应用程序的问题上,我们实现这一(Maven的大会插件,Maven的阴影插件,瓶瓶链接,一JAR仅举几例)许多简单的方法。
不,这不是一门功课,但使用在我的课的在线生成系统我/应用/ *和其他几类(而不是从我)来自动生成整个解决方案。 无论如何,我不能给你更多的细节对这个系统的内部,因为我不知道他们。 至于说,我只是不得不忍受它,这就是为什么我问这里...
听起来像是你在一个工作WTF环境(它有名字吗?),所以这里都开始围绕它黑客攻击的一些方法:
了解更多有关你的环境,下面特别是绝对的文件路径:目录所在的源文件保存,所在目录生成的.class文件被保存,和当前工作目录是在程序运行时。
如果你可以在运行时得到任何一种你的程序打印输出,你可以把你的应用程序,你使用一些调试代码File.listFiles()抓取机器的目录树。 如果你能得到的输出只能从编译时会发生什么情况,有可能通过创建自己的执行编译过程中你自己的代码注释处理器 (APT是javac的的一部分,因为Java 6中),但我不知道是否标注处理程序必须单独编译第一。
工作目录可以从读取user.dir
系统属性和类文件的位置可以从被可能得到java.class.path
系统属性(除非使用自定义类加载器)。 谁也不能保证,在源目录中的JAR文件将被复制到类路径中,所以你可能需要做一些环顾四周。
然后,当你知道JAR文件的文件路径,那么你可以使用得到一个URL给它new File("path/to/h2.jar").toURI().toURL()
然后你就可以传递给URLClassLoader的。
如果没有其他作品,上传库的源代码,并与您一起项目编译它们。
从长远来看,尝试用一个使用一个标准的构建工具(如Maven的)和一个共同的CI服务器(如詹金斯)取代WTF构建环境。 这是正常的项目有很多图书馆的依赖,所以你不应该需要破解围绕构建环境中使用它们。