2012-05-10 3 views
2

в моем проекте Java Я использую базу данных с памятью H2, для которой я должен загрузить драйвер JDBC при инициализации моего приложения. Я хочу/необходимость загрузить H2 .jar файл динамически, так что я сделать следующее:Как получить доступ к файлу 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)); 

Когда я поставил .jar файл H2 в папку «Libs» вне моей папки исходного кода Java (то есть, в Eclipse этот каталог «libs» находится на том же уровне, что и папка «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-код (указанный выше), чтобы работать с этой настройкой?

EDIT: Это должно работать и вне Eclipse, поэтому добавление JAR-файла в путь Java-сборки в Eclipse для меня не является вариантом.

EDIT2: Я уже пытался загрузить «jar: file: my/app/sub/package/h2.jar! /», Но это не сработало для меня.

Заранее благодарим за полезные советы!

С уважением, Matthias

+0

Вы попробовали jar: файл: my/app/sub/package/h2.jar? – kosa

+0

«Странная настройка», которую вы описываете, является довольно обычной структурой каталогов. Нет причин помещать файлы JAR в папку 'src'. Похоже, вы просто не используете 'h2.jar' в своем пути к классам. –

+0

@thinksteep: да, попробовал, но это не сработало. – Matthias

ответ

2

В некоторых структур, относящихся к файлам внутри JAR-можно сделать с помощью префикса classpath:. Я сомневаюсь, что URLClassLoader поддерживает его изначально, но стоит попробовать (например, classpath:/my/app/sub/package/h2.jar). Но так как это не работает с URLClassLoader, здесь и другие способы:

Один из способов сделать это было бы написать свой собственный ClassLoader, который считывает файл JAR из пути к классам (используя getResourceAsStream), распаковывает его (используя ZipInputStream) в память (например, карту массивов байтов) и загружает классы оттуда.

Другой, немного более простой способ - прочитать JAR-файл из пути к классам и записать его во временный файл. Затем вы можете использовать простой URLClassLoader для загрузки классов из него. Это имеет тот недостаток, что файл должен быть записан в файл, и файл, вероятно, не может быть удален до выхода JVM (unless using Java 7 или выше).

Я использую второй подход (копирование во временный файл) in one project, хотя я использую его для launch an external process. Мне было бы интересно узнать, почему у вас есть такое требование. Если это всего лишь вопрос о наличии всего приложения в одном JAR, для этого есть множество простых методов (Maven Assembly Plugin, Maven Shade Plugin, Jar Jar Links, One-JAR, чтобы назвать несколько).


Нет это не не домашнее задание, но онлайн система сборки, которая использует свои классы под моим/приложение/* и несколько других классов (не от меня), чтобы автоматически создать все решение. Во всяком случае, я не могу дать вам более подробную информацию о внутренних компонентах этой системы, поскольку я их не знаю. Как уже говорилось, я просто жить с этим, и именно поэтому я прошу здесь ...

Похоже, вы работаете в WTF среде (у него есть имя?), так вот несколько способов начать взломать его:

Узнайте больше о вашей среде, особенно абсолютных путей к файлу: каталог, в котором хранятся исходные файлы, каталог, в котором сохранены сгенерированные файлы .class, и текущий рабочий каталог при запуске программы.

Если вы можете получить какой-либо вывод о том, что ваша программа печатает во время выполнения, вы можете добавить в свое приложение код отладки, в котором вы используете File.listFiles() для сканирования дерева каталогов машины. Если вы можете получить вывод только из того, что происходит при компиляции, возможно, вы сможете выполнить свой собственный код во время компиляции, создав свой собственный annotation processor (apt является частью javac с Java 6), хотя я не уверен, должен ли обработчик аннотации сначала составляться.

Рабочий каталог можно прочитать из системного свойства user.dir, и расположение файлов классов может быть, вероятно, получено из системного свойства java.class.path (если не используются специальные загрузчики классов). Нет никакой гарантии, что файл JAR в исходном каталоге будет скопирован в путь к классам, поэтому вам может потребоваться некоторое время оглядеться.

Затем, когда вы знаете путь к файлу JAR-файла, вы можете получить URL-адрес, используя new File("path/to/h2.jar").toURI().toURL(), который затем можно передать URLClassLoader.

Если ничего не работает, загрузите исходный код библиотек и скомпилируйте их вместе с вашим проектом.

В конечном итоге попробуйте заменить среду сборки WTF той, которая использует стандартный инструмент сборки (например, Maven) и общий сервер CI (например, Jenkins). Обычно для проектов есть множество зависимостей между библиотеками, поэтому вам не нужно взламывать среду сборки, чтобы использовать их.

+0

К сожалению, использование «classpath:» не работает. Мне нужно работать с этим окружением, потому что это своего рода автоматическая система онлайн-сборки, где я могу загружать только файлы и папки под моим/app/* – Matthias

+0

. Я обновил свой ответ. Можете ли вы узнать больше об окружающей среде, используя эти советы? Является ли среда открытой, чтобы мы могли ее рассмотреть? –

+0

Я думаю, вы правы, это действительно среда WTF. Я попытаюсь связаться с его владельцем и узнать каталоги, в которых все файлы классов будут в конечном итоге. Кроме того, возможно, он может вручную скопировать файл .jar в соответствующий каталог ... – Matthias

Смежные вопросы