如何访问源文件夹中的Jar文件? [英] How to access Jar file located within source folders?

查看:124
本文介绍了如何访问源文件夹中的Jar文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Java项目中我使用的是H2内存数据库,我必须在初始化应用程序时加载JDBC驱动程序。我想/需要动态加载H2 .jar文件,所以我执行以下操作:

in my Java project I am using an H2 in-memory database, for which I have to load the JDBC driver when I initialize my application. I want/need to load the H2 .jar file dynamically, so I do the following:

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文件放入源代码文件夹树中的一个文件夹中,但是在主类文件夹下面。

When I put the H2 .jar file into a "libs" folder outside my Java source code folder (that is, in Eclipse, this "libs" directory is on the same level as the "src" folder), then this approach works fine. However, unfortunately I have to put this H2 .jar file into a folder within the source code folder tree, but below the main class folder.

例如,我的Java包Eclipse中的结构如下所示:

For example, my Java package structure looks like this in 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

I知道这是愚蠢的,但不幸的是我必须使用这个奇怪的设置。但我不知道:如何编辑我的Java代码(如上所列)以便使用此设置?

I know this is stupid, but unfortunately I have to work with this strange setup. But what I don't know: how can I edit my Java code (listed above) in order to work with this setup?

编辑:这必须在Eclipse外部工作同样,所以将JAR文件添加到Eclipse中的Java Build Path对我来说是没有选择。

This has to work outside Eclipse as well, so adding the JAR file to the Java Build Path in Eclipse is no option for me.

EDIT2:我已经尝试加载jar:file:my / app / sub / package / h2.jar!/,但这对我没用。

I already tried to load "jar:file:my/app/sub/package/h2.jar!/", but that did not work for me.

提前感谢所有有用的想法!

Thanks in advance for all helpful ideas!

亲切的问候,Matthias

Kind regards, Matthias

推荐答案

在某些框架中,引用JAR内的文件可以使用类路径:前缀。 我怀疑URLClassLoader本身是否支持它,但值得一试(例如 classpath:/my/app/sub/package/h2.jar )。但由于这不适用于URLClassLoader,这里有其他方法:

In some frameworks referring to files inside JARs can be done using the classpath: prefix. I doubt URLClassLoader supports it natively, but it's worth a try (e.g. classpath:/my/app/sub/package/h2.jar). But since that doesn't work with URLClassLoader, here are other ways:

一种方法是编写自己的ClassLoader,从类路径中读取JAR文件(使用getResourceAsStream),将其解压缩(使用ZipInputStream)到内存(例如字节数组的映射)并从那里加载类。

One way to do it would be to write your own ClassLoader which reads the JAR file from classpath (using getResourceAsStream), uncompresses it (using ZipInputStream) to memory (e.g. a map of byte arrays) and loads the classes from there.

另一种更简单的方法是从类路径中读取JAR文件并将其写入临时文件。然后,您可以使用普通URLClassLoader从中加载类。这样做的缺点是必须将文件写入文件,并且在JVM退出之前可能无法删除该文件(除非使用Java 7或更高版本

Another, slightly easier way, is to read the JAR file from classpath and write it into a temporary file. Then you can use the plain URLClassLoader to load classes from it. This has the disadvantage that the file must be written to a file and the file probably cannot be removed until the JVM exits (unless using Java 7 or higher).

我正在使用第二种方法(复制到临时文件)在一个项目中,虽然我用它来启动外部流程。我很想知道为什么你有这样的要求。如果只是将整个应用程序放在一个JAR中,有许多更简单的方法可以实现(Maven Assembly Plugin,Maven Shade Plugin,Jar Jar Links,One-JAR等等)。

I'm using the second approach (copying to a temp file) in one project, though I'm using it to launch an external process. I would be curious to hear why you have such a requirement. If it's just a matter of having the whole application in one JAR, there are numerous simpler methods for achieving that (Maven Assembly Plugin, Maven Shade Plugin, Jar Jar Links, One-JAR to name a few).


不,这不是一个家庭作业,而是一个在我的/ app / *下使用我的课程的在线构建系统其他类(不是来自我)自动构建整个解决方案。无论如何,我不能给你更多关于这个系统内部的细节,因为我不知道它们。如上所述,我只需忍受它,这就是我在这里问的原因......

No it's not a homework, but an online build system that uses my classes under my/app/* and several other classes (not from me) to automatically build the whole solution. Anyway, I can't give you more details on the internals of this system, as I don't know them. As said, I simply have to live with it, and that is why I am asking here...

听起来你在工作在 WTF 环境中(它有名称吗?),所以这里有一些方法来开始黑客攻击:

Sounds like you are working in a WTF environment (does it have a name?), so here are some ways to start hacking around it:

了解有关您的环境的更多信息,特别是以下的绝对文件路径:保存源文件的目录,保存生成的.class文件的目录以及当前的工作程序运行时的目录。

Find out more about your environment, especially absolute file paths of the following: directory where the source files are saved, directory where the generated .class files are saved, and the current working directory when the program is run.

如果您可以获得程序在运行时打印的任何类型的输出,您可以在应用程序中输入一些调试代码 File.listFiles()抓取机器的目录树。如果只能从编译时发生的事情中获得输出,则可以在编译期间通过创建自己的注释处理器(自Java 6以来apt是javac的一部分),虽然我不确定是否必须首先单独编译注释处理器。

If you can get any kind of output of what your program prints during runtime, you can put into your application some debug code where you use File.listFiles() to crawl the machine's directory trees. If you can get output only from what happens when compiling, it might be possible to execute your own code during compile by creating your own annotation processor (apt is part of javac since Java 6), though I'm not sure whether the annotation processor must be compiled first separately.

可以从 user.dir 系统属性中读取工作目录,并且类文件的位置可能来自 java.class.path 系统属性(除非使用自定义类加载器)。无法保证源目录中的JAR文件将被复制到类路径中,因此您可能需要进行一些查看。

The working directory can be read from the user.dir system property and the location of class files can be probably gotten from the java.class.path system property (unless custom class loaders are used). There is no guarantee that a JAR file in the source directory would be copied to the classpath, so you might need to do some looking around.

然后当您知道文件时JAR文件的路径,然后你可以使用 new File(path / to / h2.jar)。toURI()。toURL()获取一个URL。然后你可以传递给URLClassLoader。

Then when you know the file path of the JAR file, then you can get an URL to it using new File("path/to/h2.jar").toURI().toURL() which you can then pass to URLClassLoader.

如果没有其他工作,上传库的源代码并将它们与你的项目一起编译。

If nothing else works, upload the source code of the libraries and compile them together with your project.

从长远来看,尝试将WTF构建环境替换为使用标准构建工具(例如Maven)和公共CI服务器(例如Jenkins)的构建环境。项目有很多库依赖项是正常的,所以你不需要破解构建环境来使用它们。

In the long run, try to replace the WTF build environment with one that uses a standard build tool (such as Maven) and a common CI server (such as Jenkins). It's normal for projects to have lots of library dependencies, so you shouldn't need to hack around a build environment to use them.

这篇关于如何访问源文件夹中的Jar文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