Загрузчик классов в апплете: не удается получить доступ к файлам

У меня есть приложение, которое использует отражение для создания экземпляра кода, сохраненного в некотором каталоге: я создаю URLClassLoader, который затем загружает классы, используя предоставленные URL-адреса; это работает нормально. Я попытался перенести приложение на апплет. Для загрузки текстовых файлов и изображений я изменил код с использования относительных путей на использование getResourceAsStream(), который отлично работает. Однако для загрузчика классов у меня все еще есть исключение ввода-вывода (которое я также использовал для получения текстовых файлов и изображений, прежде чем я изменил код для использования потоков):

java.security.AccessControlException: access denied (java.io.FilePermission /.../... read)

Загружаемые классы содержатся в файле jar (как и все остальные ресурсы). Есть ли способ загрузить классы, используя что-то вроде getResourceAsStream(), которое не вызывает исключение безопасности? Обратите внимание: я говорю о загрузчике классов, вызываемом из java-кода, а не о загрузчике классов, который загружает апплет.

РЕДАКТИРОВАТЬ: Подробнее о структуре файлов/папок:

Мой апплет находится в пакете a, a.MyApplet, который использует класс a.aa.Loader, предназначенный для загрузки классов, хранящихся в другой папке b (поэтому не загружается при загрузке апплета). Папка b содержит множество каталогов, b.c_i, где c_i — уникальный каталог. В каждом из этих каталогов находятся классы, принадлежащие пакету x.y.z, поэтому общая структура папок b имеет вид b.c_i.x.y.z; z содержит файл для загрузки. Когда я создаю банку, верхний уровень выглядит следующим образом ([] указывает папку): [a], [b], [data], [images], где [a] = {MyApplet, [aa], [aaa] и т. д.} и [b]={c_1,_c2,...}, где c_i={[x]}, [x]={[y]}, [y]={[z]} и, наконец, [z ]={Класс.класс}. Надеюсь, обозначение не слишком странное.

Редактировать 2: Подробнее.

Чтобы уточнить: классы, которые я хочу загрузить, - это классы других людей, все они помещены в отдельный каталог «DIR» (они не являются частью проекта и сами не образуют проект). На самом деле все эти имена классов идентичны, они хранятся в уникальных каталогах внутри "DIR". Мне нужно загрузить один файл за раз. Другими словами, я хотел бы обращаться с файлами классов, как с любым другим ресурсом.

ПРИМЕЧАНИЕ. Я попробовал подписанный апплет, и он больше не выдает исключение безопасности, а исключение ввода-вывода: он не может найти файл. Я проверил структуру каталогов и попробовал множество вариантов, все с тем же результатом (это работает на моей локальной машине). Я не уверен, действительно ли это проблема ввода-вывода или все еще проблема безопасности.


