如何访问源文件夹中的Jar文件?
在我的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源代码文件夹之外的“libs”文件夹中时(也就是说,在Eclipse中,这个“libs”目录与“src”文件夹处于同一级别),那么这种方法工作正常。 但是,不幸的是,我必须将这个H2 .jar文件放入源代码文件夹树中的文件夹中,但是在主类文件夹下面。
例如,我的Java包结构在Eclipse中如下所示:
/src/my/app/MyApp.java // main class of my application /src/my/app/sub/package/h2.jar // how to access this? /libs/h2.jar // loading from here works
我知道这是愚蠢的,但不幸的是我必须使用这个奇怪的设置。 但我不知道:我如何编辑我的Java代码(如上所列)才能使用此设置?
编辑:这也必须在Eclipse之外工作,所以将JAR文件添加到Eclipse中的Java Build Path对我来说是不可取的。
EDIT2:我已经尝试加载“jar:file:my / app / sub / package / h2.jar!/”,但这对我不起作用。
在此先感谢所有有用的想法!
亲切的问候,马蒂亚斯
在某些框架中,引用JAR中的文件可以使用classpath:
前缀来完成。 我怀疑URLClassLoader本身是否支持它,但值得一试(例如 但由于这不适用于URLClassLoader,以下是其他方法: classpath:/my/app/sub/package/h2.jar
)。
一种方法是编写自己的ClassLoader,它从类路径中读取JAR文件(使用getResourceAsStream),将其解压缩(使用ZipInputStream)到内存(例如字节数组的映射)并从那里加载类。
另一种稍微简单的方法是从类路径中读取JAR文件并将其写入临时文件。 然后,您可以使用普通URLClassLoader从中加载类。 这样做的缺点是必须将文件写入文件,并且在JVM退出之前可能无法删除该文件( 除非使用Java 7或更高版本)。
我在一个项目中使用第二种方法(复制到临时文件),虽然我正在使用它来启动外部进程 。 我很想知道为什么你有这样的要求。 如果只是将整个应用程序放在一个JAR中,那么有许多更简单的方法可以实现(Maven Assembly Plugin,Maven Shade Plugin,Jar Jar Links,One-JAR等等)。
不,这不是一个家庭作业,而是一个在我的/ app / *和其他几个类(不是来自我)下使用我的类来自动构建整个解决方案的在线构建系统。 无论如何,我不能给你更多关于这个系统内部的细节,因为我不知道它们。 如上所述,我只需忍受它,这就是我在这里问的原因……
听起来你在WTF环境中工作(它有一个名字吗?),所以这里有一些方法来开始黑客攻击它:
了解有关您的环境的更多信息,尤其是以下的绝对文件路径:保存源文件的目录,保存生成的.class文件的目录以及运行程序时的当前工作目录。
如果您可以获得程序在运行时打印的任何类型的输出,您可以在应用程序中放入一些调试代码,您可以使用File.listFiles()来抓取机器的目录树。 如果只能从编译时发生的事情中获得输出,那么可以在编译期间通过创建自己的注释处理器来执行自己的代码(自Java 6开始,apt是javac的一部分),尽管我不确定是否注释处理器必须先单独编译。
可以从user.dir
系统属性读取工作目录,并且可以从java.class.path
系统属性获取类文件的位置(除非使用自定义类加载器)。 无法保证源目录中的JAR文件将被复制到类路径中,因此您可能需要进行一些调查。
然后,当您知道JAR文件的文件路径时,您可以使用new File("path/to/h2.jar").toURI().toURL()
获取它的URL,然后您可以将其传递给URLClassLoader。
如果没有其他工作,请上传库的源代码并与项目一起编译。
从长远来看,尝试使用标准构建工具(例如Maven)和公共CI服务器(例如Jenkins)替换WTF构建环境。 项目具有大量库依赖项是正常的,因此您不需要破解构建环境来使用它们。
- Parent Last Classloader解决Java类路径地狱?
- 在代码上获取ClassNotFoundException:“Class.forName(”com.microsoft.sqlserver.jdbc.SqlServerDriver“);”
- 设置类路径以便在mysql和jdbc之间进行连接
- Netbeans:需要在classpath中包含第三方目录
- 又一个Ant + JUnit类路径问题
- Java SPI – ServiceLoader – 将多个JAR添加到APP类路径
- 在Mac OS中将JAR添加到CLASSPATH
- Windows上的RxTx安装java.lang.NoClassDefFoundError:gnu / io / CommPort
- 执行Mavenunit testing,并将classpath设置为生成的项目JAR