Library Is Alredy Loaded In Anover Classloader

Тема в разделе "Lotus + Java + LS2J", создана пользователем lionk, 19 ноя 2011.

  1. lionk

    lionk Well-Known Member

    Регистрация:
    5 апр 2007
    Сообщения:
    308
    Симпатии:
    3
    Есть Ява-библиотека, которая работает с функциями спрятанными в ДЛЛ.


    Код (C++):
    class JavaDLL
    {  
    public native int Execute();//функция в ДЛЛ

    static {
    System.loadLibrary("mydll"); // подключил ДЛЛ
    }

    }
    public class HASP
    {
    private JavaDLL oHASP;

    public int iniHASP(){
    oHASP = new JavaDLL(); //создал объект
    int ret;
    ret=oHASP.Execute(); //выполнил
    oHASP=null; //обнулил чтобы GC освободил ресурс !!!
    System.gc(); // напомнил
    return ret;
    }
    }
    Делаю её отображение в LS-библиотеке, для удобства, вот функция которую вызываю:


    Код (LotusScript):
    ' js, jHASPClass, jHASPObject - глобальные чтобы при вызове на форме не инициализировать по несколько раз

    If js Is Nothing Then
    Set js = New JAVASESSION
    End If
    If jHASPClass Is Nothing Then
    Set jHASPClass = js.GetClass("HASP")
    End If
    If jHASPObject Is Nothing Then
    Set jHASPObject = jHASPClass.CreateObject
    End If

    call jHASPObject.iniHASP()

    Так вот проблема:

    Если я выполняю ls-функцию в "Действии" или событии формы всё работает, можно даже по несколько раз подряд запускать.

    Если ls-функцию положить в "Агента" - то получаю ошибку "library is alredy loaded in anover ClassLoader", если эту ls-функцию уже хоть раз вызывали (например в действии или событии формы).
    Если к ls-функции не было обращений, и вызвать её через агента, то она один раз отработает, и но при следующем запуске выдаст ошибку "о занятой библиотеке". НО из "действяи" будет продолжать работать.

    В чём дело?
     
  2. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.073
    Симпатии:
    299
    причина, КМК, кроется именно в класслоадере, при экшенах - происходит "очистка" классов, а в агенте - нет

    Добавлено:
    http://habrahabr.ru/blogs/java/132500/
     
  3. lionk

    lionk Well-Known Member

    Регистрация:
    5 апр 2007
    Сообщения:
    308
    Симпатии:
    3
    И изменить положение дел невозможно?

    Переписал класс без параметра static, подключаю библиотек в конструкторе, ситуация не изменилась.
    По ссылке указано что есть замена, но погуглив ничего подходящего не нашёл.
     
  4. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.073
    Симпатии:
    299
    помимо статика там есть вызо нэйтив АПИ, кот подразумевает синглтон, кот. отстутствует :)
    и почему же не вынести в jar файл свой код и сложить его в jvm/lib/ext/ ?

    Добавлено: <!--shcode--><pre><code class='java'>oHASP=null; //обнулил чтобы GC освободил ресурс !!!
    System.gc(); // напомнил
    return ret;[/CODE]ничего не освободится, вызов gc не гарантирует освобожение IO, нативных ресурсов... и ваще не слушает ваших похотелок (вызов - не иструкция для исполнения, а лишь констатация намерения ;) )
     
  5. lionk

    lionk Well-Known Member

    Регистрация:
    5 апр 2007
    Сообщения:
    308
    Симпатии:
    3
    Не понял, в jar-файлик - вывести ява либу из лотуса?
    И в лотус-либе обращаться к этому выносному файлику?
    Разве есть принципиальная разница между библиотекой в базе и внешней?
     
  6. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.073
    Симпатии:
    299
    есть принципиальная
     
  7. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    Код на кнопке грузится класслоадером lotus.domino.JavaConnectLoader - так называемый бридж. Соответственно и либа грузится им же.
    В клиенте(точнее в notes jvm) ровно один экземпляр такого класслоадера, поэтому повторные попытки грузить либу тихо игнорируются.

    В случае с агентом ситуация иная: код грузится экземпляром lotus.domino.AgentLoader. Причем при каждом запуске агента создается экземпляр указанного класслоадера - т.е. их может быть несколько.
    Т.о. два запуска агента подряд приведут к тому, что второй раз либа будет грузится вторым класслоадером, о чем вы и получаете сообщение. До тех пор пока сборщик не собирет первый класслоадер - вы не сможете загрузить либу. Когда именно происходит сборка AgentLoader - я, честно говоря, не знаю. По идее - он должен собраться сразу, но, как минимум, возможны утечки внутри агента, которые будут препятствовать gc.

    Простейший вариант решения этого квеста описал lmike: выложите класс, грузящий dll в lib/ext. В этом случае он будет грузиться class sun.misc.Launcher$ExtClassLoader, независимо от того, как вызывается код, использующий такой класс, т.к. ExtClassLoader - это системный класслоадер, который присутствует в единственном экземпляре.
     
Загрузка...
Похожие Темы - Library Alredy Loaded
  1. Nick Nick
    Ответов:
    14
    Просмотров:
    743
  2. Cleric-Lviv
    Ответов:
    1
    Просмотров:
    476
  3. garrick
    Ответов:
    14
    Просмотров:
    1.444
  4. vsokol
    Ответов:
    0
    Просмотров:
    1.086
  5. JohnLemon
    Ответов:
    4
    Просмотров:
    1.312

Поделиться этой страницей