ClassLoader на виртуальной машине

У меня есть исходный код:

private Image getImage(String path, ClassLoader loader) {
    InputStream image = null;
    try {
        image = loader.getResourceAsStream(path);
        return new Image(PlatformUI.getWorkbench().getDisplay(), image);
    } finally {
        if (image != null) {
            try {
                image.close();
            } 
            catch (IOException e) {
                //OK
            }
        }
    }
}

На моем компьютере этот код работает отлично. Но в строке виртуальной машины:

loader.getResourceAsStream(path);

всегда возвращает ноль. Почему?

РЕДАКТИРОВАТЬ:

Путь является относительным путем. Например: icons/tools/device.png. Приложение, которое я разрабатываю, содержит более десяти проектов. Я использую Eclipse IDE. Все проекты имеют структуру:

  • com.pkg.name - папка с иконками классов
  • папка с иконками и другими файлами

Файлы JAR также имеют эту структуру.

На моем компьютере приложения работают идеально. На виртуальной машине (Windows Server (64-разрядная)) приложение не может загружать изображения из файла Jar.


person Michał Ziober    schedule 27.01.2010    source источник
comment
Не могли бы вы уточнить, о какой ВМ вы говорите? Я хотя JVM на первый взгляд, но это может быть неправильным предположением.   -  person Andreas Dolk    schedule 27.01.2010
comment
Конечно. Виртуальная машина означает - 64-битный Windows Server. en.wikipedia.org/wiki/Виртуальная_машина.   -  person Michał Ziober    schedule 27.01.2010
comment
Другой вопрос - это стандартное java-приложение, OSGI или даже RCP? Если это OSGi или RCP, то проблема может быть решена перепроверкой манифестов и их разделов экспорта/импорта.   -  person Andreas Dolk    schedule 27.01.2010
comment
Это приложение RCP на основе uDig. Andreas_D: проблема может быть решена перепроверкой манифестов и разделов их экспорта/импорта - все в порядке. Это работает на моем компьютере.   -  person Michał Ziober    schedule 27.01.2010
comment
mykhaylo - вы должны были предоставить эту информацию раньше - загрузка классов в OSGi намного сложнее, чем в приложениях, отличных от OSGi.   -  person Andreas Dolk    schedule 27.01.2010
comment
Я не знал, что это так важно. Виноват.   -  person Michał Ziober    schedule 27.01.2010


Ответы (2)


Если путь является относительным путем, то он должен работать, если ресурс изображения был скопирован вместе с файлами классов (как уже упоминалось), а папка или банка, содержащая ресурс изображения, находится в пути к классам (используете ли вы ПУТЬ К КЛАССУ или -cp для указания пути к классам? Если вы полагаетесь на ПУТЬ К КЛАССУ, убедитесь, что эта переменная среды правильно установлена ​​для пользователя, выполняющего приложение)

Если это абсолютный путь, дважды проверьте, действителен ли он на целевой виртуальной машине.

так что в основном для структуры папок, например

./classes
./images
./libs

команда java -cp classes;images;libs/* my.app.Application должна работать (java 1.6 - в более старых версиях подстановочный знак не разрешен), предполагая значение пути, такое как images/myImage.jpg.

Еще одна мысль: разделитель пути к классам - ; в Windows и : в unix. Это может быть проблемой, если вы подготовили приложение в среде типа unix.

Изменить

Вы читаете изображение из той же библиотеки, что и ваш настоящий файл класса? Тогда, пожалуйста, попробуйте это:

this.getClass().getResourceAsStream(path)

Изменить

Хорошо, это OSGi. Таким образом, есть еще несколько причин, по которым приложение работает внутри среды eclipse IDE, но не при развертывании в качестве приложения RCP. Я думаю, что это не имеет ничего общего с целевой средой.

В OSGi каждый пакет имеет свой собственный загрузчик классов, и класс из пакета1 не сможет видеть классы из пакета2, если пакеты не экспортированы должным образом. Это верно и для ресурсов. Я предполагаю, что изображение хранится в другом пакете. Я не знаю, какой загрузчик классов передается методу getImage, но этот загрузчик классов определенно не видит файл ресурсов.

Это может работать внутри eclipse, особенно если вы добавляете проекты в пути сборки друг друга.

После того, как вы создали продукт, вы сказали, что он не работает (частично) на виртуальной машине, но показывает ли тот же продукт образ на локальном компьютере (вне eclipse)?

person Andreas Dolk    schedule 27.01.2010
comment
Я не использую CLASSPATH. CLASSPATH требуется для ClassLoder? - person Michał Ziober; 27.01.2010
comment
Я протестировал этот метод (this.getClass().getResourceAsStream(path)). К сожалению, возвращает всегда null. - person Michał Ziober; 27.01.2010
comment
Показывает ли тот же продукт изображение на локальном компьютере (вне eclipse)? - Нет! Ты был прав! Я сделал много тестов. Теперь все работает. Я использовал загрузчик классов из своего класса, который наследуется от UDIGApplication. Я загружаю изображения в методе init этого класса. Спасибо за помощь. - person Michał Ziober; 27.01.2010

Вы не предоставляете достаточно подробностей, но вот мое предположение:

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

Когда вы разрабатываете код с помощью Eclipse (или других IDE), Eclipse позаботится о копировании ваших ресурсов из каталога src/ в каталог bin/.

person Itay Maman    schedule 27.01.2010
comment
Я уверен, что все файлы существуют на виртуальной машине. Я всегда экспортирую свой исходный код в файл Jar. Jar содержит все файлы ресурсов. - person Michał Ziober; 27.01.2010