person coderino    schedule 20.09.2011    source источник
comment
относится ли путь в FilePermission к одному из ресурсов?   -  person jtahlborn    schedule 20.09.2011
comment
@jtahlborn Да, я просто заменил имена каталогов на ... структура jar-файла следующая: [изображения] [данные] [файлы для загрузки] [пакет]. Загружаемые файлы находятся в своем собственном каталоге, а фактический код апплета находится в [package]. Все находится в файле jar.   -  person coderino    schedule 20.09.2011
comment
@AndrewThompson: но загружаемые классы находятся в каталоге внутри файла jar. Почему это будет отличаться от классов, загружаемых как часть апплета?   -  person coderino    schedule 20.09.2011
comment
@coderino Ты подписал свой апплет?   -  person Alex Abdugafarov    schedule 20.09.2011
comment
@FrozenSpider Нет, в настоящее время он не подписан. Я мог бы подписать его, но предпочел бы этого не делать (думаю, людей это отталкивает). Однако, если бы это было единственным решением, я бы, конечно, так и сделал.   -  person coderino    schedule 20.09.2011
comment
@coderino Ну, это самый простой способ, и я не знаю, как загрузить класс во время выполнения, чтобы обойти SecurityManager (поскольку это не то действие, которое вы хотите сделать бесплатным для какого-то случайного апплета).   -  person Alex Abdugafarov    schedule 20.09.2011
comment
@coderino - на самом деле не должно быть проблем с загрузкой материала из jar, который уже загружен в загрузчик классов. это то, что я пытаюсь понять. как путь к файлу в исключении относится к ресурсам, которые вы пытаетесь загрузить?   -  person jtahlborn    schedule 20.09.2011
comment
@ Эндрю Томпсон - загрузка чего-либо из уже загруженного файла jar не является ошибкой безопасности. если бы это было так, апплеты никогда бы ничего не смогли сделать. как вы думаете, откуда берутся все классы апплетов?   -  person jtahlborn    schedule 20.09.2011
comment
@jtahlborn Я согласен, я думаю, это должно сработать. Исключение показывает относительный путь к месту расположения загружаемых классов. Итак, в банке весь код апплета является частью пакета «а» и находится в каталоге с именем «а». Загружаемые классы находятся в каталоге с именем «b», так что «a» и «b» находятся на одном уровне. У меня была такая же проблема с другими файлами: при попытке загрузить текстовый файл с использованием пути он выдает исключение безопасности, но asStream работает. Поэтому мне было интересно, можно ли загружать классы таким же образом. Я долго искал в Интернете, но не мог найти пример.   -  person coderino    schedule 20.09.2011
comment
@coderino - вы не загружаете классы, используя asStream. если классы уже находятся в пути к классам, вы используете Class.forName(). я понимаю, что вы не хотите давать фактические данные о классе, но вам нужно быть более конкретным, если вам нужна помощь. используйте поддельные каталоги/пакеты, если хотите, но подробно опишите, где что находится и что именно вы пытаетесь сделать.   -  person jtahlborn    schedule 20.09.2011
comment
@coderino Эмм... нотация действительно странная :) Я не мог ее прочитать, поэтому надеюсь, что вы сможете представить ее в виде древовидной структуры.   -  person user592704    schedule 21.09.2011
comment
@ user592704 Да, извините за странную запись. Я не могу загружать изображения и не могу понять, как правильно редактировать текст, чтобы указать структуру каталогов. Я добавил еще несколько заметок, надеюсь, что это поможет.   -  person coderino    schedule 26.09.2011


Ответы (1)


На самом деле, хранить проект как отдельный диапазон объектов - это плохой тон, так что...

  • Вы можете просто упаковать весь свой проект в один файл jar.

  • В случае, если вы храните свои классы на сервере только потому, что весь проект слишком велик, вы можете сжать его с помощью утилиты pack200, которая очень полезна для апплетов толстого клиента Java Web Start.

  • И я рекомендую использовать тип запуска апплета jnlp, потому что он предоставляет больше возможностей с его DeployJava.js.

P.S.

И если вы действительно настаиваете на загрузке ресурсов с помощью загрузчика классов, сделайте это стандартным способом апплета, я имею в виду объект Anchor

например, создайте структуру, например

  • |- образы пакетов -
  • |изображениеA.png
  • |изображениеB.png
  • |Якорь.класс
  • |SourceBound.класс

SourceBound.java

public class SourceBound
{

  /**
    Conception only...
  **/
  public SourceBound(){}

  public ImageIcon getImageA()
  {
    ImageIcon icon;
    Image image;

    image=ImageIO.read(Anchor.class.getResourceAsStream("imageA.png"));
    icon=new ImageIcon(image);

    return icon;
  }
}

  • |пакетный тест
  • |Тест.класс

Тест.java

public class Test
{

SourceBound sourceBound=new SourceBound();

Test()
{
  JButton button=new JButton();
  button.setIcon(sourceBound.getImageA());

}

}

Удачи

person user592704    schedule 21.09.2011